我试图在画布上实现由 mousemove 控制的无限背景场景滚动
我在 requestAnimationFrame 中的工作几乎正确
y1 = y1 >= h? y1 - h : y1; // y1 is the current mouse position on('drag') less the offset if the position is greater than height of canvas reset with offset
c.font="20px Georgia";
c.clearRect(0,0, w, h); // w, h is the width and height of canvas
c.save();
//c.translate(0, y1);
for (var i = 0; i < numImages; i++) { // number of images to be drawn to fill area
var y = y1 + (i * im.height); // reposition the images relative to mouse position
y = y >= h? - im.height + y1 : y; // if the image position is off screen then re position to top relative to mouse
c.drawImage(im, 0, y, im.width, im.height);
}
c.fillText("y: " + y,10,190);
c.restore();
然而,当我到达画布边缘并且需要&#34;循环&#34;时会出现问题。图像...无法弄清楚如何在离开视图后重新定位图像相对于鼠标位置
对此有何见解?
更新
我能够连续滚动,但我相信它会被文档元素上的 e.preventDefault 搞砸了>当我在画布元素本身上运行 &#39; touchmove&#39; 时...
在画布或文档上运行代码是否更安全?
答案 0 :(得分:1)
以下是创建无限全景的一种方法:
从源图像创建水平镜像图像。
创建一个动画循环,首先绘制原始&amp;然后是原始图像右侧的镜像..
向右平移:对于每个循环,将图像向左偏移1个像素(偏移 - )。当偏移量是原始+镜像宽度的大小时,则将偏移量重置为零。
向左平移:以偏移= - (原始+镜像宽度)开始,每个循环向右偏移1个像素(偏移++)。当偏移为零时,将偏移重置为 - (原始+镜像)。
鼠标控制:您可以使用鼠标X位置来确定计算所需的偏移量(这又决定了您在无限全景图中的位置)。
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var infiniteImage;
var infiniteImageWidth;
var img=document.createElement("img");
img.onload=function(){
// use a tempCanvas to create a horizontal mirror image
// This makes the panning appear seamless when
// transitioning to a new image on the right
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=img.width*2;
tempCanvas.height=img.height;
tempCtx.drawImage(img,0,0);
tempCtx.save();
tempCtx.translate(tempCanvas.width,0);
tempCtx.scale(-1,1);
tempCtx.drawImage(img,0,0);
tempCtx.restore();
infiniteImageWidth=img.width*2;
infiniteImage=document.createElement("img");
infiniteImage.onload=function(){
pan();
}
infiniteImage.src=tempCanvas.toDataURL();
}
img.crossOrigin="anonymous";
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/mountain.jpg";
var fps = 60;
var offsetLeft=0;
function pan() {
// increase the left offset
offsetLeft+=1;
if(offsetLeft>infiniteImageWidth){ offsetLeft=0; }
ctx.drawImage(infiniteImage,-offsetLeft,0);
ctx.drawImage(infiniteImage,infiniteImage.width-offsetLeft,0);
setTimeout(function() {
requestAnimationFrame(pan);
}, 1000 / fps);
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<h4>Infinite panorama using mirror image</h4>
<canvas id="canvas" width=500 height=143></canvas>
答案 1 :(得分:0)
最简单的方法是做两次传球:一次传球,一次传球
y1 = y1 >= h? y1 - h : y1; // y1 is the current mouse position on('drag') less the offset if the position is greater than height of canvas reset with offset
c.font="20px Georgia";
c.clearRect(0,0, w, h); // w, h is the width and height of canvas
c.save();
var cumulatedHeight=0;
for (var i = 0; i < numImages; i++) { // number of images to be drawn to fill area
var y = y1 + cumulatedHeight; // reposition the images relative to mouse position
if (y>h) break;
c.drawImage(im, 0, y, im.width, im.height);
cumulatedHeight+= im.height;
}
cumulatedHeight=0;
for (var i = numImage-1; i >=0; i--) { // number of images to be drawn to fill area
cumulatedHeight+= im.height;
var y = y1 - cumulatedHeight; // reposition the images relative to mouse position
if (y+im.height<0) break;
c.drawImage(im, 0, y, im.width, im.height);
}
c.fillText("y: " + y,10,190);
c.restore();
(你可能会注意到我开始工作以防你想要不同高度的图像:只需添加
var im = someImageArray[i];
在每个for循环中。)