如何对角线重复 HTML 画布模式



我已经创建了一个画布图案,并希望在整个网页中对角线重复该图案。由于 repeat 属性仅支持 repeat-x、repeat-y 或双向重复,因此我现在将其设置为"无重复",并尝试使用偏移或平移对角线移动我的模式,但没有成功。

这是我现在得到的:

在此处输入图像描述

以下是我想要完成的: 在此处输入图像描述

我只是想模仿效果,不需要完全相同。

有人可以告诉我如何沿对角线继续我的模式吗?多谢!

以下是我的一些代码:

var patternCanvas = document.createElement('canvas');
			var patternContext = patternCanvas.getContext('2d');
			patternCanvas.width = 350;
			patternCanvas.height = 350;
			patternContext.fillStyle = "orange";
			patternContext.fillRect(0, 50, 150, 50);
			patternContext.fillRect(50, 0, 50, 150);
			patternContext.fillStyle = "black";
			patternContext.fillRect(100, 100, 150, 50);
			patternContext.fillRect(150, 50, 50, 150);
			patternContext.fillStyle = "green";
			patternContext.fillRect(200, 150, 150, 50);
			patternContext.fillRect(250, 100, 50, 150);
			patternContext.fillStyle = "darkred";
			patternContext.fillRect(0, 100, 50, 150);
			patternContext.fillRect(0, 150, 150, 50);
			patternContext.fillStyle = "blue";
			patternContext.fillRect(100, 150, 50, 150);
			patternContext.fillRect(50, 200, 150, 50);
			patternContext.fillStyle = "yellow";
			patternContext.fillRect(200, 200, 50, 150);
			patternContext.fillRect(150, 250, 150, 50);
		
			var canvas = document.getElementById("myCanvas");
			canvas.width = window.innerWidth;
			canvas.height = window.innerHeight;
			var context = canvas.getContext('2d');
			var pattern = context.createPattern(patternCanvas, 'no-repeat');
			context.fillStyle = pattern;
			context.fillRect(0, 0, 350, 350);
<canvas id="myCanvas"></canvas>

此解决方案将画布视为空白板,而不是复制/粘贴图案的位置。

它通过将画布划分为正方形并根据其在虚拟网格中的位置为每个正方形着色来创建重复图案的外观。

感谢 irchans 在数学方面的帮助。

const
// Creates a canvas, and a context
canvas = document.getElementById("myCanvas"),
context = canvas.getContext('2d'),
// Configures colors, unit-square size, and the number of unit squares to draw
colors = "blue,yellow,darkred,green,orange,black".split(","),
unit = 50,
gridDimensionX = 10,
gridDimensionY = 10;
// Makes the canvas wide enough for its content
canvas.width = unit * gridDimensionX;
canvas.height = unit * gridDimensionY;
// Builds a grid of squares, each of which is assigned a color
const grid = makeGrid(gridDimensionX, gridDimensionY, colors);
// Loops through the grid and draws each square
drawGrid(grid, context, unit);
// Defines the `makeGrid` function
function makeGrid(gridDimensionX, gridDimensionY, colors){
const grid = [];
for(let y = 0; y < gridDimensionY; y++){
const row = [];
for(let x = 0; x < gridDimensionX; x++){

// Assigns coordinates to each not-yet-drawn square, along two axes 
//   (rotated 60 degrees from the vertical and horizontal axes)
//   and groups squares according to these coordinates
cell = {
slantyRowGrp: Math.round((2 * y - x) / 5, 0),
slantyColGrp: Math.round((y + 2 * x) / 5, 0)
}

// Assigns a color to each square based on its 'slanty' grouping
cell.colorIndex = (cell.slantyRowGrp + 2 * cell.slantyColGrp) % colors.length;
cell.color = colors[cell.colorIndex];
// Adds the cell to the row
row.push(cell);
}
// Adds the completed row to the grid
grid.push(row);
}
// Returns the completed grid
return grid;
}
// Defines the `drawGrid` function
function drawGrid(grid, context, unit){
grid.forEach( (row, y) => {
row.forEach( (cell, x) => {
// Fills each square with its assigned color
context.fillStyle = cell.color;
context.fillRect(unit * x, unit * y, unit, unit);

// Displays the 'slanty' row and column group numbers
/*
context.fillStyle = "lightgrey";
context.fillText(
`${cell.slantyRowGrp}; ${cell.slantyColGrp}`,
unit * x + unit/2.5,
unit * y + unit/2
);
*/
});
});
}
<canvas id="myCanvas"></canvas>

这花了相当多的努力来实现。这是一个看似复杂的问题。

每个位置的移动类似于x = x + (iterationY/3) * 2y = iterationX尽管我的代码已经对 1/3 的ixiy进行了非规范化的迭代步骤,以便更容易推理交叉块移动,例如 1/3 的宽度或高度十字。

为了给每个十字分配一个id进行着色,我取一行和一列,其中x/y迭代的步长为1,作为row = iterationX % 2col = iterationY % 3,这给出了从0,1等开始的行,以及从0,1,2开始的col并重复。在这种情况下,我为 col 分配权重 2,因此id = row+(col*2),以确保每个 id 都是唯一的。最后,我定义了一个可以通过这个 id 引用的颜色数组。

const canvas = document.getElementById("canv");
const ctx = canvas.getContext('2d');
const w = window.innerWidth;
const h = window.innerHeight;
const s = 80;//size
const bs = s / 3;//block size
const gs = Math.max(w, h)/s;//grid size
canvas.width = w;
canvas.height = h;
let yAcc = 0;
let jx = 0;
let jy = 0;
const getColour = (jx, jy) => {
const row = (jx%2);//0, 1
const col = (jy % 3);//0, 1, 2
//00, 10, 01, 11, 02, 12
//0 , 1 , 2 , 3 , 4 , 5
const id = row + (col*2);
const colours = ['orange', 'blue', 'black', 'yellow', 'green', 'red']
return colours[id];
}
for(let ix = 0; ix < gs; ix+=1/3){

for(let iy = 0; iy < gs; iy+=1/3){
const colour = getColour(jx, jy);
let x = ix+iy*2-(gs);
let y = iy+ix*3-(gs);
ctx.fillStyle = colour;
ctx.beginPath();
ctx.lineWidth = 2;
ctx.rect(x * bs * 3, y * bs * 3 + bs, bs * 3, bs);

ctx.rect(x * bs * 3 + bs, y * bs * 3, bs, bs * 3);
ctx.fill();
ctx.closePath();
jy ++;
}
jx ++;
}
<canvas id="canv"></canvas>

最新更新