html5 椭圆运动(canvas画布实现)
2016/07/21    标签: html5    canvas    椭圆运动   

使用html5的canvas标签实现任意元素椭圆运动

实现原理实际上就是椭圆的两个方程:


  1. QQ截图20160721094440.png让椭圆的一个轴的值x周期性匀速增加或减少,算出另外一个坐标点y的值

  2. 由椭圆的XY坐标和长半轴长和短半轴长,求任意角度椭圆的坐标

    X=acosp,Y=bsinp(p为角度参数,a为长半轴,b为短半轴)


示例代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <canvas id="test" width="600" height="200" style="border: 1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
    <canvas id="test1" width="400" height="600" style="background: url(1.gif) no-repeat 50px 100px;
        border: 1px solid #c3c3c3; transform: rotate(30deg); left: 50%; top: 200px; position: absolute;">
Your browser does not support the canvas element.
</canvas>
    <script type="text/javascript">
        function yundong(a, b, contextId, contextFun) {
            //a:椭圆长半轴长度
            //b:椭圆短半轴长度
            //context:canvas对象
            //contextFun:canvas对象方法
            var c = document.getElementById(contextId);
            var am = a * a;
            var bm = b * b;
            if (!c.getContext("2d")) {
                return;
            }

            var cxt = c.getContext("2d");
            var x = -1, y = 0;
            var reverses = false;
            cxt.translate(-1, b);
            setInterval(function () {
                //清空画布
                cxt.clearRect(0, 0, c.offsetWidth, c.offsetHeight);
                if (x == (2 * a + 1)) {
                    reverses = true;
                }
                if (x == -1) {
                    reverses = false;
                }
                if (reverses) {
                    y = Math.sqrt((1 - (x - 1 - a) * (x - 1 - a) / (am)) * bm) - Math.sqrt((1 - (x - a) * (x - a) / (am)) * bm);
                    cxt.translate(-1, y);
                    x--;
                } else {
                    y = Math.sqrt((1 - (x - a) * (x - a) / (am)) * bm) - Math.sqrt((1 - (x - 1 - a) * (x - 1 - a) / (am)) * bm);
                    cxt.translate(1, -y);
                    x++;
                }
                contextFun(cxt);

            }, 0)
        }
        function yundong1(a, b, speed, contextId, contextFun) {
            //a椭圆长半轴长
            //b:椭圆短半轴长
            //speed运动速度
            //contextId要行椭圆运动的画布
            //contextFun运动时的回调,draw画的具体内容
            var c = document.getElementById(contextId);
            if (!c.getContext("2d")) {
                return;
            }
            var angleStart = -Math.PI;
            var cxt = c.getContext("2d");
            var x = -1, y = 0;
            var reverses = false;
            cxt.translate(-1, b);
            var step = Math.PI / 180;
            var timmer = setInterval(function () {
                angleStart = angleStart + step;
                cxt.clearRect(0, 0, c.offsetWidth, c.offsetHeight);
                x = a * (Math.cos(angleStart) - Math.cos(angleStart - step));
                y = b * (Math.sin(angleStart) - Math.sin(angleStart - step));
                cxt.translate(x, y);
                contextFun(cxt);
            }, speed);
            var obj = {
                start: function () {
                    timmer = setInterval(function () {
                        angleStart = angleStart + step;
                        cxt.clearRect(0, 0, c.offsetWidth, c.offsetHeight);
                        x = a * (Math.cos(angleStart) - Math.cos(angleStart - step));
                        y = b * (Math.sin(angleStart) - Math.sin(angleStart - step));
                        cxt.translate(x, y);
                        contextFun(cxt);
                    }, speed);
                },
                stop: function () {
                    clearInterval(timmer);
                }
            }
            return obj;
        }
        //方法1示例
        yundong(200, 50, 'test', function (cxt) {
            cxt.beginPath();
            cxt.fillStyle = "#ccc";
            cxt.arc(100, 50, 15, 0, Math.PI * 2, true);
            cxt.closePath();
            cxt.fill();
        })
        //方法2示例
        var rst = yundong1(100, 200, 20, 'test1', function (cxt) {
            cxt.beginPath();
            cxt.fillStyle = "#ccc";
            cxt.arc(50, 100, 15, 0, Math.PI * 2, true);
            cxt.closePath();
            cxt.fill();
        })
        var stop = false;
        document.getElementById('test1').onclick = function () {
            if (!stop) {
                rst.stop();
                stop = true;
            } else {
                rst.start();
                stop = false;
            }
        };
    </script>
</html>

在线查看Demo