[英]Make a bitmap wrap around the canvas for infinite scrolling
我正在尋找一種將位圖圖像包裹在畫布上的方法,以實現無限滾動效果。 我在看EaselJS,但是干凈的javascript代碼也足夠了。
現在,我正在向左移動圖像,當圖像達到某個標記時,它將重置自身。
來自動作腳本,有一個選項可以將位圖的像素“包裝”到另一側,從而永遠不會真正置換圖像,而是將像素包裝在圖像內部。 在畫布上的JavaScript中有可能嗎?
我當前的代碼:
this.update = function() {
// super large graphic
_roadContainer.x -= 9;
if(_roadContainer.x < -291) _roadContainer.x = 0;
}
從良好的風景圖像開始。
使用context.scale(-1,1)水平翻轉圖像。
將翻轉的圖像合並到原始圖像的右側。
因為我們已經完全鏡像了圖像,所以組合圖像的最左側和右側完全相同。
因此,當我們平移組合圖像並“用完圖像”時,我們可以在右側添加另一個組合圖像副本,從而實現無限+無縫平移。
這是代碼和小提琴: http : //jsfiddle.net/m1erickson/ywDp5/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
// thanks Paul Irish for this RAF fallback shim
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
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() {
requestAnimFrame(pan);
}, 1000 / fps);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=500 height=143></canvas><br>
</body>
</html>
您可以使用html5 canvas輕松實現此目的。
在這里查看drawImage規范:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#drawing-images
drawImage有3種樣式,第一種是圖像的簡單副本,第二種是縮放圖像,第三種是您想要的圖像,它允許在一次調用中執行剪切。
您要做的是:
-有一個計數器,該計數器將從零移動到圖像的寬度,然后再次循環到零。
-在每一幀中,最大程度地繪制可以在畫布上顯示的圖像。
-如果仍未繪制畫布的某些部分,請再次從零開始繪制圖像以填充畫布。
我做了一個小提琴,唯一重要的部分是動畫功能(其他東西是我經常在小提琴中使用的工具)。
(Rq:在此示例中,我假設兩個圖像足以填充畫布。)
http://jsfiddle.net/gamealchemist/5VJhp/
var startx = Math.round(startPos);
var clippedWidth = Math.min(landscape.width - startx, canvasWidth);
// fill left part of canvas with (clipped) image.
ctx.drawImage(landscape, startx, 0, clippedWidth, landscape.height,
0, 0, clippedWidth, landscape.height);
if (clippedWidth < canvasWidth) {
// if we do not fill the canvas
var remaining = canvasWidth - clippedWidth;
ctx.drawImage(landscape, 0, 0, remaining, landscape.height,
clippedWidth, 0, remaining, landscape.height);
}
// have the start position move and loop
startPos += dt * rotSpeed;
startPos %= landscape.width;
要回答我自己的問題:我找到了一種使用EaselJS實現此效果的方法。 這種方法的最大好處是您不必檢查位圖的位置。 它將無限滾動-無需將位置重置為0。
訣竅是用bitmapfill填充形狀。 您可以將位圖填充設置為無限重復。 然后,使用Matrix2D來確定位圖填充的偏移量。 由於它會自動重復,因此會產生滾動效果。
function.createRoad() {
// road has a matrix, shape and image
_m = new createjs.Matrix2D();
// this gets the image from the preloader - but this can be any image
_r = queue.getResult("road");
// this creates a shape that will hold the repeating bitmap
_roadshape = new createjs.Shape();
// put the shape on the canvas
addChild(_roadshape);
}
//
// the draw code gets repeatedly called, for example by requestanimationframe
//
function.drawRoad() {
// var _speed = 4;
_m.translate(-_speed, 0);
_roadshape.graphics.clear().beginBitmapFill(_r, "repeat", _m).rect(0, 0, 900, 400);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.