Вы можете использовать Path2D
Использование Path2D
для создания путей и их рендеринга по мере необходимости удобно и с точки зрения рендеринга пути немного быстрее, поскольку нет необходимости создавать дополнительные пути каждый раз при рендеринге пути.
Лучше всего создавать дополнительные пути вокруг начала координат (0,0), чтобы их можно было легко перемещать, вращать и масштабировать. при необходимости.
Пример создания нескольких путей с различным содержимым
function createRect() {
const path = new Path2D();
path.rect(-70, -45, 140, 90); // add the sub path;
return path;
}
function createCircle() {
const path = new Path2D();
path.arc(0, 0, 50, 0, Math.PI * 2); // add the sub path;
return path;
}
function createRandLines() {
const path = new Path2D();
var i = 10;
while(i--) {
path.moveTo(Math.random() * 20 - 10, Math.random() * 20 - 10);
path.lineTo(Math.random() * 20 - 10, Math.random() * 20 - 10);
}
return path;
}
Чтобы создать пути
const myCircle = createCircle();
const myRect = createCircle();
const myLines1 = createRandLines();
const myLines2 = createRandLines();
Затем можно отобразить любой из путей с помощью одной функции .
function strokePath(path, x, y, lineWidth = ctx.lineWidth, color = ctx.strokeStyle) { // defaults to current style
ctx.setTransform(1, 0, 0, 1, x, y); // position the path so its (0,0) origin is at x,y
ctx.lineWidth = lineWidth;
ctx.strokeStyle = color;
ctx.stroke(path);
}
Передача стиля положения и ширины линии для рисования пути.
const W = ctx.canvas.width;
const H = ctx.canvas.height;
strokePath(myCircle, Math.random() * W, Math.random() * H);
strokePath(myRect, Math.random() * W, Math.random() * H);
strokePath(myLines1, Math.random() * W, Math.random() * H);
strokePath(myLines2, Math.random() * W, Math.random() * H);
Пример
Более подробная функция рисования и некоторая организация в отношении функции создания пути.
В примере создается 4 пути один раз, а затем выполняется многократное использование aws их: случайное расположение, вращение, масштабирование, альфа-затухание, цвет и заполнение.
const W = canvas.width;
const H = canvas.height;
const ctx = canvas.getContext("2d");
ctx.lineCap = ctx.lineJoin = "round";
// Some math utils
Math.TAU = Math.PI * 2;
Math.rand = (m = 0, M = 1) => Math.random() * (M - m) + m;
Math.randItem = array => array[Math.random() * array.length | 0];
const FACE = [[-3,-38,-34,-32,-47,-16,-48,15,-36,34,-5,43,32,38,47,12,47,-21,25,-35],[-31,-19,-42,-6,-32,1,-9,-6,-6,-24],[5,-24,3,-6,29,2,40,-5,33,-19],[-30,15,-14,32,12,31,29,15,15,15,-2,23,-17,16],[-28,-14,-29,-6,-18,-9,-17,-15],[11,-17,12,-8,20,-6,22,-13,18,-16],[2,-39,0,-53,-9,-60],[-14,17,-16,26,-7,28,-5,22],[2,21,1,28,11,27,13,16]];
// Object to hold path types
const paths = {
rect() {
const path = new Path2D();
path.rect(-20, -10, 40, 20); // add the sub path;
return path;
},
ellipse() {
const path = new Path2D();
path.ellipse(0, 0, 20, 10, 0, 0, Math.TAU); // add the sub path;
return path;
},
randLines() {
const path = new Path2D();
var i = 10;
while (i--) {
path.moveTo(Math.rand(-20, 20), Math.rand(-20, 20));
path.lineTo(Math.rand(-20, 20), Math.rand(-20, 20));
}
return path;
},
face() {
const path = new Path2D();
FACE .forEach(sub => { // each sub path
let i = 0;
path.moveTo(sub[i++] / 3, sub[i++] / 3);
while (i < sub.length) { path.lineTo(sub[i++] / 3, sub[i++] / 3) }
path.closePath();
});
return path;
}
};
// Function to draw scaled, rotated, faded, linewidth, colored path
function strokePath(path, x, y, scale, rotate, alpha, lineWidth, color, fillColor) {
ctx.lineWidth = lineWidth * (1 / scale); //Scale line width by inverse scale to ensure the pixel size is constant
ctx.setTransform(scale, 0, 0, scale, x, y); // position the path so its (0,0) origin is at x,y
ctx.rotate(rotate);
if (fillColor) {
ctx.globalAlpha = 1;
ctx.fillStyle = fillColor;
ctx.fill(path, "evenodd");
}
ctx.globalAlpha = alpha;
ctx.strokeStyle = color;
ctx.stroke(path);
}
// create some paths and colors
const pathArray = [paths.ellipse(), paths.rect(), paths.randLines(), paths.face()];
const colors = "#F00,#FA0,#0B0,#0AF,#00F,#F0A,#000,#888".split(",");
drawRandomPath();
function drawRandomPath() {
strokePath(
Math.randItem(pathArray), // random path
Math.rand(0, W), Math.rand(0, H), // random pos
Math.rand(0.25, 1), // random scale
Math.rand(0, Math.TAU), // random rotate
Math.rand(0.5, 1), // random alpha
1, // constant lineWidth
Math.randItem(colors), // random color
Math.rand() < 0.2 ? "#EED" : undefined, // Fill 1 in 5 with white
);
setTimeout(drawRandomPath, 250); // draw another path every quarter second.
}
* {margin:0px}
canvas {border:1px solid}
<canvas id="canvas" width="600" height="190"></canvas>