使用JavaScript的HTML画布中的动画圈

时间:2019-05-19 13:18:27

标签: javascript html html5-canvas

我需要为在html画布中移动的圆圈设置动画。为此,我决定使用一种典型的精灵动画技术,该技术包括以下常规步骤:

  1. 初始化背景(在这种情况下,只是一个灰色矩形)
  2. 计算新精灵的坐标
  3. 绘制精灵(圆圈)
  4. 重置背景
  5. 转到2

我的问题是,尽管我正在重置画布,但每次调用ctx.fill()时,结果似乎都重画了所有旧圆圈。

我在做什么错?有什么建议吗?

        var canvas;
        var ctx;
        var canvasPos;

        function rgbToHex(r, g, b) {
            return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
        }

        function init() {
            canvas = document.getElementById("target_temp");
            ctx = canvas.getContext("2d");
            canvasPos = { x: canvas.offsetLeft, y: canvas.offsetTop };
            drawSlider();
        }

        var y = 7;

        function animate() {
            y = y + 1;

            knob.setPosition(8, y);
            knob.clear();
            knob.draw();

            if (y < 93) {
                setTimeout(animate, 10);
            }
        }

        function drawSlider() {
            ctx = canvas.getContext("2d");
            ctx.fillStyle = "#d3d3d3";
            ctx.fillRect(0, 0, 16, 100);
        }

        var knob = {
            position: { x: 8, y: 7 },
            oldPosition: { x: 8, y: 7 },
            setPosition(_x, _y) {
                this.oldPosition = this.position;
                this.position.x = _x;
                this.position.y = _y
            },
            clear() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                drawSlider();
            },
            draw() {
                ctx.fillStyle = rgbToHex(0, 0, 112);              
                ctx.arc(8, this.position.y, 7, 0, 2 * Math.PI);
                ctx.fill();
            }
        }

        window.onload = function () { init(); animate(); };
<!DOCTYPE html>
<html>
<boyd>
    <canvas id="target_temp" width="16px" height="100px"></canvas>
</boyd>
</html>

2 个答案:

答案 0 :(得分:1)

好吧,我找到了原因:arc()方法将圆堆叠为路径的一部分,因此,要使其正常工作,我们需要像这样重置路径:

draw() {
  ctx.fillStyle = rgbToHex(0, 2*y, 107);      
  ctx.beginPath();          
  ctx.arc(8, this.position.y, 7, 0, 2 * Math.PI);
  ctx.fill();
}

答案 1 :(得分:1)

我看到您已经想出要使用beginPath了,但是我不同意该位置,我将在函数动画开始的那一刻,看看下面的代码,我重构了您的代码,摆脱了一些未使用的变量,并将滑块变成了与旋钮一样的对象

var canvas = document.getElementById("target_temp");
var ctx = canvas.getContext("2d");

var slider = {
  width: 16, 
  height: 100,
  draw() {
    ctx.fillStyle = "#d3d3d3";
    ctx.fillRect(0, 0, this.width, this.height);
  }
}

var knob = {
  position: {x: 8, y: 7},
  radius: 8,
  draw() {    
    ctx.fillStyle = "#00D";    
    ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
    ctx.fill();
  }
}

function animate() {
  ctx.beginPath()
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  slider.draw();
  if (knob.position.y + knob.radius < slider.height) 
    knob.position.y++;  
  knob.draw();
  setTimeout(animate, 10);
}

window.onload = function() {
  animate()
};
<canvas id="target_temp"></canvas>