let canvas, circles;
const controls = {
view: {
x: 0,
y: 0,
zoom: 1
},
viewPos: {
prevX: null,
prevY: null,
isDragging: false
},
}
function setup() {
canvas = createCanvas(window.innerWidth, window.innerHeight);
canvas.mouseWheel(e => Controls.zoom(controls).worldZoom(e))
circles = Circle.create(100)
}
function draw() {
background(100)
translate(controls.view.x, controls.view.y);
scale(controls.view.zoom)
circles.forEach(circle => circle.show());
}
window.mousePressed = e => Controls.move(controls).mousePressed(e)
window.mouseDragged = e => Controls.move(controls).mouseDragged(e);
window.mouseReleased = e => Controls.move(controls).mouseReleased(e)
class Controls {
static move(controls) {
function mousePressed(e) {
controls.viewPos.isDragging = true;
controls.viewPos.prevX = e.clientX;
controls.viewPos.prevY = e.clientY;
}
function mouseDragged(e) {
const {
prevX,
prevY,
isDragging
} = controls.viewPos;
if (!isDragging) return;
const pos = {
x: e.clientX,
y: e.clientY
};
const dx = pos.x - prevX;
const dy = pos.y - prevY;
if (prevX || prevY) {
controls.view.x += dx;
controls.view.y += dy;
controls.viewPos.prevX = pos.x, controls.viewPos.prevY = pos.y
}
}
function mouseReleased(e) {
controls.viewPos.isDragging = false;
controls.viewPos.prevX = null;
controls.viewPos.prevY = null;
}
return {
mousePressed,
mouseDragged,
mouseReleased
}
}
static zoom(controls) {
// function calcPos(x, y, zoom) {
// const newX = width - (width * zoom - x);
// const newY = height - (height * zoom - y);
// return {x: newX, y: newY}
// }
function worldZoom(e) {
const {
x,
y,
deltaY
} = e;
const direction = deltaY > 0 ? -1 : 1;
const factor = 0.1;
const zoom = 1 * direction * factor;
controls.view.zoom += zoom;
controls.view.x += -(x * direction * factor);
controls.view.y += -(y * direction * factor);
}
return {
worldZoom
}
}
}
class Circle {
constructor(x, y) {
this.x = x;
this.y = y;
}
show() {
fill(255);
noStroke();
ellipse(this.x, this.y, 15, 15);
}
static create(count) {
return Array.from(Array(count), () => {
const x = random(-500, width + 500);
const y = random(-500, height + 500);
return new this(x, y);
})
}
}
body {margin: 0; padding: 0;}
canvas {vertical-align: top;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.min.js"></script>