gpt4 book ai didi

javascript - 显示具有阴影效果的底部 Canvas - 剪切区域内的阴影

转载 作者:行者123 更新时间:2023-11-28 19:13:13 25 4
gpt4 key购买 nike

我是 Canvas 新手,感谢您的耐心等待。

我编写了一个引擎,它在 2 个 Canvas 元素中创建 2 个不同的图层,这两个图层彼此重叠。它们包含一些生成的图片,这些图片在这里并不重要。
They are on over another

我正在尝试创建一种效果,当我将鼠标移到顶层并单击时,该效果将显示底层。

类似这样的:
enter image description here

这是我迄今为止尝试过的:

  1. 在 Canvas 元素上使用透明度并显示底部 Canvas (快速但不可用)
  2. 重新创建剪切区域。
    每当我按下鼠标时,我都会存储当前坐标并使用更新的剪切区域重新渲染 Canvas


如果我使用描边创建阴影,更新剪切区域会很慢+我不知道如何从中删除线条(见图)。
Lines show up

如果我删除阴影效果,它的工作速度非常快,但我需要它。

我想到的唯一一件事是如何加快速度,就是保存每次点击的坐标,然后将其重新计算为 1 个形状并在其上放置阴影 - 我仍然会有线条,但它会更快,因为不会有数千个圆圈需要绘制...

任何帮助将不胜感激!

最佳答案

您可以利用浏览器的内置插值,将其用作伪低通滤波器,但首先将其涂成黑色:

  • 将顶层复制到底层
  • 设置源输入补偿。模式
  • 绘制全黑
  • 设置源输入补偿。模式
  • 将图像缩小至 25%
  • 将 25% 区域缩小至原始区域的 50%(或当前区域的两倍)
  • 将当前 50% 的区域缩放回原来的 100%。它将变得模糊。

根据您想要的模糊程度,您可以添加其他步骤。话虽这么说:无论如何扭曲和转动,模糊阴影都是一项密集的操作。例如,我们可以做出妥协,仅在鼠标松开时渲染阴影(如下面的演示所示)。

示例

使用两层的示例。顶层让您可以绘制任何内容,底层将在稍后绘制时在底部显示阴影版本。

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>

关于javascript - 显示具有阴影效果的底部 Canvas - 剪切区域内的阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30392244/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com