Implementation approach
- First, the original image was shifted in 8 directions
- Then fill the moved image with the stroke color
- Finally, overlay the original image
The core code
Generate the canvas
Create the canvas, load the image, and set the canvas width and height to the image width and height:
// create canvas
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// create image
const image = new Image();
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
};
image.src = url;
image.crossOrigin = "Anonymous";
Copy the code
Pan image
We construct an array with two elements representing one direction.
const dArr = [-1, -1.0, -1.1, -1, -1.0.1.0, -1.1.0.1.1.1];
Copy the code
Set the borderWidth to 4, and depending on the direction and the borderWidth, we can calculate the shifted x,y,
const borderWidth = 4;
const x = dArr[i] * borderWidth;
const y = dArr[i + 1] * borderWidth;
Copy the code
Loop the original drawing in all directions:
for (let i = 0; i < dArr.length; i += 2) {... ctx.drawImage(image, x, y); }Copy the code
The shifted image is equivalent to expanding the borderWidth of the original image.
Fill the stroke color
Here we need to use the Source-in pattern in globalCompositeOperation
Source-in: Draws a new image within the current image and displays only the new image.
ctx.globalCompositeOperation = "source-in";
ctx.fillStyle = "red";
ctx.fillRect(0.0, canvas.width, canvas.height);
Copy the code
Draw the artwork
Change the blend mode to the default source-over and draw the original image:
ctx.globalCompositeOperation = "source-over";
ctx.drawImage(image, 0.0);
Copy the code
Online code
Codepen address
The complete code
/** * image stroke *@param {string} url- Image address or base64 *@param {string} [borderColor=red] - Stroke color *@param {number} [borderWidth=4] - Stroke width *@return {string} base64- Picture string after stroke */
function strokeImage(url, borderColor='red', borderWidth = 4) {
return new Promise((resolve) = > {
// create canvas
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// create image
const image = new Image();
image.onload = draw;
image.src = url;
image.crossOrigin = "Anonymous";
function draw() {
canvas.width = image.width;
canvas.height = image.height;
const dArr = [-1, -1.0, -1.1, -1, -1.0.1.0, -1.1.0.1.1.1]; // offset array
// Pan the image
for (let i = 0; i < dArr.length; i += 2)
ctx.drawImage(image, dArr[i] * borderWidth, dArr[i + 1] * borderWidth);
// Fill the stroke color
ctx.globalCompositeOperation = "source-in";
ctx.fillStyle = borderColor;
ctx.fillRect(0.0, canvas.width, canvas.height);
// Add the original image
ctx.globalCompositeOperation = "source-over";
ctx.drawImage(image, 0.0); resolve(canvas.toDataURL()); }}); }Copy the code