在绘制的Canvas元素上应用CSS

Man*_*cho 3 css canvas css-animations angularjs angularjs-directive

是否可以将CSS动画(在我的情况下是一个发光效果)应用于通过javascript在画布上绘制的圆圈?

我正在使用这个angularjs指令:https://github.com/angular-directives/angular-round-progress-directive/blob/master/angular-round-progress-directive.js

我用它作为计数器,我希望它每秒都发光(已经获得了动画的css代码).

那可能吗?另一个想法是,使画布本身呈圆形,并将发光效果应用于画布.

aur*_*ano 5

您无法将 CSS 应用于画布中绘制的元素,因为它们不存在于 DOM 上。就像它们是位图图像一样。

不过,您可以使用SVG 圆圈,这将允许您使用CSS设计圆圈样式并使用动画:

<svg height="100" width="100">
    <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
Run Code Online (Sandbox Code Playgroud)


小智 5

您不能将CSS应用于绘制到画布的形状,但只需使用阴影即可创建发光效果.

这是一个演示

var canvas = document.getElementById('canvas'), // canvas
    ctx = canvas.getContext('2d'),              // context
    w = canvas.width,                           // cache some values
    h = canvas.height,
    cx = w * 0.5,
    cy = h * 0.5,
    glow = 0,                                   // size of glow
    dlt = 1,                                    // speed
    max = 40;                                   // max glow radius

ctx.shadowColor = 'rgba(100, 100, 255, 1)';     // glow color
ctx.fillStyle = '#fff';                         // circle color

function anim() {
    ctx.clearRect(0, 0, w, h);                  // clear frame
    ctx.shadowBlur = glow;                      // set "glow" (shadow)

    ctx.beginPath();                            // draw circle
    ctx.arc(cx, cy, cx * 0.25, 0, 6.28);
    ctx.fill();                                 // fill and draw glow

    glow += dlt;                                // animate glow
    if (glow <= 0 || glow >= max) dlt = -dlt;

    requestAnimationFrame(anim);                // loop
}
anim();
Run Code Online (Sandbox Code Playgroud)

例

更新

要获得外部发光的轮廓,您可以使用复合操作简单地"打出"圆的中心.这里的示例使用save/restore来删除阴影 - 您可以通过手动重置这些来优化代码 - 但为简单起见,请执行以下修改:

ctx.fillStyle = '#fff';
// remove shadow from global

function anim() {
    ctx.clearRect(0, 0, w, h);

    // draw main circle and glow
    ctx.save();                                 // store current state
    ctx.shadowColor = 'rgba(100, 100, 255, 1)';
    ctx.shadowBlur = glow;

    ctx.beginPath();
    ctx.arc(cx, cy, cx * 0.25, 0, 6.28);
    ctx.fill();    
    ctx.restore();                              //restore -> removes the shadow

    // draw inner circle
    ctx.globalCompositeOperation = 'destination-out'; // removes what's being drawn
    ctx.beginPath();
    ctx.arc(cx, cy, cx * 0.23, 0, 6.28);          // smaller filled circle
    ctx.fill();    
    ctx.globalCompositeOperation = 'source-over'; // reset

    glow += dlt;
    if (glow <= 0 || glow >= max) dlt = -dlt;

    requestAnimationFrame(anim);
}
Run Code Online (Sandbox Code Playgroud)

复合操作将从下一个绘制操作中删除像素.只需在顶部绘制一个较小的实心圆圈,这将留下第一个圆圈及其发光的轮廓.

在这里改进了小提琴

例题