I'm trying to create an infinite looping canvas based on a main 'grid'. Scaled down fiddle here with the grid in the centre of the viewport.
JS Fiddle here
In the fiddle I have my main grid of coloured squares in the centre, I want them tiled infinitely in all directions. Obviously this isn't realistically possible, so I want to give the illusion of infinite by just redrawing the grids based on the scroll direction.
I found some good articles: https://developer.mozilla.org/en-US/docs/Games/Techniques/Tilemaps/Square_tilemaps_implementation:_Scrolling_maps
https://gamedev.stackexchange.com/questions/71583/html5-dynamic-canvas-grid-for-scrolling-a-big-map
And the best route seems to be to get the drag direction and then reset camera to that point, so the layers scroll under the main canvas viewport, thus meaning the camera can never reach the edge of the main viewport canvas.
I've worked on adding some event listeners for mouse drags :
Fiddle with mouse events
var bMouseDown = false;
var oPreviousCoords = {
'x': 0,
'y': 0
}
var oDelta;
var oEndCoords;
var newLayerTop;
$(document).on('mousedown', function (oEvent) {
bMouseDown = true;
oPreviousCoords = {
'x': oEvent.pageX,
'y': oEvent.pageY
}
});
$(document).on('mouseup', function (oEvent) {
bMouseDown = false;
oPreviousCoords = {
'x': oEvent.pageX,
'y': oEvent.pageY
}
oEndCoords = oDelta
if(oEndCoords.y < -300){
if(newLayerTop){
newLayerTop.destroy();
}
layerCurentPosition = layer.position();
newLayerTop = layer.clone();
newLayerTop.position({
x: layerCurentPosition.x,
y: layerCurentPosition.y -1960
});
stage.add(newLayerTop)
stage.batchDraw();
}
});
$(document).on('mousemove', function (oEvent) {
if (!bMouseDown) {
return;
}
oDelta = {
'x': oPreviousCoords.x - oEvent.pageX,
'y': oPreviousCoords.y - oEvent.pageY
}
});
But I can't reliably work out the co-ordinates for each direction and then how to reset the camera position.
As you need "infinite" canvas I suggest to not use scrolling and make canvas as large as user viewport. Then you can emulate camera and on every move, you need to draw a new grid on the canvas. You just need to carefully calculate the position of the grid.
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
draggable: true
});
const layer = new Konva.Layer();
stage.add(layer);
const WIDTH = 100;
const HEIGHT = 100;
const grid = [
['red', 'yellow'],
['green', 'blue']
];
function checkShapes() {
const startX = Math.floor((-stage.x() - stage.width()) / WIDTH) * WIDTH;
const endX = Math.floor((-stage.x() + stage.width() * 2) / WIDTH) * WIDTH;
const startY = Math.floor((-stage.y() - stage.height()) / HEIGHT) * HEIGHT;
const endY = Math.floor((-stage.y() + stage.height() * 2) / HEIGHT) * HEIGHT;
for(var x = startX; x < endX; x += WIDTH) {
for(var y = startY; y < endY; y += HEIGHT) {
const indexX = Math.abs(x / WIDTH) % grid.length;
const indexY = Math.abs(y / HEIGHT) % grid[0].length;
layer.add(new Konva.Rect({
x,
y,
width: WIDTH,
height: HEIGHT,
fill: grid[indexX][indexY]
}))
}
}
}
checkShapes();
layer.draw();
stage.on('dragend', () => {
layer.destroyChildren();
checkShapes();
layer.draw();
})
<script src="https://unpkg.com/konva@^2/konva.min.js"></script>
<div id="container"></div>
If you need scrolling you can listen wheel
event on stage and move into desired direction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With