我正在开发一个项目,在 HTML Canvas 上覆盖图像并为其添加圆角和阴影。但是,我面临一个问题,即叠加图像内有不需要的白色内嵌边框。如何在覆盖图像周围添加透明边框轮廓而没有这种不需要的边框?我正在使用 JavaScript 和 Canvas API。 我也有兴趣在覆盖图像后面添加透明矩形,这样它看起来就像勾勒出覆盖图的轮廓,并且我可以单独控制轮廓的角半径
var canvas = document.getElementById ('mycanvas'); // access the canvas object
const background = document.getElementById("source");
background.onload = function() {
const overlay = new Image(300, 300)
overlay.src = 'https://images.unsplash.com/photo-1518826778770-a729fb53327c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1887&q=80';
overlay.onload = function() {
var context = canvas.getContext ('2d'); // access the canvas context
const canvasWidth = background.width; // Set your desired width
const canvasHeight = background.height; // Set your desired height
const ctx = canvas.getContext('2d');
// Draw the background image
ctx.drawImage(background, 0, 0, background.width, background.height);
const x = (canvas.width - overlay.width) / 2;
const y = (canvas.height - overlay.height) / 2;
const cornerRadius = 30;
const shadowBlur = 93;
const shadowOffsetX = 0;
const shadowOffsetY = -116;
const borderWidth = 30; // Set the width of the border
const borderColor = 'rgba(255, 255, 255, 0.5)';
ctx.fillStyle = ctx.createPattern(overlay, "no-repeat");
// Prepare the shadow
ctx.shadowBlur = shadowBlur;
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowOffsetX = shadowOffsetX;
ctx.shadowOffsetY = shadowOffsetY;
// Place our drawing so that we can see the full shadow
ctx.translate(x, y);
// Trace the rounded rectangle (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect)
ctx.roundRect(0, 0, overlay.width, overlay.height, cornerRadius);
ctx.fill();
// Draw a transparent border outline
ctx.strokeStyle = borderColor;
ctx.lineWidth = borderWidth;
ctx.stroke();
ctx.resetTransform();
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.fillStyle = "black";
}
}
<canvas id="mycanvas" width="500" height="500"></canvas>
<div style="display:none;">
<img id="source" src="https://images.unsplash.com/photo-1534644107580-3a4dbd494a95?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80" width="500" height="500" />
<img id="overlay" src="" width="300" height="300" />
</div>
看来您的问题是笔画和填充的顺序。
如果我们更改这些操作的顺序,结果如下:
之前:
之后:
我从您的示例中删除了很多代码以使其更短
var canvas = document.getElementById('mycanvas'); // access the canvas object
const background = document.getElementById("source");
background.onload = function() {
const overlay = new Image(300, 300)
overlay.src = 'https://images.unsplash.com/photo-1518826778770-a729fb53327c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1887&q=80';
overlay.onload = function() {
var context = canvas.getContext('2d'); // access the canvas context
const canvasWidth = background.width; // Set your desired width
const canvasHeight = background.height; // Set your desired height
const ctx = canvas.getContext('2d');
ctx.drawImage(background, 0, 0, background.width, background.height);
const x = (canvas.width - overlay.width) / 2;
const y = (canvas.height - overlay.height) / 2;
const cornerRadius = 30;
const borderWidth = 30; // Set the width of the border
const borderColor = 'rgba(255, 255, 255, 0.5)';
ctx.fillStyle = ctx.createPattern(overlay, "no-repeat");
ctx.translate(x, y);
ctx.roundRect(0, 0, overlay.width, overlay.height, cornerRadius);
ctx.strokeStyle = borderColor;
ctx.lineWidth = borderWidth;
ctx.stroke();
ctx.fill();
}
}
<canvas id="mycanvas" width="500" height="500"></canvas>
<div style="display:none;">
<img id="source" src="https://images.unsplash.com/photo-1534644107580-3a4dbd494a95?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80" width="500" height="500" />
<img id="overlay" src="" width="300" height="300" />
</div>