Skip to content

Commit 5d2cc5b

Browse files
committed
Cleanup: use pointer events instead of my older Draggable.v2 library
Draggable.v2 is a wrapper around mouse and touch events to hide their differences. Pointer Events, widely supported in browsers as of 2021, is a simpler way to handle mouse and touch events.
1 parent e5d714f commit 5d2cc5b

File tree

4 files changed

+59
-145
lines changed

4 files changed

+59
-145
lines changed

README.org

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ It's a continuation of ideas I developed for [[https://github.com/amitp/mapgen2/
5252

5353
There's plenty more that could be done to make it even faster and prettier. There are plenty of features that could be added, such as [[https://www.redblobgames.com/x/1723-procedural-river-growing/#draw][drawing your own rivers]], [[https://www.redblobgames.com/x/1843-planet-generation/][sphere output]], [[https://www.redblobgames.com/x/1736-resource-placement/][natural resources]], towns, forests, names, roads, and nations, but I'm leaving those for a future project.
5454

55+
* Code
56+
57+
The entry point is [[mapgen4.js]]. The main data structures are from my dual-mesh library. The map generation algorithms are in [[map.js]]. The input painting is in [[painting.js]]. The output rendering is in [[render.js]]. Calculations are in [[worker.js]]. Some of the calculations are shared between the worker and renderer, and those are in [[geometry.js]].
58+
5559
* License
5660

5761
Mapgen4 and helper libraries I wrote (dual-mesh, prng) are licensed under Apache v2. You can use this code in your own project, including commercial projects.

draggable.v2.js

Lines changed: 0 additions & 123 deletions
This file was deleted.

embed.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@
9292

9393
<div id="map"><canvas id="mapgen4" width="2048" height="2048"/></div>
9494
</div>
95-
<script defer="defer" src="draggable.v2.js"></script>
9695
<script defer="defer" src="build/_bundle.js"></script>
9796
</div>
9897

painting.js

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
*/
88
'use strict';
99

10-
/* global Draggable */
11-
1210
/*
1311
* The painting interface uses a square array of elevations. As you
1412
* drag the mouse it will paint filled circles into the elevation map,
@@ -198,42 +196,78 @@ for (let control of controls) {
198196
displayCurrentTool();
199197

200198

201-
const output = document.getElementById('mapgen4');
202-
new Draggable({
203-
// TODO: replace with pointer events, now that they're widely supported
204-
el: output,
205-
start(event) {
206-
this.timestamp = Date.now();
199+
function setUpPaintEventHandling() {
200+
const el = document.getElementById('mapgen4');
201+
let dragging = false;
202+
let timestamp = 0;
203+
204+
/**
205+
* @param {PointerEvent} event
206+
*/
207+
function start(event) {
208+
if (event.button !== 0) return; // left button only
209+
el.setPointerCapture(event.pointerId);
210+
211+
dragging = true;
212+
timestamp = Date.now();
207213
currentStroke.time.fill(0);
208214
currentStroke.strength.fill(0);
209215
currentStroke.previousElevation.set(heightMap.elevation);
210-
this.drag(event);
211-
},
212-
drag(event) {
216+
move(event);
217+
}
218+
219+
function end(_event) {
220+
dragging = false;
221+
}
222+
223+
/**
224+
* @param {PointerEvent} event
225+
*/
226+
function move(event) {
227+
if (!dragging) return;
228+
213229
const nowMs = Date.now();
214-
let coords = [event.x / output.clientWidth,
215-
event.y / output.clientHeight];
230+
const bounds = el.getBoundingClientRect();
231+
let coords = [
232+
(event.x - bounds.left) / bounds.width,
233+
(event.y - bounds.top) / bounds.height,
234+
];
216235
coords = exported.screenToWorldCoords(coords);
217236
let brushSize = SIZES[currentSize];
218-
if (event.touch && event.touch.force > 0) {
219-
// Apple Stylus
220-
let radius = Math.sqrt(event.touch.force);
237+
if (event.pointerType === 'pen' && event.pressure !== 0.5) {
238+
// Pointer Event spec says 0.5 sent when pen does not
239+
// support pressure; I primarily added this for Apple
240+
// Pencil but haven't tested on others. I want pressure
241+
// 0.25 to correspond to "regular" pressure for the given
242+
// brush size, so radius should be 1.0. I am *not*
243+
// currently supporting Macbook pressure-sensitive
244+
// touchpads, which don't show up under Pointer Events.
245+
// https://developer.mozilla.org/en-US/docs/Web/API/Force_Touch_events
246+
let radius = 2 * Math.sqrt(event.pressure);
221247
brushSize = {
222248
key: brushSize.key,
223249
innerRadius: Math.max(1, brushSize.innerRadius * radius),
224250
outerRadius: Math.max(2, brushSize.outerRadius * radius),
225251
rate: brushSize.rate,
226252
};
227253
}
228-
if (event.raw && event.raw.shiftKey) {
254+
if (event.shiftKey) {
229255
// Hold down shift to paint slowly
230256
brushSize = {...brushSize, rate: brushSize.rate/4};
231257
}
232-
heightMap.paintAt(TOOLS[currentTool], coords[0], coords[1], brushSize, nowMs - this.timestamp);
233-
this.timestamp = nowMs;
258+
heightMap.paintAt(TOOLS[currentTool], coords[0], coords[1],
259+
brushSize, nowMs - timestamp);
260+
timestamp = nowMs;
234261
exported.onUpdate();
235-
},
236-
});
262+
}
263+
264+
el.addEventListener('pointerdown', start);
265+
el.addEventListener('pointerup', end);
266+
el.addEventListener('pointercancel', end);
267+
el.addEventListener('pointermove', move)
268+
el.addEventListener('touchstart', (e) => e.preventDefault()); // prevent scroll
269+
}
270+
setUpPaintEventHandling();
237271

238272

239273

0 commit comments

Comments
 (0)