在绘制的画布元素上应用 CSS
Posted
技术标签:
【中文标题】在绘制的画布元素上应用 CSS【英文标题】:Applying CSS on drawn Canvas Elements 【发布时间】:2014-05-10 13:41:55 【问题描述】:是否可以将 CSS 动画(在我的情况下为发光效果)应用到通过 javascript 在画布上绘制的圆圈?
我正在使用这个 angularjs 指令:https://github.com/angular-directives/angular-round-progress-directive/blob/master/angular-round-progress-directive.js
我将它用作计数器,我希望它每秒发光(已经获得动画的 css 代码。
这可能吗? 另一个想法是,使画布本身呈圆形,并将发光效果应用于画布。
【问题讨论】:
【参考方案1】:您不能将 CSS 应用于画布中绘制的元素,因为它们不存在于 DOM 中。就好像它们是位图图像一样。
您可以使用SVG circle,这将允许您使用 CSS 并使用动画style the circle:
<svg >
<circle cx="50" cy="50" r="40" stroke="black" stroke- fill="red" />
</svg>
【讨论】:
【参考方案2】:您不能将 CSS 应用于绘制到画布上的形状,但您可以简单地使用阴影来创建发光效果。
A demo here
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();
更新
要获得具有外发光的轮廓,您只需使用复合操作“打孔”圆心即可。这里的示例使用保存/恢复来移除阴影 - 您可以通过手动重置这些来优化代码 - 但为简单起见,请进行以下修改:
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);
复合操作将从下一次绘制操作中移除像素。只需在顶部画一个较小的实心圆圈,即可留下第一个圆圈的轮廓及其发光。
Modified fiddle here
【讨论】:
这真的很有帮助!不幸的是,我不能将它应用到我的样本中。你介意帮我解决这个问题吗?我只想在外圈上产生发光效果 - 但我能得到的只是所有圆圈上的发光效果 - 但没有动画:( 在这里查看我的 git:github.com/manulitopetito/angular-progress 仍在尝试(连续 3 小时......)但没有运气......在第二张画布上绘制外圈会更好吗? @user2556555 (late answer->timezone diff.) 当然,但你能设置一个小提琴,因为我不知道你的代码。把最重要的部分放进去,我看看。本质上:您可以在使用复合模式绘制圆心后“标记”圆心(将 globalCompositeOperation 模式设置为destination-out,并在禁用阴影的情况下在顶部绘制一个较小的圆,将模式设置为source-over)。看到这个模组:jsfiddle.net/4BdGQ/1以上是关于在绘制的画布元素上应用 CSS的主要内容,如果未能解决你的问题,请参考以下文章