《canvas》之第18章 高级动画

130 篇文章 4 订阅
20 篇文章 4 订阅

第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;
  • 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>
  • 任意方向的缓动动画
<!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>
  • 一个小球追随鼠标指针
<!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>
  • 多个小球追随鼠标指针
<!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>

18.3 缓动动画应用

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

当前速度 = (最终指-当前值) × 缓动系数;
新值 = 当前值 + 当前速度;
  • 作用于半径
<!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>
  • 作用于透明度
<!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>
  • 作用于颜色
<!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>

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;
  • 无摩檫力的弹性动画
<!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>
  • 有摩檫力的弹性动画
<!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>
  • 鼠标追随效果
<!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>

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>
  • 加入重力影响
<!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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值