From c3f66d966c4613bb7531ec47b6344bfac8578b23 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sat, 6 Apr 2024 13:57:40 +0300 Subject: [PATCH] Determinitstic zooming --- client/index.js | 8 +++++--- client/wasm/lod.c | 2 -- client/webgl_draw.js | 5 +++-- client/webgl_listeners.js | 33 +++++++++++++++++---------------- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/client/index.js b/client/index.js index 384b07c..c877b5e 100644 --- a/client/index.js +++ b/client/index.js @@ -13,8 +13,9 @@ const config = { second_finger_timeout: 500, buffer_first_touchmoves: 5, debug_print: false, - min_zoom: 0.00001, - max_zoom: 10, + zoom_delta: 0.15, + min_zoom_level: -75, + max_zoom_level: 20, initial_offline_timeout: 1000, default_color: 0x00, default_width: 8, @@ -26,7 +27,7 @@ const config = { dynamic_stroke_texture_size: 128, // means no more than 128^2 = 16K dynamic strokes at once bvh_fullnode_depth: 5, benchmark: { - zoom: 0.00001, + zoom_level: -75, offset: { x: 425, y: -1195 }, frames: 500, }, @@ -137,6 +138,7 @@ async function main() { 'canvas': { 'offset': { 'x': 0, 'y': 0 }, + 'zoom_level': 0, 'zoom': 1.0, }, diff --git a/client/wasm/lod.c b/client/wasm/lod.c index fd5508f..0e6ce43 100644 --- a/client/wasm/lod.c +++ b/client/wasm/lod.c @@ -1,5 +1,3 @@ -// clang -Oz --target=wasm32 -nostdlib -Wl,--export-all,--no-entry -msimd128 lod.c -o lod.wasm - #include extern char __heap_base; diff --git a/client/webgl_draw.js b/client/webgl_draw.js index 28247cc..78e79a4 100644 --- a/client/webgl_draw.js +++ b/client/webgl_draw.js @@ -195,8 +195,9 @@ async function draw(state, context) { document.getElementById('debug-stats').innerHTML = ` Segments onscreen: ${segment_count} - Canvas offset: (${state.canvas.offset.x}, ${state.canvas.offset.y}) - Canvas zoom: ${Math.round(state.canvas.zoom * 100000) / 100000}`; + Canvas offset: (${Math.round(state.canvas.offset.x * 100) / 100}, ${Math.round(state.canvas.offset.y * 100) / 100}) + Canvas zoom level: ${state.canvas.zoom_level} + Canvas zoom: ${Math.round(state.canvas.zoom * 100) / 100}`; if (context.gpu_timer_ext) { gl.endQuery(context.gpu_timer_ext.TIME_ELAPSED_EXT); diff --git a/client/webgl_listeners.js b/client/webgl_listeners.js index 6848d4d..5f1247a 100644 --- a/client/webgl_listeners.js +++ b/client/webgl_listeners.js @@ -58,10 +58,13 @@ function debug_panel_init(state, context) { }); document.getElementById('debug-begin-benchmark').addEventListener('click', (e) => { - state.canvas.zoom = config.benchmark.zoom; + state.canvas.zoom_level = config.benchmark.zoom_level; state.canvas.offset.x = config.benchmark.offset.x; state.canvas.offset.y = config.benchmark.offset.y; + const dz = (state.canvas.zoom_level > 0 ? config.zoom_delta : -config.zoom_delta); + state.canvas.zoom = Math.pow(1.0 + dz, Math.abs(state.canvas.zoom_level)) + state.debug.benchmark_mode = true; const origin_x = state.canvas.offset.x; @@ -328,31 +331,29 @@ function wheel(e, state, context) { const screenp = {'x': window.devicePixelRatio * e.clientX, 'y': window.devicePixelRatio * e.clientY}; const canvasp = screen_to_canvas(state, screenp); - const dz = (e.deltaY < 0 ? 0.1 : -0.1); - const old_zoom = state.canvas.zoom; - - state.canvas.zoom *= (1.0 + dz); + const zooming_in = e.deltaY < 0; + const zoom_level = zooming_in ? state.canvas.zoom_level + 1 : state.canvas.zoom_level - 1; - if (state.canvas.zoom > config.max_zoom) { - state.canvas.zoom = old_zoom; + if (zoom_level < config.min_zoom_level || zoom_level > config.max_zoom_level) { return; } - if (state.canvas.zoom < config.min_zoom) { - state.canvas.zoom = old_zoom; - return; - } + state.canvas.zoom_level = zoom_level; + + const dz = (zoom_level > 0 ? config.zoom_delta : -config.zoom_delta); + const old_zoom = state.canvas.zoom; + const new_zoom = Math.pow(1.0 + dz, Math.abs(zoom_level)) // If we are moving our canvas, we don't need to follow anymore if (state.following_player !== null) { toggle_follow_player(state, state.following_player); } - - const zoom_offset_x = Math.round((dz * old_zoom) * canvasp.x); - const zoom_offset_y = Math.round((dz * old_zoom) * canvasp.y); - state.canvas.offset.x -= zoom_offset_x; - state.canvas.offset.y -= zoom_offset_y; + // https://gist.github.com/aolo2/a373363419bd5a9283977ab9f8841f78 + state.canvas.offset.x = screenp.x - (screenp.x - state.canvas.offset.x) * new_zoom / old_zoom; + state.canvas.offset.y = screenp.y - (screenp.y - state.canvas.offset.y) * new_zoom / old_zoom; + + state.canvas.zoom = new_zoom; fire_event(state, movecanvas_event(state));