import kaplay from "./modules/kaplay.js"; const map = document.querySelector("map"); class KaplayMap { kp; opts = { minZoomLevel: 0, maxZoomLevel: 3, }; #zoomLevel = 0; #scaleTween = null; startMousePos = null; startCamPos = null; prevCamPos = null; moveVelocity = null; moveFriction = 0.25; moveDead = 1; #moveTween = null; constructor(kp, opts) { this.kp = kp; this.opts = { ...this.opts, ...opts, }; // Zooming this.kp.onScroll((delta) => { const scrollDist = -delta.y / 120; this.zoomTo(this.zoomLevel + scrollDist, this.kp.mousePos()); }); // Dragging this.kp.onUpdate(() => { const curCamPos = this.kp.camPos(); const camScale = 1 / this.kp.camScale().y; // ||| Completely unintelligible to the average person ||| // vvv Sorry y'all xwx vvv if (this.kp.isMousePressed()) { this.startMousePos = this.kp.mousePos(); this.startCamPos = this.kp.camPos(); } else if (this.kp.isMouseReleased() && this.prevCamPos != null) { this.moveVelocity = this.prevCamPos.sub(curCamPos).scale(1 / camScale); } if (this.kp.isMouseDown()) { this.prevCamPos = this.kp.camPos(); this.kp.camPos( this.startCamPos.sub( this.kp.mousePos().sub(this.startMousePos).scale(camScale) ) ); } else if (this.moveVelocity?.x != 0 && this.moveVelocity?.y != 0) this.kp.camPos(curCamPos.sub(this.moveVelocity?.scale(camScale) ?? 0)); // ^^^ Completely unintelligible to the average person ^^^ // ||| Sorry y'all xwx ||| if (this.moveVelocity == null) return; if ( this.moveVelocity.x <= this.moveDead && this.moveVelocity.x >= -this.moveDead ) this.moveVelocity.x = 0; if ( this.moveVelocity.y <= this.moveDead && this.moveVelocity.y >= -this.moveDead ) this.moveVelocity.y = 0; this.moveVelocity = this.moveVelocity.scale(1 - this.moveFriction); }); } get zoomLevel() { return this.#zoomLevel; } set zoomLevel(newZoom) { const cameraZoom = this.kp.camScale().y; let addLinear = newZoom; if (addLinear < this.opts.minZoomLevel) addLinear = this.opts.minZoomLevel; if (addLinear > this.opts.maxZoomLevel) addLinear = this.opts.maxZoomLevel; let linearToLog = Math.pow(2, addLinear); this.#zoomLevel = addLinear; if (this.#scaleTween != null) { this.#scaleTween.finish(); } this.#scaleTween = this.kp.tween( cameraZoom, linearToLog, 0.25, this.kp.camScale, this.kp.easings.easeOutQuad ); this.#scaleTween.then(() => { this.#scaleTween = null; }); } zoomTo(newZoom, position) { const curCamPos = this.kp.camPos(); const camScale = 1 / this.kp.camScale().y; const diff = this.kp.center().sub(position).scale(camScale); this.zoomLevel = newZoom; let newZoomLog = 1 / Math.pow(2, newZoom); const newDiff = this.kp.center().sub(position).scale(newZoomLog); if (newZoom < this.opts.minZoomLevel) return; if (newZoom > this.opts.maxZoomLevel) return; if (this.#moveTween != null) { this.#moveTween.finish(); } this.#moveTween = this.kp.tween( curCamPos, curCamPos.sub(diff).add(newDiff), 0.25, this.kp.camPos, this.kp.easings.easeOutQuad ); this.#moveTween.then(() => { this.#moveTween = null; }); } } const kp = kaplay({ canvas: map, focus: true, loadingScreen: false, crisp: false, debug: false, global: false, maxFPS: 120, background: "404040", }); const kaplaymap = new KaplayMap(kp, {}); const bean = kp.loadBean(); kp.add([kp.sprite("bean"), kp.pos(kp.center())]);