使用canvas实现鲤鱼跃龙门的动画效果

 更新时间:2024年02月05日 08:46:09   作者:前端搬砖人  
这篇文章主要给大家介绍了使用canvas实现鲤鱼跃龙门的动画效果,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,感兴趣的小伙伴可以自己动手尝试一下

废话不多说,先看效果图

实现代码与思路如下:

第一步 添加canvas画布

<body style="background-color: rgb(216, 249, 250);margin: 0px;">
    <canvas id="tutorial" width="1520" height="699"></canvas>
    <div class="text">
        <p>鲤鱼跃龙门</p>
        <p>冲呀!</p>
    </div>
</body>

第二步 获取canvas元素

let canvas = document.getElementById("tutorial");
    //检查支持性
    if (canvas.getContext) {
        var ctx = canvas.getContext("2d"); // 获取渲染上下文
        // ToDo ...
    }

第三步 关于白云部分的绘制和动画

  • 白云的绘制
    用position数组统一设置白云的位置
    var img = new Image();
    img.src = "./public/cloud.svg";
    var position = [{ x: 20, y: 520 }, { x: 350, y: 560 }, { x: 650, y: 490 }, { x: 930, y: 550 }, { x: 1230, y: 570 }]; //设置白云的位置
    
    img.onload = function () {
            // 开始动画    
        for (let i = 0; i < position.length; i++) {
            ctx.drawImage(img, position[i].x, position[i].y); // 每个图片间隔300像素
       }
    };
  • 白云的动画
    整体的思路就是,结合周期定时器动态设置globalAlpha属性去控制元素的显示与隐藏。
        // 淡入淡出动画
        function fadeInOut(index) {
            var opacity = 1; // 初始透明度为1
            var increasing = true;
            // 每隔10毫秒执行一次淡入淡出效果
            var intervalId = setInterval(function () {
                var randomNum = Math.random();

                if (increasing) {
                    opacity += randomNum * 0.01; // 透明度逐渐增加
                    if (opacity >= 1) {
                        increasing = false; // 达到最大透明度后开始减少
                    }
                } else {
                    opacity -= randomNum * 0.01; // 透明度逐渐减小
                    if (opacity <= 0) {
                        // increasing = true;
                        clearInterval(intervalId); // 透明度减小到0后清除定时器
                        setTimeout(() => fadeInOut(index), 100); // 等待100ms后重新执行淡入淡出
                    }
                }
                imageOpacities[index] = opacity; // 更新图片透明度
                drawImage(); // 重新绘制

            }, 60);
        }

         // 绘制图片
        function drawImage() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.save(); // 保存当前绘制状态

            // 绘制之前的内容
            ctx.beginPath();
            ctx.moveTo(75, 25);
            //二次贝塞尔曲线
            ctx.quadraticCurveTo(25, 25, 25, 62.5);
            ctx.quadraticCurveTo(25, 100, 50, 100);
            ctx.quadraticCurveTo(50, 120, 30, 125);
            ctx.quadraticCurveTo(60, 120, 65, 100);
            ctx.quadraticCurveTo(125, 100, 125, 62.5);
            ctx.quadraticCurveTo(125, 25, 75, 25);
            ctx.stroke();

            ctx.drawImage(imgDoor, 250, -120);


            // ctx.drawImage(imgFish, 1150, 450, 200, 200);

            for (let i = 0; i < position.length; i++) {
                ctx.globalAlpha = imageOpacities[i];
                ctx.drawImage(img, position[i].x, position[i].y); // 每个图片间隔300像素
            }

            // 绘制鱼
            ctx.globalAlpha = fishOpacity;
            ctx.drawImage(imgFish, fishX, fishY, fishWidth, fishHeight);
            ctx.globalAlpha = 1 - fishOpacity;
            ctx.drawImage(imgDragon, 250, 100, 600, 600);
            ctx.restore(); // 恢复之前保存的绘制状态
        }
        
        
        
        //用处
        img.onload = function () {
            // 开始动画
            position.forEach((item, index) => {
                fadeInOut(index);
            });
        };

第四步 关于鱼的绘制和动画

        // Fish 图片的初始位置和大小
        var fishX = 1150;
        var fishY = 450;
        var fishWidth = 200;
        var fishHeight = 200;
        // 鱼的透明度
        var fishOpacity = 1;
        
        // 跳跃动画
        function jumpAnimation() {
            var startY = fishY;
            var startx = fishX;
            var maxHeight = startY - 150; // 鱼的最高跳跃高度
            var speed = 2; // 跳跃速度
            var gravity = 0.1; // 重力加速度
            var isRising = true; // 是否处于上升状态

            var jumpInterval = setInterval(function () {
                // 鱼上升
                if (isRising) {
                    fishY -= speed;
                    fishX -= speed + 3;
                    if (fishY <= maxHeight) {
                        isRising = false;
                    }
                }
                // 鱼下落
                else {
                    fishY += speed;
                    fishX -= speed + 3;
                    if (fishY >= startY) {
                        clearInterval(jumpInterval);
                        // 开始消失效果
                        fadeOut();
                    }
                }

                drawImage(); // 重新绘制鱼
            }, 30);
        }

        // 消失效果
        function fadeOut() {
            var opacityDecrement = 0.05; // 透明度减少的步长
            var fadeInterval = setInterval(function () {
                fishOpacity -= opacityDecrement; // 透明度逐渐减小
                if (fishOpacity <= 0) {
                    fishOpacity = 0;
                    clearInterval(fadeInterval);
                }
                drawImage(); // 重新绘制鱼
            }, 50);
        }
 

        //用处
        imgFish.onload = function () {
            // 图片加载完成后开始动画
            setTimeout(function () {
                jumpAnimation(); // 1秒后开始跳跃动画
            }, 1000);
        };

第五步 关于对文字的样式

<style>
    .text {
        position: absolute;
        top: 28px;
        left: 25px;
    }

    p {
        text-align: center;
        margin: 10px;
    }
</style>

就这,over over ~

以上就是使用canvas实现鲤鱼跃龙门的动画效果的详细内容,更多关于canvas鲤鱼跃龙门的资料请关注脚本之家其它相关文章!

相关文章

  • JS闭包用法实例分析

    JS闭包用法实例分析

    这篇文章主要介绍了JS闭包用法,结合具体实例形式分析了javascript闭包的原理、执行步骤与相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • js布局实现单选按钮控件

    js布局实现单选按钮控件

    这篇文章主要为大家详细介绍了js布局实现单选按钮控件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01
  • 关于TypeScript应该尽量避免的语法总结

    关于TypeScript应该尽量避免的语法总结

    TypeScript是JavaScript的超集,具有类型系统,支持ES6语法,支持面向对象编程的概念,下面这篇文章主要给大家介绍了关于TypeScript应该尽量避免的语法,需要的朋友可以参考下
    2022-04-04
  • JavaScript实现使用Canvas绘制图形的基本教程

    JavaScript实现使用Canvas绘制图形的基本教程

    本篇文章主要介绍了JavaScript实现使用Canvas绘制图形的基本教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2016-10-10
  • 详解webpack+gulp实现自动构建部署

    详解webpack+gulp实现自动构建部署

    这篇文章主要介绍了详解webpack+gulp实现自动构建部署,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • javascript检测移动设备横竖屏

    javascript检测移动设备横竖屏

    移动端的开发过程中,免不了要判断横竖屏,然后在执行其他操作,比如分别加载不同样式,横屏显示某些内容,竖屏显示其他内容等等。
    2016-05-05
  • layui的数据表格+springmvc实现搜索功能的例子

    layui的数据表格+springmvc实现搜索功能的例子

    今天小编就为大家分享一篇layui的数据表格+springmvc实现搜索功能的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JS前端加密算法示例

    JS前端加密算法示例

    这篇文章主要介绍了JS前端加密算法,结合实例形式分析了crypto-js具体用法与注意事项,需要的朋友可以参考下
    2016-12-12
  • 纯前端JavaScript实现Excel IO案例分享

    纯前端JavaScript实现Excel IO案例分享

    这篇文章主要为大家详细介绍了纯前端JavaScript实现Excel IO案例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • js操作table中tr的顺序实现上移下移一行的效果

    js操作table中tr的顺序实现上移下移一行的效果

    这篇文章主要介绍了js操作table中tr的顺序实现上移下移一行的效果 ,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-11-11

最新评论