【问题标题】:is it possible to animate canvas clip region's position?是否可以为画布剪辑区域的位置设置动画?
【发布时间】:2016-04-06 16:16:22
【问题描述】:

我想移动剪辑区域的位置,然后在剪辑区域中绘制。为什么以下方法不起作用? 感谢您的任何启发:-) 杰拉德

<canvas id="canvas" width="150" height="150"></canvas>
<script>

function fade() {
    var level = 0;
    var xClip=0, yClip=0;
    var step = function ( ) {
        var ctx = document.getElementById('canvas').getContext('2d');
        ctx.fillRect(0,0,150,150);

        // Create a circular clipping path
        ctx.beginPath();
        ctx.arc( xClip, xClip, 60, 0, Math.PI*2, true);
        ctx.clip();

        // draw background
        var lingrad = ctx.createLinearGradient(0,-75,0,75);
        lingrad.addColorStop(0, '#232256');
        lingrad.addColorStop(1, '#143778');

        ctx.fillStyle = lingrad;
        ctx.fillRect(-75,-75,150,150);

        if (level < 15) {
            level ++;
            xClip = yClip = level*10;
            console.log("level: " + level);
            console.log("xClip: " + xClip);
            setTimeout(step, 1000);
        }
    };
    setTimeout(step,100);
}
fade();
</script>

【问题讨论】:

  • 您只需要创建一次上下文。使用 ctx.save() 在创建 clop 之前保存上下文状态,然后在函数底部使用 ctx.restore() 恢复状态。

标签: html animation canvas clip


【解决方案1】:

动画剪辑。

当您多次应用剪辑时,剪辑区域被剪辑到现有剪辑。在不考虑这一点的情况下为剪辑区域设置动画将创建一个更小的剪辑区域。

保存和恢复。

在为剪辑区域设置动画时,您需要保存和恢复画布状态。 ctx.save() 将当前画布 2D 状态保存到堆栈,ctx.restore() 从堆栈顶部弹出最后保存的状态。保存和恢复可以嵌套。每次保存都必须在某个时间点进行恢复,否则您最终会占用内存并最终溢出状态堆栈。

修复您的代码。

您的代码几乎就在那里,只需要进行一些修改即可完成您想要的操作。我还将canvas.getContext() 移出淡入淡出功能,因为您只需执行一次。

function fade() {
    var level = 0;
    var xClip=0, yClip=0;
    var step = function ( ) {
        ctx.fillRect(0,0,150,150);

        //---------------------------------------------
        ctx.save();  // push the current unclipped state to the state stack.

        // Create a circular clipping path
        ctx.beginPath();
        ctx.arc( xClip, xClip, 60, 0, Math.PI*2, true);
        ctx.clip();

        ctx.fillStyle = lingrad;
        ctx.fillRect(-75,-75,150,150);

        if (level < 15) {
            level ++;
            xClip = yClip = level*10;
            setTimeout(step, 1000);
        }

        //---------------------------------------------
        ctx.restore();   // pop the last saved state from the state stack
                         // restoring the clip region to the default
                         // ready for the next call to step.

    };
    setTimeout(step,100);
}

// get the 2D context only once
var ctx = document.getElementById('canvas').getContext('2d');

// As the gradient does not change over time don't create this every
// frame as it is a expensive operation
var lingrad = ctx.createLinearGradient(0,-75,0,75);
lingrad.addColorStop(0, '#232256');
lingrad.addColorStop(1, '#143778');

fade();

【讨论】:

  • 我知道我们不应该在 cmets 中说谢谢(批准的方式是什么?)但我必须 - 非常感谢 :-)
  • @Gerard 感谢您的感谢。批准的方式是只勾选回答的答案或放弃投票,但谢谢就可以了。很高兴它有帮助。
猜你喜欢
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 2015-10-22
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多