在剪裁的画布中移动所有图像
Moving All Images In A Clipped Canvas
好的,所以我刚刚研究了Canvas元素,但遇到了一个障碍。
我发现了一个演示,它使用箭头键将三个图像在一个图像的顶部移动。
然而,我剪切了其中一个,下面的图像现在没有移动,即使上面剪切的图像移动了。
HTML:
<canvas id="parallax-canvas">
Sorry, your browser does not support HTML5 Canvas.
</canvas>
CSS:
.parallax-canvas {
width: 400px;
height: 300px;
}
JavaScript:
$(document).ready(function() {
var w = $("#parallax-canvas").width();
var h = $("#parallax-canvas").height();
var sky = new Image();
sky.src = "assets/img/sky.jpg";
var skydx = 2;
var skyx = 0;
var mountains = new Image();
mountains.src ="assets/img/mountains.png";
var mountainsdx = 10;
var mountainsx = 0;
var jeep = new Image();
jeep.src ="assets/img/jeep.png";
var jeepx = 100;
var jeepy = 210;
var jeepsx = 0;
var jeepsxWidth = 155;
var cntx = $("#parallax-canvas")[0].getContext("2d");
setInterval(draw, 10, cntx);
$(window).keydown(function(evt) {
switch (evt.keyCode) {
case 37: // Left arrow
if ((skyx + skydx) > skydx)
skyx -= skydx;
else
skyx = w;
if ((mountainsx + mountainsdx) > mountainsdx)
mountainsx -= mountainsdx;
else
mountainsx = 398;
if (jeepsx > 0)
jeepsx -= jeepsxWidth;
else
jeepsx = (jeepsxWidth*2);
break;
case 39: // Right arrow
if ((skyx + skydx) < (w - skydx))
skyx += skydx;
else
skyx = 0;
if ((mountainsx + mountainsdx) < (w - mountainsdx))
mountainsx += mountainsdx;
else
mountainsx = 0;
if (jeepsx < (jeepsxWidth*2))
jeepsx += jeepsxWidth;
else
jeepsx = 0;
break;
}
});
function draw(_cntx) {
drawRectangle(_cntx, 0, 0, w, h);
_cntx.drawImage(sky, skyx, 0, 300, 300, 0, 0, w, 300);
_cntx.beginPath();
_cntx.moveTo(0,300);
_cntx.lineTo(150,150);
_cntx.lineTo(300, 300);
_cntx.closePath();
_cntx.clip();
_cntx.drawImage(mountains, mountainsx, 0, 300, 300, 0, 0, w, 300);
_cntx.drawImage(jeep, jeepsx, 0, jeepsxWidth, 60, jeepx, jeepy, 155, 60);
}
function drawRectangle(_cntx, x, y, w, h) {
_cntx.beginPath();
_cntx.rect(x,y,w,h);
_cntx.closePath();
_cntx.fill();
_cntx.stroke();
}
});
我添加剪辑的部分是这个部分:
function draw(_cntx) {
drawRectangle(_cntx, 0, 0, w, h);
_cntx.drawImage(sky, skyx, 0, 300, 300, 0, 0, w, 300);
_cntx.beginPath();
_cntx.moveTo(0,300);
_cntx.lineTo(150,150);
_cntx.lineTo(300, 300);
_cntx.closePath();
_cntx.clip();
_cntx.drawImage(mountains, mountainsx, 0, 300, 300, 0, 0, w, 300);
_cntx.drawImage(jeep, jeepsx, 0, jeepsxWidth, 60, jeepx, jeepy, 155, 60);
}
如果从beginPath方法移除并将其包含到剪辑方法中,将允许三个图像全部移动。
发生了什么:按下左右箭头键时,天空图像不会移动,山脉和吉普车会被剪裁,但会在剪裁区域内移动。
我想发生的事情:天空图像移动,以及剪辑区域的山脉和吉普车。
还有:
我想知道如何使用箭头键移动剪切区域。我的意思是,目前有一个剪切区域,通过向左和向右按压,图像会移动,但剪切(剪切)区域保持静止。我想知道(如果可能的话)如何使用箭头键移动剪切区域。
正在使用的演示:http://www.ibm.com/developerworks/web/library/wa-parallaxprocessing/
不幸的是,无法设置Fiddle,因为图像不在网站上,所以无法提供URL,但.zip在网站上。通过复制和粘贴代码的底部,他们的方法在JavaScript文件中,这就是我得到的。
谢谢你的帮助!
编辑:感谢Ken在缩短代码和提高效率方面的帮助。然而,到目前为止,还没有什么能回答我最初关于如何移动图像以及剪切位置的问题。
您需要为画布设置大小-不要使用CSS来设置画布的大小:
<canvas id="parallax-canvas" width=500 height=300>
Sorry, your browser does not support HTML5 Canvas.
</canvas>
同样,你需要从画布上读取合适的尺寸:
$(document).ready(function() {
var canvas = $("#parallax-canvas")[0];
var w = canvas.width;
var h = canvas.height;
...
每次按下光标键时,都需要重新绘制所有内容。画布不知道里面画了什么——它只是一堆像素,所以我们需要自己提供更新的逻辑。
Update似乎我错过了您从setInterval循环进行重绘的机会,所以这不太适用,但我保留了这个例子,因为它可能是一种更好的方法,因为您只需要在实际发生变化时进行更新。例如,一个总是重新绘制所有内容的循环会很快耗尽电池电量。。
例如:
$(window).keydown(function(evt) {
switch (evt.keyCode) {
case 37: // Left arrow
if ((skyx + skydx) > skydx)
skyx -= skydx;
else
skyx = w;
if ((mountainsx + mountainsdx) > mountainsdx)
mountainsx -= mountainsdx;
else
mountainsx = 398;
if (jeepsx > 0)
jeepsx -= jeepsxWidth;
else
jeepsx = (jeepsxWidth*2);
draw(cntx );
break;
...
你需要在其他动作中重复这个动作。
由于加载是异步的,因此加载图像的方式也会遇到问题。您需要通过点击onload
处理程序来处理加载:
var sky = new Image();
sky.onload = functionToHandleLoad;
sky.src = "assets/img/sky.jpg";
当你加载许多图像时,你需要对图像进行计数或使用批量加载程序,如我的YAIL加载程序。
对于剪辑,使用保存/恢复很重要,因为当前浏览器无法很好地处理剪辑区域的手动重置:
function draw(_cntx) {
drawRectangle(_cntx, 0, 0, w, h);
_cntx.drawImage(sky, skyx, 0, 300, 300, 0, 0, w, 300);
_cntx.beginPath();
_cntx.moveTo(0,300);
_cntx.lineTo(150,150);
_cntx.lineTo(300, 300);
_cntx.closePath();
_cntx.save(); /// save current clip region
_cntx.clip();
_cntx.drawImage(mountains, mountainsx, 0, 300, 300, 0, 0, w, 300);
_cntx.drawImage(jeep, jeepsx, 0, jeepsxWidth, 60, jeepx, jeepy, 155, 60);
_cntx.restore(); /// reset clip
}
在回答的时候,那里没有小提琴,所以我还没有检查代码的其他部分,但我认为这应该是一个好的开始。
此功能
function drawRectangle(_cntx, x, y, w, h) {
_cntx.beginPath();
_cntx.rect(x,y,w,h);
_cntx.closePath();
_cntx.fill();
_cntx.stroke();
}
可以简化为:
function drawRectangle(_cntx, x, y, w, h) {
_cntx.fillRect(x, y, w, h);
_cntx.strokeRect(x, y, w, h);
}
不需要关闭rect上的路径,并且不需要使用fillRect/strokeRect的beginPath。
- 如何阻止图像移动并根据击键进行操作
- Photoshop脚本:将图像移动到位置x,y
- 使大图像移动的jQuery动画更流畅
- 如何通过按住键而不是重复按下来使图像移动
- 织物.js:将剪切的图像移动到固定的剪切蒙版后面
- 灯箱将图像移动到右下角
- 到达容器边界时停止图像移动
- HTML5画布图像移动闪烁
- 如何在修改后将堆叠的图像移动到另一页
- 垂直滚动鼠标时图像移动
- 旋转木马图像移动到不正确的地方点击事件
- 如何在用户滚动页面时触发图像移动
- 为什么我的代码在布朗运动下旋转针图像移动针的位置?为什么原点的图像是分散的?
- JavaScript在使用DOCTYPE时失去图像移动功能
- 如何使用低分辨率的图像移动
- 将图像移动到鼠标的位置
- 如何使用Javascript点击按钮使图像移动
- 将图像移动到指定的最小值
- 如何让标题随着图像移动
- 使JavaScript图像移动时滚动更平滑