Javascript HTML画布聚光灯效果

Javascript HTML画布聚光灯效果,javascript,html,canvas,Javascript,Html,Canvas,假设我有以下代码 //找出窗外的高度和宽度 wwidth=$(窗口).width(); wheight=$(窗口).height(); //将画布放置在当前窗口上 $(“正文”)。追加($(“”); var context=document.getElementById(“test”).getContext(“2d”); context.canvas.width=wwidth; context.canvas.height=wheight; //把画布漆成黑色。 context.fillStyl

假设我有以下代码

//找出窗外的高度和宽度
wwidth=$(窗口).width();
wheight=$(窗口).height();
//将画布放置在当前窗口上
$(“正文”)。追加($(“”);
var context=document.getElementById(“test”).getContext(“2d”);
context.canvas.width=wwidth;
context.canvas.height=wheight;
//把画布漆成黑色。
context.fillStyle='#000';
clearRect(0,0,context.canvas.width,context.canvas.height);
fillRect(0,0,context.canvas.width,context.canvas.height);
//在Mousemove上,在鼠标周围创建“手电筒”,以便看穿画布
$(窗口).mousemove(函数(事件){
x=event.pageX;
y=event.pageY;
半径=50;
context=document.getElementById(“测试”).getContext(“2d”);
//把画布涂成黑色。相反,它会把它画成白色?!
//context.fillStyle='#000';
//clearRect(0,0,context.canvas.width,context.canvas.height);
//fillRect(0,0,context.canvas.width,context.canvas.height);
context.beginPath();
radialGradient=context.createRadialGradient(x,y,1,x,y,radius);
径向梯度。添加色阻(0,'rgba(255255,1');
径向梯度。加色停止(1,'rgba(0,0,0');
context.globalCompositeOperation=“目标输出”;
context.fillStyle=径向梯度;
弧(x,y,半径,0,数学PI*2,false);
context.fill();
closePath();
});


测试
此代码适用于我:

x = event.pageX;
y = event.pageY;
radius = 10;
context = canvas.getContext("2d");

context.fillStyle = "black";
context.fillRect(0, 0, context.canvas.width, context.canvas.height);

context.beginPath();
var radialGradient= context.createRadialGradient(x,y,1,x,y,radius);
radialGradient.addColorStop(0,"rgba(255,255,255,1");
radialGradient.addColorStop(1,"rgba(0,0,0,1)");
//context.globalCompositeOperation = "destination-out";
context.fillStyle = radialGradient; 
context.arc(x, y, radius, 0, Math.PI*2, false);
context.fill();
context.closePath();
这行代码似乎把它搞乱了
context.globalCompositeOperation=“destination out”


代码中还有一些毫无意义的行,如填充rect之前的起始路径和填充路径之后的fill()函数。您可以使用合成来创建手电筒效果:

  • 清理画布
  • 创建用作分隔缝的径向渐变
  • 填充径向渐变
  • 使用
合成绘制背景图像。图像将仅显示在径向渐变内
  • 使用
  • destination over合成将画布填充为黑色。黑色将填充现有径向渐变图像的“后面”

    下面是示例代码和演示:

    var canvas=document.getElementById(“canvas”);
    var ctx=canvas.getContext(“2d”);
    var cw=画布宽度;
    var ch=画布高度;
    函数reOffset(){
    var BB=canvas.getBoundingClientRect();
    offsetX=BB.left;
    offsetY=BB.top;
    }
    var offsetX,offsetY;
    reOffset();
    onscroll=函数(e){reOffset();}
    onresize=函数(e){reOffset();}
    $(“#canvas”).mousemove(函数(e){handleMouseMove(e);});
    var半径=30;
    var img=新图像();
    img.onload=函数(){
    抽签(150150,30);
    }
    img.src=https://dl.dropboxusercontent.com/u/139992952/multple/annotateMe.jpg'
    功能图(cx、cy、半径){
    ctx.save();
    ctx.clearRect(0,0,cw,ch);
    var radialGradient=ctx.createRadialGradient(cx,cy,1,cx,cy,radius);
    径向梯度。addColorStop(0,'rgba(0,0,0,1');
    径向梯度.addColorStop(.65,'rgba(0,0,0,1');
    径向梯度。加色停止(1,'rgba(0,0,0');
    ctx.beginPath();
    ctx.弧(cx,cy,半径,0,数学PI*2);
    ctx.fillStyle=径向梯度;
    ctx.fill();
    ctx.globalCompositeOperation='source-top';
    ctx.drawImage(img,0,0);
    ctx.globalCompositeOperation='destination-over';
    ctx.fillStyle='black';
    ctx.fillRect(0,0,cw,ch);
    ctx.restore();
    }
    功能手柄移动(e){
    //告诉浏览器我们正在处理此事件
    e、 预防默认值();
    e、 停止传播();
    mouseX=parseInt(e.clientX-offsetX);
    mouseY=parseInt(例如clientY-offsetY);
    抽签(mouseX,mouseY,30);
    }
    body{背景色:象牙;}
    #画布{边框:1px纯红;}
    
    移动鼠标以“手电筒”显示图像
    
    通过将画布直接定位到图像上,可以实现聚光灯效果。使画布与图像大小相同,并将合成操作设置为“异或”,以便在同一位置绘制的两个黑色像素相互抵消

    context.globalCompositeOperation = 'xor';
    
    现在,您可以将画布绘制为黑色,并围绕鼠标光标填充一个黑色圆圈。结果是黑色表面上有一个洞,显示了下面的图像

    // Paint the canvas black.
    context.fillStyle = '#000';
    context.clearRect(0, 0, width, height);
    context.fillRect(0, 0, width, height);
    // Paint a black circle around x, y.
    context.beginPath();
    context.arc(x, y, spotlightRadius, 0, 2 * Math.PI);
    context.fillStyle = '#000';
    context.fill();
    // With xor compositing, the result is a circular hole.
    
    要使聚光灯的边缘模糊,请定义一个以鼠标位置为中心的径向渐变,并在其周围填充一个正方形

    var gradient = context.createRadialGradient(x, y, 0, x, y, spotlightRadius);
    gradient.addColorStop(0, 'rgba(0, 0, 0, 1)');
    gradient.addColorStop(0.9, 'rgba(0, 0, 0, 1)');
    gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
    context.fillStyle = gradient;
    context.fillRect(x - spotlightRadius, y - spotlightRadius,
                     2 * spotlightRadius, 2 * spotlightRadius);
    
    下面的代码片段演示了使用纯JavaScript的两种方法。要从边缘清晰的聚光灯更改为边缘模糊的聚光灯,请单击图像上方的复选框

    函数getOffset(元素,祖先){ 左向量=0, top=0; while(元素!=祖先){ left+=element.offsetLeft; top+=元素offsetTop; element=element.parentNode; } 返回{left:left,top:top}; } 函数getMousePosition(事件){ event=event | | window.event; 如果(event.pageX!==未定义){ 返回{x:event.pageX,y:event.pageY}; } 返回{ x:event.clientX+document.body.scrollLeft+ document.documentElement.scrollLeft, y:event.clientY+document.body.scrollTop+ document.documentElement.scrollTop }; } window.onload=函数(){ var spotlightRadius=60, container=document.getElementById('container'), canvas=document.createElement('canvas'), image=container.getElementsByTagName('img')[0], 宽度=画布。宽度=图像。宽度, 高度=画布高度=图像高度, context=canvas.getContext('2d'); context.globalCompositeOperation='xor'; container.insertBefore(canvas,image.nextSibling); container.style.width=宽度+px; container.style.height=高度+px; var offset=getOffset(canvas,document.body); 清除=功能(){ context.fillStyle='#000'; clearRect(0,0,宽度,高度); fillRect(0,0,宽度,高度); }; 清除(); image.style.visibility='visible'; canvas.onmouseout=c