Unlike the other HTML5 how to create a grid questions, I'm wondering how to make one draggable and scalable.
Drawing the grid is pretty simple:
var c = document.getElementById('canvas');
var ctx = c.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
c.width = width;
c.height = height;
drawGrid(width, height, 40);
function drawGrid(gridWidth, gridHeight, boxSize) {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
for (var i = 0; i <= gridWidth; i += boxSize) {
ctx.moveTo(i, 0);
ctx.lineTo(i, gridHeight);
}
for (var i = 0; i <= gridHeight; i += boxSize) {
ctx.moveTo(0, i);
ctx.lineTo(gridWidth, i);
}
ctx.strokeStyle = "rgba( 210, 210, 210, 1 )";
ctx.stroke();
}
html,
body {
overflow: hidden;
}
#canvas {
position: absolute;
top: 0;
left: 0;
}
<canvas id="canvas"></canvas>
Now to make it draggable, there are many ways of doing it, but I focused on creating the illusion of an infinite moving grid similar to this:
Example Image (Sorry, don't have enough credits yet)
As the graph moves toward the right, the lines that are hidden from the canvas size are moved back to the beginning, and vice versa. I'm not too sure how to go about moving the grid with the mouse, as well as the scaling. The lines tend to blur when scaled unlike SVGs. What's the quickest way of creating a grid to move around infinitely and scale?
EDIT: I took a similar approach to move the grid around using an image pattern to fill the screen.
var c = document.getElementById("canvas"),
ctx = c.getContext("2d");
var width = window.innerWidth;
var height = window.innerHeight;
var itemIsSelected = false;
var clicked = function(e) {
var x = e.pageX;
var y = e.pageY;
}
draw(width, height);
draggable('#app');
function draw(width, height) {
c.width = width;
c.height = height;
generateBackground();
}
function draggable(item) {
var isMouseDown = false;
document.onmousedown = function(e) {
e.preventDefault();
clicked.x = e.pageX;
clicked.y = e.pageY;
$(item).css('cursor', 'all-scroll');
isMouseDown = true;
};
document.onmouseup = function(e) {
e.preventDefault();
isMouseDown = false;
$(item).css('cursor', 'default');
};
document.onmousemove = function(e) {
e.preventDefault();
if (isMouseDown == true) {
var mouseX = e.pageX;
var mouseY = e.pageY;
generateBackground(mouseX, mouseY, clicked.x, clicked.y);
}
};
}
function generateBackground(x, y, initX, initY) {
distanceX = x - initX;
distanceY = y - initY;
ctx.clearRect(0, 0, c.width, c.height);
var bgImage = document.getElementById("bg")
var pattern = ctx.createPattern(bgImage, "repeat");
ctx.rect(0, 0, width, height);
ctx.fillStyle = pattern;
ctx.fill();
ctx.translate(Math.sqrt(distanceX), Math.sqrt(distanceY));
}
html,
body {
overflow: hidden;
}
#canvas {
top: 0;
left: 0;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>
<img src="https://i.imgur.com/2MupHjw.png" id="bg" hidden>
This method does not allow me to scroll left or up. It also speeds up the dragging after a distance and does not deal with negative motion well.