好的,所以我刚看了一下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方法,它将允许三个图像全部移动。
发生了什么:当按下左右箭头键时,天空图像不会移动,山峰和吉普车被剪裁但在剪裁区域内移动。
我想发生什么:在剪裁的区域内移动的天空图像以及山脉和吉普车。
ALSO:
我想知道如何用箭头按下移动剪裁区域。我的意思是,目前有一个剪切区域,通过左右按压图像移动但剪切(切出)区域保持静止。我想知道(如果可能的话)如何使用箭头键移动剪切区域。
正在使用的演示:http://www.ibm.com/developerworks/web/library/wa-parallaxprocessing/
遗憾的是无法设置小提琴,因为图片不在网站上,因此无法提供URL但.zip在网站上,并通过复制和粘贴代码的底部部分,其方法位于JavaScript文件中我得到了什么。
感谢您的帮助!
编辑:感谢Ken帮助您缩短代码和效率。到目前为止,没有什么能回答我关于如何移动图像以及剪切位置的初步问题。
答案 0 :(得分:1)
您需要为画布设置大小 - 不要将CSS用于set the size of a canvas:
<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;
...
每次按光标键时,都需要重绘所有内容。画布不知道画入了什么 - 它只是一堆像素,所以我们需要自己提供更新的逻辑。
更新似乎我错过了你正在从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";
在您加载许多图片时,您需要count the images或使用批量加载程序,例如我的YAIL loader。
对于剪辑,使用保存/恢复非常重要,因为当前浏览器无法正确处理剪辑区域的手动重置:
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。