如何使用canvas元素创建一个随时间变化的微光?

时间:2015-06-16 02:55:05

标签: javascript html5 animation canvas

所以我知道大多数人不喜欢在文字背后留下奇怪的颜色但是,我的网站http://www.cbradiowaves.com看起来更像是一份报纸。无论如何,我使用canvas元素为背景创建渐变,它加载速度非常快但是我有这个非常酷的想法,如果我只能为输入创建一个循环,我可以使背景显得微微闪烁画布元素设置。我认为有经验的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有可能通过一个函数执行此操作,但它正在逃避我。

2 个答案:

答案 0 :(得分:0)

听起来像你想要的微光效果就像一个缓慢的宽镜头眩光效果。

以下是......

在动画循环内创建一个带有2个同心圆的径向渐变,并使外圈的动画变大和变小。

效率稍低的版本。

注意:这些演示最好在&#34; Full Page&#34;模式。

&#13;
&#13;
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);
}
&#13;
body{ background-color:white; }
#canvas{border:1px solid red; margin:0 auto; }
&#13;
<canvas id="canvas" width=500 height=500></canvas>
&#13;
&#13;
&#13;

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

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

&#13;
&#13;
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);
}
&#13;
body{ background-color:white; }
canvas{border:1px solid red; margin:0 auto; }
&#13;
<canvas id="canvas" width=500 height=500></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

只需将渐变设置为元素的背景(我建议使用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);
<canvas id="background" width="1020" height="1020"></canvas>

要考虑的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}}
<div id="background"></div>