html5-canvas - HTML5 Canvas - 为带有阴影的透明 png 添加边框
问题描述
在此画布脚本中,我仍在尝试解决两个问题,以使此图像具有我想要的外观。绿色仅用于演示。最终它将是带有灰色阴影的白色。
1)我想在图像获得绿色边框后为其添加灰色阴影。
2)我希望绿色边框的角是方形的,而不是圆形的。
var c = document.getElementById("canvas"),
ctx = c.getContext("2d"),
opaqueAlpha = 255,
img = new Image();
img.onload = function(){
ctx.shadowColor = '#0f0'; // green for demo purposes
ctx.shadowBlur = 20;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.drawImage(img, 30, 30);
img = ctx.getImageData(0, 0, ctx.canvas.width - 1, ctx.canvas.height - 1);
// turn all non-transparent pixels to full opacity
for (var i = img.data.length; i > 0; i -= 4) {
if (img.data[i+3] > 0) {
img.data[i+3] = opaqueAlpha;
}
}
// write transformed opaque pixels back to image
ctx.putImageData(img, 0, 0);
// trying to get the img again and then apply the gray drop shadow...not working
img = ctx.getImageData(0, 0, ctx.canvas.width - 1, ctx.canvas.height - 1);
// need to add a gray shadow to the now opaque border
ctx.shadowColor = '#aaa';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.putImageData(img, 0, 0);
};
img.setAttribute('crossOrigin', '');
img.src = "https://i.ezr.io/racks/bb0e6dd421df72541a79f271fb4f1a90.png?" + new Date().getTime();
<canvas id="canvas" width="800" height="800"></canvas>
解决方案
我会这样做:我知道图像的宽度和高度 ( img.width
, img.height
) 我也知道偏移量:30。您开始在距离原点 30 个单位的位置绘制图像。
由于这些区别看起来或多或少相同,我需要计算 3 个点才能知道如何绘制上凹口。
我希望这是你需要的:
var c = document.getElementById("canvas"),
cw = (canvas.width = 750),
ch = (canvas.height = 310),
ctx = c.getContext("2d"),
opaqueAlpha = 255,
img = new Image();
img.onload = function() {
let offset = 30;
let whiteBorder = 15;
ctx.drawImage(img, offset, offset);
var imgData = ctx.getImageData(0, 0, cw, ch);
var pixels = imgData.data;
//get some points
let y = offset + 5;
let index = y * imgData.width * 4;
let x1;
for (let i = 0; i < imgData.width * 4; i += 4) {
if (pixels[index + i + 3] > 0) {
//console.log(i / 4);
x1 = i / 4;
break;
}
}
let x2;
for (let i = imgData.width * 4; i > 0; i -= 4) {
if (pixels[index + i] > 0) {
//console.log(i / 4);
x2 = i / 4;
break;
}
}
let x = (offset + 5) * 4;
let y1;
for (let i = 0; i < imgData.height; i++) {
if (pixels[i * imgData.width * 4 + x] > 0) {
//console.log(i);
y1 = i;
break;
}
}
// draw the border behind the image
ctx.globalCompositeOperation='destination-over';
ctx.beginPath();
ctx.moveTo(offset, img.height + offset);
ctx.lineTo(img.width + offset, img.height + offset);
ctx.lineTo(img.width + offset, y1);
ctx.lineTo(x2, y1);
ctx.lineTo(x2, offset);
ctx.lineTo(x1, offset);
ctx.lineTo(x1, y1);
ctx.lineTo(offset, y1);
ctx.closePath();
ctx.strokeStyle = "white";
ctx.lineWidth = 25;
ctx.stroke();
};
img.setAttribute("crossOrigin", "");
img.src =
"https://i.ezr.io/racks/bb0e6dd421df72541a79f271fb4f1a90.png?" +
new Date().getTime();
canvas{
filter:drop-shadow(0px 0px 5px #333);
}
<canvas id="canvas"></canvas>
推荐阅读
- php - 使 Laravel Jetstream 团队能够配置自己的 SSO 登录
- r - ggplot 中的 Geom_errorbar 未显示正确的标准错误
- python - Matplotlib 函数动画不为预先计算的数据设置动画
- angular - 在 Angular 应用程序中找不到名称“缓冲区”错误
- ruby - 使用 ruby twilio 进行外呼
- list - 处理 600 万个项目的列表
- javascript - MySQL Array 变成一个对象
- c# - 如何声明非托管结构的 C# 托管等效项?
- ajax - Ajax 调用返回未定义对象
- sockets - 使用 useEffect 时重复的 socket.io 侦听器