我是画布的新手,所以感谢您的耐心等待。
我写了一个引擎,它在2个画布元素中创建了2个不同的图层,这些图层是一个在另一个上面。它们包含一些生成的图片,这些图片并不重要
我正在尝试创建一种效果,当我将鼠标移到顶层并点击时,它会显示底层。
这样的事情:
这是我到目前为止所尝试的:
如果我使用笔划创建阴影,那么更新剪裁区域会很慢+我不知道如何从中删除线条(见图片)。
如果我删除阴影效果,它的效果非常快,但我需要它。
我唯一想到的是如何加快速度,保存每次点击的坐标,然后将其重新计算成1个形状并在其上留下阴影 - 我仍然会有线条,但它会更快,因为不会有数千个圈子来画...
非常感谢任何帮助!
答案 0 :(得分:3)
您可以利用浏览器的内置插值将其用作伪低通滤镜,但首先将其涂成黑色:
根据您想要的模糊程度,您可以添加其他步骤。话虽这么说:模糊的阴影是一个密集的操作,无论它是如何扭曲和转动。例如,人们可以妥协只在鼠标上渲染阴影(如下面的演示)。
使用两层的示例。顶层可以让你绘制任何东西,底部会在绘图时在底部显示阴影版本。
var ctx = document.getElementById("top").getContext("2d"),
bctx = document.getElementById("bottom").getContext("2d"),
bg = new Image(),
isDown = false;
bg.src = "http://i.imgur.com/R2naCpK.png";
ctx.fillStyle = "#27f";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.globalCompositeOperation = "destination-out"; // "eraser"
ctx.canvas.onmousedown = function(e) {isDown = true};
window.onmousemove = function(e) {
if (!isDown) return;
var pos = getPos(ctx.canvas, e);
ctx.beginPath();
ctx.moveTo(pos.x + 10, pos.y);
ctx.arc(pos.x, pos.y, 10, 0, 2*Math.PI); // erase while drawing
ctx.fill();
};
window.onmouseup = function(e) {
if (isDown) {
isDown = false;
makeShadow();
}
};
function makeShadow(){
var w = bctx.canvas.width,
h = bctx.canvas.height,
offset = 7,
alpha = 0.75;
// reset alpha
bctx.globalAlpha = 1;
// normal comp mode to clear as it is faster than using "copy"
bctx.globalCompositeOperation = "source-over";
bctx.clearRect(0, 0, w, h);
// copy top-layer to bottom-layer
bctx.drawImage(ctx.canvas, 0, 0);
// comp. mode will only draw in to non-alpha pixels next
bctx.globalCompositeOperation = "source-in";
// black overlay
bctx.fillRect(0, 0, w, h);
// copy mode so we don't need an extra canvas
bctx.globalCompositeOperation = "copy";
// step 1: reduce to 50% (quality related - create more steps to increase blur/quality)
bctx.drawImage(bctx.canvas, 0, 0, w, h, 0, 0, w * 0.5, h * 0.5);
bctx.drawImage(bctx.canvas, 0, 0, w * 0.5, h * 0.5, 0, 0, w * 0.25, h * 0.25);
bctx.drawImage(bctx.canvas, 0, 0, w * 0.25, h * 0.25, 0, 0, w * 0.5, h * 0.5);
// shadow transparency
bctx.globalAlpha = alpha;
// step 2: draw back up to 100%, draw offset
bctx.drawImage(bctx.canvas, 0, 0, w * 0.5, h * 0.5, offset, offset, w, h);
// comp in background image
bctx.globalCompositeOperation = "destination-over";
bctx.drawImage(bg, 0, 0, w, h);
}
function getPos(canvas, e) {
var r = canvas.getBoundingClientRect();
return {x: e.clientX - r.left, y: e.clientY - r.top};
}
div {position:relative;border:1px solid #000;width:500px;height:500px}
canvas {position:absolute;left:0;top:0}
#bottom {background:#eee}
<div>
<canvas id="bottom" width=500 height=500></canvas>
<canvas id="top" width=500 height=500></canvas>
</div>