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(2..4/2) % 2 == 1 などがあります。

また、線はアンチエイリアス処理されているため、既に描画されているものを開始角度で上書きするのに役立ちます。そうしないと、おそらく望ましくない余分な白い線が表示されます。同様の理由で、白い円を描くときは、少し太めの線(半径が小さいほど太い線)を描く必要があります。そうしないと、アンチエイリアシングによって、一部のシュムッツ (消去された円のかすかな輪郭) が残ります。

半径と幅を、上部に配置するグローバルに入れます。

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 に答える