在我的画布中,我有一个随光标移动的圆形。 我试图给它一个内在的阴影,但它不起作用。
以下是代码和演示:JSFIDDLE
function writeMessage(canvas, message, x, y) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var pattern = context.createPattern(imageResized, 'no-repeat'); //Use imageResized, not imageObj.
context.fillStyle = pattern;
context.fill();
context.font = '28pt Calibri';
context.fillStyle = 'white';
//context.fillText(message, x, y);
context.beginPath();
context.arc(x, y, 50, 0, 2 * Math.PI);
context.stroke();
context.beginPath();
context.lineWidth = 5;
context.shadowColor = 'black';
context.strokeStyle = "rgba(0,0,0,1)";
context.shadowBlur = 15;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.arc(x, y, 50, 0, 2 * Math.PI, false);
context.stroke();
context.restore();
}
我注意到如果我添加context.clip();
,这个设置会起作用但是它会使整个画布崩溃。
想知道这个圈子有内在阴影吗?
答案 0 :(得分:2)
尝试绘制弧,以便在提供帧的弧之前提供阴影。在beginPath之前保存上下文状态,并在阴影弧的中风后恢复它。您需要使阴影圆弧半径小于框架圆弧,以便阴影的外边缘被框架圆弧的笔划覆盖。阴影弧外部的外部阴影仍然被绘制,但被框架弧覆盖。
示例:
context.save();
context.beginPath();
context.lineWidth = 6;
context.shadowColor = 'black';
context.strokeStyle = "rgba(0,0,0,1)";
context.shadowBlur = 15;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.arc(x, y, 47, 0, 2 * Math.PI, false);
context.stroke();
context.restore();
context.save();
context.beginPath();
context.lineWidth = 6;
context.arc(x, y, 50, 0, 2 * Math.PI);
context.stroke();
context.restore();
您需要调整弧的大小,颜色和线宽以获得所需的效果。
答案 1 :(得分:2)
如果在像mousemove这样繁忙的处理程序中执行.clip会导致浏览器崩溃,您可以在应用程序开始时使用内部阴影预先构建一个圆圈,然后重复使用预先构建的圆圈,而不会影响性能。
以下是如何创建包含内部阴影圆的内存中画布。是的,它使用.clip,但它只在应用程序的开头使用它一次。
var PI2=Math.PI*2;
var cut=document.createElement('canvas');
var cutCtx=cut.getContext('2d');
cut.width=100;
cut.height=100;
cutCtx.arc(50,50,50,0,Math.PI*2);
cutCtx.closePath();
cutCtx.clip();
cutCtx.shadowColor='black'
cutCtx.shadowBlur=15;
for(var i=0;i<15;i++){
cutCtx.stroke();
}
然后在mousemove事件中绘制预先建立的圆圈并不是非常昂贵。
这是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var PI2=Math.PI*2;
var cut=document.createElement('canvas');
var cutCtx=cut.getContext('2d');
cut.width=100;
cut.height=100;
cutCtx.arc(50,50,50,0,Math.PI*2);
cutCtx.closePath();
cutCtx.clip();
cutCtx.shadowColor='black'
cutCtx.shadowBlur=15;
for(var i=0;i<15;i++){
cutCtx.stroke();
}
ctx.fillStyle='white';
ctx.fillRect(0,0,cw,ch);
$("#canvas").mousemove(function(e){handleMouseMove(e);});
function applyCut(mx,my){
// hide the background image by whiteing-out the canvas
ctx.fillRect(0,0,cw,ch);
// use compositing to "erase" a circle under the mouse
ctx.globalCompositeOperation='destination-out';
ctx.beginPath();
ctx.arc(mx,my,50,0,PI2);
ctx.closePath();
ctx.fill();
// draw the pre-built circle shadow under the mouse
ctx.globalCompositeOperation='source-over';
// Hint: the in-memory canvas can be an image source for
// your on-screen canvas
ctx.drawImage(cut,mx-50,my-50);
}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
applyCut(mouseX,mouseY);
}
body{ background-color: ivory; }
#wrapper{position:relative;}
#bk,#canvas{position:absolute;}
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move the mouse to reveal the image underneath</h4>
<div id=wrapper>
<img id=bk src=https://dl.dropboxusercontent.com/u/139992952/stackoverflow/tiger.png />
<canvas id="canvas" width=512 height=512></canvas>
</div>
答案 2 :(得分:0)
我刚刚为这种情况创建了Inset.js!
只需要设置ctx.shadowInset = true;
例如:http://codepen.io/patlillis/pen/RpEoKE
var ctx = canvas.getContext("2d");
var w = canvas.width = window.innerWidth;
var h = canvas.height = window.innerHeight;
// Set up circle styles.
ctx.shadowInset = true;
ctx.shadowBlur = 15;
ctx.shadowColor = 'black';
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillStyle = 'red';
// Set up mouse listener.
document.addEventListener('mousemove', function(e) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(e.clientX, e.clientY, 30, 0, 2 * Math.PI);
ctx.fill();
});