5

这是我的问题:我有一个动画,构建是圆形的。见:http: //jsfiddle.net/2TUnE/

JavaScript:

var currentEndAngle = 0
var currentStartAngle = 0;
var currentColor = 'black';

setInterval(draw, 50);


function draw() { /***************/

    var can = document.getElementById('canvas1'); // GET LE CANVAS
    var canvas = document.getElementById("canvas1");
    var context = canvas.getContext("2d");
    var x = canvas.width / 2;
    var y = canvas.height / 2;
    var radius = 75;

    var startAngle = currentStartAngle * Math.PI;
    var endAngle = (currentEndAngle) * Math.PI;

    currentEndAngle = currentEndAngle + 0.01;

    var counterClockwise = false;

    context.beginPath();
    context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
    context.lineWidth = 15;
    // line color
    context.strokeStyle = currentColor;
    context.stroke();

    /************************************************/
}

当圆圈完全绘制好后,我希望它开始擦除,就像它被创建的方式一样(所以慢慢地去除黑色)。一旦整个圆圈被擦除,我会再次创建黑色圆圈,创建某种“等待/加载”效果。

我试图做的是检查 currentEndAngle 是否为 2(所以圆圈是完整的),然后移动 startAngle,但它没有用。

任何的想法?

谢谢!

编辑:忘了说,动画会在图像上,所以它必须是“透明的”而不是白色的

4

2 回答 2

4

查看这个 JSFiddle 中的内容:http: //jsfiddle.net/fNTsA/

这个方法基本上是你的代码,只是我们使用模数来控制状态。检查半径是否为 2 只对了一半,要切换绘制白色或绘制黑色,您应该将半径取模 2 的一半。第一次有 floor(0..2/2) % 2 == 0 时,第二个你有 floor(2..4/2) % 2 == 1,依此类推。

此外,因为线条是抗锯齿的,它有助于让起始角度覆盖已经绘制的内容,否则您可能会得到额外的白线,您可能不想要。同理,在画白圈的时候,应该画一条稍粗的线(半径越小,线越粗)。否则,抗锯齿会留下一些 schmutz - 已擦除圆圈的微弱轮廓。

我将半径和宽度放入您放在顶部的全局变量中:

var lineRadius = 75;
var lineWidth = 15;

同样,这是我的模数,非常标准:

currentStartAngle = currentEndAngle - 0.01;
currentEndAngle = currentEndAngle + 0.01;

if (Math.floor(currentStartAngle / 2) % 2) {
  currentColor = "white";
  radius = lineRadius - 1;
  width = lineWidth + 3;
} else {
  currentColor = "black";
  radius = lineRadius;
  width = lineWidth;
}
于 2012-08-15T20:46:42.813 回答
1

有趣的挑战!试试下面的(这里更新小提琴)。我试图加入大量评论来表达我的想法。

    // Moved these to global scope as you don't want to re-declare 
    // them in your draw method each time your animation loop runs
    var canvas = document.getElementById("canvas1");
    var context = canvas.getContext("2d");
    var x = canvas.width / 2;
    var y = canvas.height / 2;
    var radius = 75;

    // Use objects to hold our draw and erase props
    var drawProps = {
      startAngle: 0,
      speed: 2,
      color: 'black',
      counterClockwise: false,
      globalCompositeOperation: context.globalCompositeOperation,
      lineWidth: 15            
    };

    var eraseProps = {
      startAngle: 360,
      speed: -2,
      color: 'white',
      counterClockwise: true,
      globalCompositeOperation: "destination-out",
      lineWidth: 17 // artefacts appear unless we increase lineWidth for erase
    };

    // Let's work in degrees as they're easier for humans to understand
    var degrees = 0; 
    var props = drawProps;

    // start the animation loop
    setInterval(draw, 50);

    function draw() { /***************/

        degrees += props.speed;

        context.beginPath();
        context.arc(
            x, 
            y, 
            radius, 
            getRadians(props.startAngle), 
            getRadians(degrees), 
            props.counterClockwise
        );
        context.lineWidth = props.lineWidth;
        context.strokeStyle = props.color;
        context.stroke();

        // Start erasing when we hit 360 degrees
        if (degrees >= 360) {
            context.closePath();
            props = eraseProps;
            context.globalCompositeOperation = props.globalCompositeOperation;
        }

        // Start drawing again when we get back to 0 degrees
        if (degrees <= 0) {
            canvas.width = canvas.width; // Clear the canvas for better performance (I think)
            context.closePath();
            props = drawProps;
            context.globalCompositeOperation = props.globalCompositeOperation;
        }
        /************************************************/
    }  

    // Helper method to convert degrees to radians
    function getRadians(degrees) {
        return degrees * (Math.PI / 180);
    }
于 2012-08-15T20:13:46.483 回答