1 回答

TA貢獻(xiàn)1852條經(jīng)驗 獲得超1個贊
畫布填充(CanvasPatterns 和 CanvasGradients)始終相對于上下文的變換矩陣,因此它們確實默認(rèn)位于畫布的左上角,并且并不真正關(guān)心使用它們的路徑在哪里。
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = begin; //!\ ALWAYS WAIT FOR YOUR IMAGE TO LOAD BEFORE DOING ANYTHING WITH IT!
img.crossOrigin = "anonymous";
img.src = "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
function begin() {
const rect_size = 20;
ctx.fillStyle = ctx.createPattern( img, 'no-repeat' );
// drawing a checkerboard of several rects shows that the pattern doesn't move
for ( let y = 0; y < canvas.height; y += rect_size ) {
for ( let x = (y / rect_size % 2) ? rect_size : 0 ; x < canvas.width; x += rect_size * 2 ) {
ctx.fillRect( x, y, rect_size, rect_size );
}
}
}
<canvas id="canvas" width="500" height="500"></canvas>
現(xiàn)在,因為它們與上下文變換矩陣相關(guān),這意味著我們還可以通過更改該變換矩陣來移動它們:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = begin; //!\ ALWAYS WAIT FOR YOUR IMAGE TO LOAD BEFORE DOING ANYTHING WITH IT!
img.crossOrigin = "anonymous";
img.src = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Cool_bunny_sprite.png";
function begin() {
const rect_size = 244;
const max_speed = 5;
let x_speed = Math.random() * max_speed;
let y_speed = Math.random() * max_speed;
ctx.fillStyle = ctx.createPattern( img, 'repeat' );
let x = 0;
let y = 0;
requestAnimationFrame( anim );
function anim( now ) {
clear();
x = (x + x_speed);
y = (y + y_speed);
if( x > canvas.width || x < -rect_size ) {
x_speed = Math.random() * max_speed * -Math.sign( x_speed );
x = Math.min( Math.max( x, -rect_size ), canvas.width );
}
if( y > canvas.height || y < -rect_size ) {
y_speed = Math.random() * max_speed * -Math.sign( y_speed )
y = Math.min( Math.max( y, -rect_size ), canvas.height );
}
// we change the transformation matrix of our context
ctx.setTransform( 1, 0, 0, 1, x, y );
// we thus always draw at coords 0,0
ctx.fillRect( 0, 0, rect_size, rect_size );
ctx.strokeRect( 0, 0, rect_size, rect_size );
requestAnimationFrame( anim );
}
function clear() {
// since we changed the tranform matrix we need to reset it to identity
ctx.setTransform( 1, 0, 0, 1, 0, 0 );
ctx.clearRect( 0, 0, canvas.width, canvas.height );
}
}
<canvas id="canvas" width="300" height="300"></canvas>
我們甚至可以通過在聲明子路徑后更改變換矩陣來將路徑聲明與填充分離,當(dāng)然也可以將簡寫替換 fillRect()為beginPath(); rect(); fill()
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = begin; //!\ ALWAYS WAIT FOR YOUR IMAGE TO LOAD BEFORE DOING ANYTHING WITH IT!
img.crossOrigin = "anonymous";
img.src = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Cool_bunny_sprite.png";
function begin() {
const rect_size = 244;
const max_speed = 5;
let x_speed = Math.random() * max_speed;
let y_speed = Math.random() * max_speed;
ctx.fillStyle = ctx.createPattern( img, 'repeat' );
let x = 0;
let y = 0;
requestAnimationFrame( anim );
function anim( now ) {
clear();
x = (x + x_speed);
y = (y + y_speed);
if( x > canvas.width || x < -rect_size ) {
x_speed = Math.random() * max_speed * -Math.sign( x_speed );
x = Math.min( Math.max( x, -rect_size ), canvas.width );
}
if( y > canvas.height || y < -rect_size ) {
y_speed = Math.random() * max_speed * -Math.sign( y_speed )
y = Math.min( Math.max( y, -rect_size ), canvas.height );
}
// we declare the sub-path first, with identity matrix applied
ctx.beginPath();
ctx.rect( 50, 50, rect_size, rect_size );
// we change the transformation matrix of our context
ctx.setTransform( 1, 0, 0, 1, x, y );
// and now we fill
ctx.fill();
ctx.stroke();
requestAnimationFrame( anim );
}
function clear() {
// since we changed the tranform matrix we need to reset it to identity
ctx.setTransform( 1, 0, 0, 1, 0, 0 );
ctx.clearRect( 0, 0, canvas.width, canvas.height );
}
}
<canvas id="canvas" width="300" height="300"></canvas>
但就你而言,聽起來改變整個繪圖是最簡單、最慣用的方法。不太確定為什么要修改相對于相機的 x 和 y 坐標(biāo)。一般來說,如果我們使用相機對象,那么場景中的對象不必關(guān)心它,并且與世界保持相對關(guān)系。
- 1 回答
- 0 關(guān)注
- 142 瀏覽
添加回答
舉報