【问题标题】:How can I create a shimmer over time animation with a canvas element?如何使用画布元素创建微光动画?
【发布时间】:2015-06-16 14:16:14
【问题描述】:

所以我知道大多数人不喜欢文字后面有奇怪的颜色,但是我的网站http://www.cbradiowaves.com 应该看起来更像报纸。无论如何,我正在使用画布元素为背景创建渐变,并且加载速度非常快但是我有一个非常酷的想法,如果我只能为画布元素的输入创建一个循环,我可以让背景看起来闪烁设置。我认为对于有经验的 javascript 程序员来说会有一个简单的解决方案。

这是我的代码:

<canvas id="background" width="1020" height="1020"
style="border:0px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>
var c = document.getElementById("background");
var ctx = c.getContext("2d");

// Create gradient
var grd = ctx.createRadialGradient(100,100,100,90,800,850);
grd.addColorStop(0,"white");
grd.addColorStop(1,"silver");

// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0,0,1020,1020);
</script>

创建动画需要随时间递增的行是这一行:

var grd = ctx.createRadialGradient(100,100,100,90,800,850);

我认为 javascript 有能力通过一个函数来做到这一点,但它正在逃避我。

【问题讨论】:

  • 你能指定/描述你希望它如何“闪烁”吗?

标签: javascript html animation canvas


【解决方案1】:

听起来您希望微光效果类似于缓慢的宽镜头光晕效果。

方法如下...

在动画循环内创建一个带有 2 个同心圆的径向渐变,并为外圆设置越来越小的动画。

有点低效的版本。

注意:这些演示最好在“整页”模式下查看。

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var offset=400;
var direction=4;

requestAnimationFrame(animate);


function animate(time){
  var grd = ctx.createRadialGradient(cw/2,ch/2,100,cw/2,ch/2,offset);
  grd.addColorStop(0,"white");
  grd.addColorStop(1,"silver");
  ctx.fillStyle=grd;
  ctx.fillRect(0,0,cw,ch);
  offset+=direction;
  if(offset<300 || offset>500){
    direction*=-1;
    offset+=direction;
  }
  requestAnimationFrame(animate);
}
body{ background-color:white; }
#canvas{border:1px solid red; margin:0 auto; }
&lt;canvas id="canvas" width=500 height=500&gt;&lt;/canvas&gt;

如果你有一点额外的内存,效率更高的版本:

如果您有内存,您可以使用径向渐变创建第二个内存画布,然后将第二个画布绘制到可见画布上。在动画循环中执行 drawImage 并缩放绘图以创建闪烁的脉冲效果。

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var scale=100;
var direction=1;

var c=document.createElement('canvas');
var cctx=c.getContext('2d');
var ccw=cw*1.50;
var cch=ch*1.50;
c.width=ccw;
c.height=cch;
var grd = ctx.createRadialGradient(ccw/2,cch/2,100,ccw/2,cch/2,500);
grd.addColorStop(0,"white");
grd.addColorStop(1,"silver");
cctx.fillStyle=grd;
cctx.fillRect(0,0,ccw,cch);

requestAnimationFrame(animate);


function animate(time){
  var iw=ccw*scale/100;
  var ih=cch*scale/100;
  ctx.drawImage(c,
                0,0,ccw,cch,
                cw/2-iw/2,ch/2-ih/2,iw,ih
               );
  scale+=direction;
  if(scale<75 || scale>125){
    direction*=-1;
    scale+=direction;
  }
  requestAnimationFrame(animate);
}
body{ background-color:white; }
canvas{border:1px solid red; margin:0 auto; }
&lt;canvas id="canvas" width=500 height=500&gt;&lt;/canvas&gt;

【讨论】:

  • 非常感谢!我会玩弄它,我可能会切换为 x 和 y 动画的宽度和高度,这样它看起来更像是光线在页面上移动而不是改变大小。你很有帮助!谢谢!!!!!!!
【解决方案2】:

只需将渐变设置为元素的背景(不过我建议使用 CSS 渐变),然后在顶部绘制一个具有可变不透明度的白色方块(这里也可以将 CSS 不透明度与动画一起使用)。

这种方式渐变只渲染一次,不需要额外的画布缓冲区,浏览器将使用渐变进行主要合成。

调节速度和深度以满足您的需求(我选择了一个微妙的老式经典电影闪光)- 您还可以通过将帧速率切换到 30 fps 而不是默认的 60 fps 来节省一些性能。

画布

var c = document.getElementById("background"), ctx = c.getContext("2d");

// Create gradient
var grd = ctx.createRadialGradient(100,100,100,90,800,850);
grd.addColorStop(0,"white"); 
grd.addColorStop(1,"silver");
ctx.fillStyle = grd;
ctx.fillRect(0,0,1020,1020);

// Set as element background:
c.style.backgroundImage = "url(" + c.toDataURL() + ")";            // element bg.

ctx.fillStyle = "#fff";                                            // white fill

// variate opacity
(function loop(time) {
  ctx.clearRect(0, 0, c.width, c.height);                          // clear frame
  ctx.globalAlpha = Math.abs(Math.sin(time * 0.008)) * 0.15 + 0.2; // set some opacity/time
  ctx.fillRect(0, 0, c.width, c.height);                           // fill white
  requestAnimationFrame(loop)
})(0);
&lt;canvas id="background" width="1020" height="1020"&gt;&lt;/canvas&gt;

要考虑的 CSS 版本:

这里只是一个简单的椭圆渐变,根据需要调整:

html, body, #background {width:100%; height:100%; margin:0}
#background {
  position:fixed;
  z-index:-1;
  /* note: you may need to add more prefixed version */
  background: -webkit-radial-gradient(center, ellipse cover, rgba(238,238,238,1) 0%,rgba(255,255,255,1) 2%,rgba(224,224,224,1) 100%);
  background: radial-gradient(ellipse at center, rgba(238,238,238,1) 0%, rgba(255,255,255,1) 2%,rgba(224,224,224,1) 100%);
  -webkit-animation: 0.2s shimmer linear infinite alternate;
  animation: 0.20s shimmer linear infinite alternate;
}

@keyframes shimmer {from {opacity:0.8} to {opacity:1}}
@-webkit-keyframes shimmer {from {opacity:0.8} to {opacity:1}}
&lt;div id="background"&gt;&lt;/div&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多