gpt4 book ai didi

javascript - HTML5 Canvas createPattern API

转载 作者:行者123 更新时间:2023-12-03 10:28:47 26 4
gpt4 key购买 nike

我有这样的代码:

<body>
<canvas id="main" width=400 height=300></canvas>
<script>
var windowToCanvas = function(canvas, x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: (x - bbox.left) * (canvas.width / bbox.width),
y: (y - bbox.top) * (canvas.height / bbox.height)
};
};

image = new Image();
image.src = "redball.png";
image.onload = function (e) {
var canvas = document.getElementById('main'),
context = canvas.getContext('2d');

var pattern = context.createPattern(image, "repeat");

function draw(loc) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = pattern;
context.beginPath();
context.moveTo(loc.x, loc.y);
context.lineTo(loc.x + 300, loc.y + 60);
context.lineTo(loc.x + 70, loc.y + 200);
context.closePath();
context.fill();
}

canvas.onmousemove = function(e) {
var event = e || window.event,
x = event.x || event.clientX,
y = event.y || event.clientY,
loc = windowToCanvas(canvas, x, y);

draw(loc);
};
}
</script>
</body>

我调用createPattern API,使用背景图像填充三 Angular 形,但是当鼠标移动时,背景图像也会移动,我只想要背景图像在固定位置,我该如何解决这个问题?

最佳答案

将上下文模式视为 Canvas 上的背景图像。

模式始终从 Canvas 原点 [0,0] 开始。如果图案重复,则图案会以向右和向下重复的图 block 填充 Canvas 。

因此,如果您在 Canvas 上移动三 Angular 形,三 Angular 形将始终显示图案的不同部分。

有多种方法可以让三 Angular 形始终显示图案图像的相同部分。

选项#1 -- context.translate

将 Canvas 原点从默认的 [0,0] 位置移动到三 Angular 形位置 [loc.x,loc.y]。您可以通过 Canvas 转换来做到这一点。特别是,翻译命令将移动原点。移动原点也会移动图案的左上角起始位置,以便图案始终相对于移动三 Angular 形以相同的方式对齐:

var pattern = context.createPattern(image, "repeat");
context.fillStyle=pattern;

function draw(loc) {
context.clearRect(0, 0, canvas.width, canvas.height);
// the origin [0,0] is now [loc.x,loc.y]
context.translate(loc.x,loc.y);
context.beginPath();
// you are already located at [loc.x,loc.y] so
// you don't need to add loc.x & loc.y to
// your drawing coordinates
context.moveTo(0,0);
context.lineTo(300,60);
context.lineTo(70,200);
context.closePath();
context.fill();
// always clean up! Move the origina back to [0,0]
context.translate(-loc.x,-loc.y);
}

使用翻译的演示:

var windowToCanvas = function(canvas, x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: (x - bbox.left) * (canvas.width / bbox.width),
y: (y - bbox.top) * (canvas.height / bbox.height)
};
};

image = new Image();
image.src = "https://dl.dropboxusercontent.com/u/139992952/multple/jellybeans.jpg";
image.onload = function (e) {
var canvas = document.getElementById('main'),
context = canvas.getContext('2d');

var pattern = context.createPattern(image, "repeat");
context.fillStyle=pattern;

draw({x:0,y:0});

function draw(loc) {
context.clearRect(0, 0, canvas.width, canvas.height);
// the origin [0,0] is now [loc.x,loc.y]
context.translate(loc.x,loc.y);
context.beginPath();
// you are already located at [loc.x,loc.y] so
// you don't need to add loc.x & loc.y to
// your drawing coordinates
context.moveTo(0,0);
context.lineTo(300,60);
context.lineTo(70,200);
context.closePath();
context.fill();
// always clean up! Move the origina back to [0,0]
context.translate(-loc.x,-loc.y);
}


canvas.onmousemove = function(e) {
var event = e || window.event,
x = event.x || event.clientX,
y = event.y || event.clientY,
loc = windowToCanvas(canvas, x, y);

draw(loc);
};
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<h4>Move the mouse to move the triangle<br>The image is large, so be patient while it loads</h4>
<canvas id="main" width=600 height=600></canvas>

选项#2——合成

使用合成而不是图案化在三 Angular 形顶部绘制图像。合成是一种控制在 Canvas 上绘制的新像素如何与现有 Canvas 像素交互的方法。特别是,source-atop 合成将导致仅在新像素与现有非透明像素重叠的位置绘制任何新像素。您要做的是以纯色绘制三 Angular 形,然后使用 source-atop 合成仅在实心三 Angular 形像素所在的位置绘制图像:

function draw(loc) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(loc.x, loc.y);
context.lineTo(loc.x + 300, loc.y + 60);
context.lineTo(loc.x + 70, loc.y + 200);
context.closePath();
// fill the triangle with a solid color
context.fill();
// set compositing to 'source-atop' so
// new drawings will only be visible if
// they overlap a solid color pixel
context.globalCompositeOperation='source-atop';
context.drawImage(image,loc.x,loc.y);
// always clean up! Set compositing back to its default value
context.globalCompositeOperation='source-over';
}

使用合成的演示:

var windowToCanvas = function(canvas, x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: (x - bbox.left) * (canvas.width / bbox.width),
y: (y - bbox.top) * (canvas.height / bbox.height)
};
};

image = new Image();
image.src = "https://dl.dropboxusercontent.com/u/139992952/multple/jellybeans.jpg";
image.onload = function (e) {
var canvas = document.getElementById('main'),
context = canvas.getContext('2d');

var pattern = context.createPattern(image, "repeat");
context.fillStyle=pattern;

draw({x:0,y:0});

function draw(loc) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(loc.x, loc.y);
context.lineTo(loc.x + 300, loc.y + 60);
context.lineTo(loc.x + 70, loc.y + 200);
context.closePath();
// fill the triangle with a solid color
context.fill();
// set compositing to 'source-atop' so
// new drawings will only be visible if
// they overlap a solid color pixel
context.globalCompositeOperation='source-atop';
context.drawImage(image,loc.x,loc.y);
// always clean up! Set compositing back to its default value
context.globalCompositeOperation='source-over';
}

canvas.onmousemove = function(e) {
var event = e || window.event,
x = event.x || event.clientX,
y = event.y || event.clientY,
loc = windowToCanvas(canvas, x, y);

draw(loc);
};
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<h4>Move the mouse to move the triangle<br>The image is large, so be patient while it loads</h4>
<canvas id="main" width=600 height=600></canvas>

更多选项...

还有更多可能的选择。我将提及其中一些,但不会给出代码示例:

  • 创建填充三 Angular 形的 img 元素,并使用 drawImage(img,loc.x,loc.y) 在 Canvas 上移动该三 Angular 形图像

    <
  • 从三 Angular 形创建一个剪切区域。剪切区域导致新绘图仅显示在定义的剪切区域中。在这种情况下,新的绘制图像仅在三 Angular 形内部可见,而在三 Angular 形外部不可见。

  • 还有更多不那么传统的选项...

关于javascript - HTML5 Canvas createPattern API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29305326/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com