• 《canvas》之第18章 高级动画


    第18章 高级动画

    18.1 高级动画简介

    缓动动画指物体运动到目标点就停下来;
    弹性动画指来回反弹,最终停止目标点。

    18.2 缓动动画简介

    带有缓冲效果的动画,物体在某一段时间内渐进加速或减速,物体运动看起来更为自然逼真。
    缓入动画,汽车启动时逐渐加速;缓出动画,汽车停止时逐渐减速。

    1. 定义0.0~1.0的缓动系数easing。
    2. 计算物体与终点间距离。
    3. 计算当前速度,当前速度=速度×缓动系数。
    4. 计算新的位置,新的位置=当前位置+当前速度。
    5. 重复执行2~4,直到物体达到目标。
    var targetX = 任意位置;
    var targetY = 任意位置;
    
    //动画循环
    var vx = (targetX-object.x) * easing;
    var vy = (targetY-object.y) * easing;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • x轴或y轴方向的缓动动画
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(0, cnv.height / 2);
                //定义终点的X轴坐标
                var targetX = cnv.width * (3 / 4);
                //定义缓动系数
                var easing = 0.05;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var vx = (targetX - ball.x) * easing;
                    ball.x += vx;
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 任意方向的缓动动画
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(0, 0);
                //定义终点的X轴坐标和Y轴坐标
                var targetX = cnv.width * (3 / 4);
                var targetY = cnv.height * (1 / 2);
                //定义缓动系数
                var easing = 0.05;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var vx = (targetX - ball.x) * easing;
                    var vy = (targetY - ball.y) * easing;
                    ball.x += vx;
                    ball.y += vy;
    
                    ball.fill(cxt);
                })();
    
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 一个小球追随鼠标指针
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                //初始化数据
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 15, "#FF6699");
                var mouse = tools.getMouse(cnv);
                var easing = 0.05;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var vx = (mouse.x - ball.x) * easing;
                    var vy = (mouse.y - ball.y) * easing;
                    ball.x += vx;
                    ball.y += vy;
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 多个小球追随鼠标指针
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                //初始化数据
                var bigBall = new Ball(cnv.width / 2, cnv.height / 2, 15, "# FF6699");
                var smallBall = new Ball(cnv.width / 2, cnv.height / 2, 12, "#66CCFF");
                var mouse = tools.getMouse(cnv);
                var easing = 0.05;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    //第1个小球跟随鼠标移动
                    var vx1 = (mouse.x - bigBall.x) * easing;
                    var vy1 = (mouse.y - bigBall.y) * easing;
                    bigBall.x += vx1;
                    bigBall.y += vy1;
                    bigBall.fill(cxt);
    
                    //第2个小球跟随第1个小球移动
                    var vx2 = (bigBall.x - smallBall.x) * easing;
                    var vy2 = (bigBall.y - smallBall.y) * easing;
                    smallBall.x += vx2;
                    smallBall.y += vy2;
                    smallBall.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    18.3 缓动动画应用

    缓动动画可以用于物体运动,大小,颜色,透明度,旋转等。

    当前速度 = (最终指-当前值) × 缓动系数;
    新值 = 当前值 + 当前速度;
    
    • 1
    • 2
    • 作用于半径
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(cnv.width / 2, cnv.height / 2);
                var targetRadius = 36;
                var easing = 0.05;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var vRadius = (targetRadius - ball.radius) * easing;
                    ball.radius += vRadius;
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 作用于透明度
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                //初始化数据
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 30, "rgba(255,102,153,1.0)");
                var opacity = 1.0;
                var targetOpacity = 0.0;
                var easing = 0.05;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var v = (targetOpacity - opacity) * easing;
                    opacity += v;
                    ball.color = "rgba(255,102,153," + opacity + ")";
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 作用于颜色
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                //初始化数据
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 30);
                ball.fill(cxt);
                var easing = 0.02;
    
                var red = 255;
                var green = 0;
                var blue = 0;
                var targetRed = 10;
                var targetGreen = 255;
                var targetBlue = 55;
    
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var vRed = (targetRed - red) * easing;
                    var vGreen = (targetGreen - green) * easing;
                    var vBlue = (targetBlue - blue) * easing;
    
                    red += vRed;
                    green += vGreen;
                    blue += vBlue;
    
                    var color = "rgba(" + parseInt(red) + "," + parseInt(green) + "," + parseInt(blue) + "," + "1.0)";
                    ball.color = color;
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    18.4 弹性动画简介

    • 设置终点
    • 物体与终点距离
    • 运动和距离成正比

    缓动动画中,速度与距离成正比;弹性动画中,加速度与距离成正比。

    ax = (targetX - object.x) * spring;
    ay = (targetY - object.y) * spring;
    
    vx += ax;
    vy += ay;
    vx *= friction;
    vy *= friction;
    object.x += vx;
    object.y += vy;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 无摩檫力的弹性动画
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                //初始化数据
                var ball = new Ball(0, cnv.height / 2);
                var targetX = cnv.width / 2;
                var spring = 0.02;
                var vx = 0;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var ax = (targetX - ball.x) * spring;
                    vx += ax;
                    ball.x += vx;
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 有摩檫力的弹性动画
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(0, cnv.height / 2);
                var targetX = cnv.width / 2;
                var spring = 0.02;
                var vx = 0;
                var friction = 0.95;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var ax = (targetX - ball.x) * spring;
                    vx += ax;
                    vx *= friction;
                    ball.x += vx;
    
                    ball.fill(cxt);
                })();
    
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 鼠标追随效果
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(cnv.width / 2, cnv.height / 2);
                var mouse = tools.getMouse(cnv);
    
                var targetX = cnv.width / 2;
                var spring = 0.02;
                var vx = 0;
                var vy = 0;
                var f = 0.95;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    var ax = (mouse.x - ball.x) * spring;
                    var ay = (mouse.y - ball.y) * spring;
    
                    vx += ax;
                    vy += ay;
    
                    vx *= f;
                    vy *= f;
    
                    ball.x += vx;
                    ball.y += vy;
    
                    ball.fill(cxt);
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    18.5 弹性动画应用

    • 绳球运动
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(cnv.width / 2, cnv.height / 2);
                var mouse = tools.getMouse(cnv);
    
                var targetX = cnv.width / 2;
                var spring = 0.02;
                var vx = 0;
                var vy = 0;
                var friction = 0.95;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    //加入弹性动画
                    var ax = (mouse.x - ball.x) * spring;
                    var ay = (mouse.y - ball.y) * spring;
                    vx += ax;
                    vy += ay;
                    vx *= friction;
                    vy *= friction;
                    ball.x += vx;
                    ball.y += vy;
                    ball.fill(cxt);
    
                    //将鼠标以及小球中心连接成一条直线
                    cxt.beginPath();
                    cxt.moveTo(ball.x, ball.y);
                    cxt.lineTo(mouse.x, mouse.y);
                    cxt.stroke();
                    cxt.closePath();
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="270" height="180" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 加入重力影响
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script src="js/tools.js"></script>
        <script src="js/ball.js"></script>
        <script type="text/javascript">
            function $$(id) {
                return document.getElementById(id);
            }
            window.onload = function () {
                var cnv = $$("canvas");
                var cxt = cnv.getContext("2d");
    
                var ball = new Ball(cnv.width / 2, cnv.height / 2);
                var mouse = tools.getMouse(cnv);
    
                var targetX = cnv.width / 2;
                var spring = 0.02;
                var vx = 0;
                var vy = 0;
                var friction = 0.95;
                //定义重力
                var gravity = 1;
    
                (function frame() {
                    window.requestAnimationFrame(frame);
                    cxt.clearRect(0, 0, cnv.width, cnv.height);
    
                    //加入弹性动画
                    var ax = (mouse.x - ball.x) * spring;
                    var ay = (mouse.y - ball.y) * spring;
                    vx += ax;
                    vy += ay;
                    //加入重力影响
                    vy += gravity;
                    vx *= friction;
                    vy *= friction;
                    ball.x += vx;
                    ball.y += vy;
                    ball.fill(cxt);
    
                    //将鼠标以及小球中心连接成一条直线
                    cxt.beginPath();
                    cxt.moveTo(ball.x, ball.y);
                    cxt.lineTo(mouse.x, mouse.y);
                    cxt.stroke();
                    cxt.closePath();
                })();
            }
        </script>
    </head>
    <body>
        <canvas id="canvas" width="270" height="180" style="border:1px solid silver;"></canvas>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    * 玩转数据魔方Plotly Express实战8例
    技术对接46
    stp基本介绍
    vue大屏可视化项目页面全屏展示(强制缩放实现)
    5Python的Pandas:数据结构
    【 图像去雾】基于暗通道和非均值滤波实现图像去雾附matlab代码
    对 JavaBean 的特点写法与实战心得详解
    第一天商城项目
    扫描全能王文档矫正逆向记录
    第十一章《Java实战常用类》第6节:Object类
  • 原文地址:https://blog.csdn.net/oqqyx1234567/article/details/125398352