使用 context.putImageData html canvas 中的阴影
Dropshadow in html canvas using context.putImageData
在 html canvas 中,我试图在包含透明片段的图像上生成阴影。此图像由代码生成,然后使用 ctx.putImageData(dst, 0, 0);
绘制到 canvas
问题是以下代码没有生成任何阴影:
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 15;
ctx.shadowColor = 'rgba(0,0,0,1)';
ctx.putImageData(dst, 0, 0);
如有任何帮助,我们将不胜感激
ctx.putImageData()
会将上下文中的像素替换为您放置的 ImageData 中包含的像素。
没有像 shadowBlur 这样的上下文 属性,也没有过滤器,也没有 globalCompositeOperation,甚至没有矩阵变换会影响它。即使 ImageData 中的透明像素在上下文中也是透明的。
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'salmon';
ctx.fillRect(0,0,300,150);
ctx.translate(120, 50);
ctx.rotate(Math.PI/3);
ctx.translate(-25, -25);
ctx.filter = 'blur(5px)';
ctx.globalCompositeOperation = 'lighter';
ctx.fillStyle = '#0000FF';
ctx.fillRect(0,0,50,50);
setTimeout(() => {
// at this time, all previous filters, transform, gCO are still active
const bluerect = ctx.createImageData(50,50);
const data = new Uint32Array(bluerect.data.buffer);
data.fill(0xFFFF0000); // blue
ctx.putImageData(bluerect, 0, 0); // same as our previous fillRect();
// a transparent ImageData (smaller)
const transrect = ctx.createImageData(25, 25);
ctx.putImageData(transrect, 170, 50); // push a bit farther;
}, 1500);
body {
background: lightblue;
}
<canvas id="canvas"></canvas>
那么,如何处理 ImageData 并且仍然能够在其上应用上下文的属性?
通过第二个离屏 canvas,您将在其上放置 ImageData,然后您将在主 canvas 上绘制。 drawImage
接受 HTMLCanvasElement 作为源,它受 shadowBlur 等上下文属性的影响:
const ctx = canvas.getContext('2d');
ctx.shadowBlur = 12;
ctx.shadowColor = "red";
// our ImageData
const bluerect = ctx.createImageData(50,50);
const data = new Uint32Array(bluerect.data.buffer);
data.fill(0xFFFF0000); // blue
// create a new canvas, the size of our ImageData
const offscreen = document.createElement('canvas');
offscreen.width = bluerect.width;
offscreen.height = bluerect.height;
// put our ImageData on it
offscreen.getContext('2d')
.putImageData(bluerect, 0, 0);
// draw it on main canvas
ctx.drawImage(offscreen, 50, 50);
<canvas id="canvas"></canvas>
现在,新的浏览器也可以在不使用第二个浏览器的情况下通过从 ImageData 生成 ImageBitmap 来执行此操作,但此操作是异步的,因此您可能仍然更喜欢旧方法.
const ctx = canvas.getContext('2d');
ctx.shadowBlur = 12;
ctx.shadowColor = "red";
// our ImageData
const bluerect = ctx.createImageData(50,50);
const data = new Uint32Array(bluerect.data.buffer);
data.fill(0xFFFF0000); // blue
// create an ImageBitmap from our ImageData
createImageBitmap(bluerect)
.then(bitmap => { // later
ctx.drawImage(bitmap, 50, 50);
});
<canvas id="canvas"></canvas>
在 html canvas 中,我试图在包含透明片段的图像上生成阴影。此图像由代码生成,然后使用 ctx.putImageData(dst, 0, 0);
问题是以下代码没有生成任何阴影:
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 15;
ctx.shadowColor = 'rgba(0,0,0,1)';
ctx.putImageData(dst, 0, 0);
如有任何帮助,我们将不胜感激
ctx.putImageData()
会将上下文中的像素替换为您放置的 ImageData 中包含的像素。
没有像 shadowBlur 这样的上下文 属性,也没有过滤器,也没有 globalCompositeOperation,甚至没有矩阵变换会影响它。即使 ImageData 中的透明像素在上下文中也是透明的。
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'salmon';
ctx.fillRect(0,0,300,150);
ctx.translate(120, 50);
ctx.rotate(Math.PI/3);
ctx.translate(-25, -25);
ctx.filter = 'blur(5px)';
ctx.globalCompositeOperation = 'lighter';
ctx.fillStyle = '#0000FF';
ctx.fillRect(0,0,50,50);
setTimeout(() => {
// at this time, all previous filters, transform, gCO are still active
const bluerect = ctx.createImageData(50,50);
const data = new Uint32Array(bluerect.data.buffer);
data.fill(0xFFFF0000); // blue
ctx.putImageData(bluerect, 0, 0); // same as our previous fillRect();
// a transparent ImageData (smaller)
const transrect = ctx.createImageData(25, 25);
ctx.putImageData(transrect, 170, 50); // push a bit farther;
}, 1500);
body {
background: lightblue;
}
<canvas id="canvas"></canvas>
那么,如何处理 ImageData 并且仍然能够在其上应用上下文的属性?
通过第二个离屏 canvas,您将在其上放置 ImageData,然后您将在主 canvas 上绘制。 drawImage
接受 HTMLCanvasElement 作为源,它受 shadowBlur 等上下文属性的影响:
const ctx = canvas.getContext('2d');
ctx.shadowBlur = 12;
ctx.shadowColor = "red";
// our ImageData
const bluerect = ctx.createImageData(50,50);
const data = new Uint32Array(bluerect.data.buffer);
data.fill(0xFFFF0000); // blue
// create a new canvas, the size of our ImageData
const offscreen = document.createElement('canvas');
offscreen.width = bluerect.width;
offscreen.height = bluerect.height;
// put our ImageData on it
offscreen.getContext('2d')
.putImageData(bluerect, 0, 0);
// draw it on main canvas
ctx.drawImage(offscreen, 50, 50);
<canvas id="canvas"></canvas>
现在,新的浏览器也可以在不使用第二个浏览器的情况下通过从 ImageData 生成 ImageBitmap 来执行此操作,但此操作是异步的,因此您可能仍然更喜欢旧方法.
const ctx = canvas.getContext('2d');
ctx.shadowBlur = 12;
ctx.shadowColor = "red";
// our ImageData
const bluerect = ctx.createImageData(50,50);
const data = new Uint32Array(bluerect.data.buffer);
data.fill(0xFFFF0000); // blue
// create an ImageBitmap from our ImageData
createImageBitmap(bluerect)
.then(bitmap => { // later
ctx.drawImage(bitmap, 50, 50);
});
<canvas id="canvas"></canvas>