From 1a50fe14e92472a727735060669fde1030fcc7ec Mon Sep 17 00:00:00 2001 From: xdan Date: Tue, 19 Mar 2024 19:25:05 +0300 Subject: [PATCH] Added debounce mode --- example/common.css | 13 ++++++ example/common.js | 106 +++++++++++++++++++++++++++++++++++++++++++ example/vanilla.html | 9 ++-- 3 files changed, 124 insertions(+), 4 deletions(-) diff --git a/example/common.css b/example/common.css index 9237937..7e57325 100644 --- a/example/common.css +++ b/example/common.css @@ -24,6 +24,7 @@ body, z-index: 1112; top: 10px; left: 10px; + display: flex; } .version { @@ -78,3 +79,15 @@ body, color: #fff; } + +.debounce-board { + top: 10px; + display: flex; + align-items: center; + border-radius: 12px; + background-color: #EEFD7D; + min-width: 80px; + justify-content: center; + height: 36px; + margin-right: 10px; +} diff --git a/example/common.js b/example/common.js index 16d959c..37eaea6 100644 --- a/example/common.js +++ b/example/common.js @@ -27,6 +27,8 @@ const MODE = ['tile-clusterer', 'tile', 'bbox'].includes(SEARCH_PARAMS.get('mode const SHOW_MODE_SWITCHER = SEARCH_PARAMS.get('hideModeSwitcher') !== 'true'; const SHOW_CELLS = SEARCH_PARAMS.get('showCells') === 'true'; const DEBOUNCE = SEARCH_PARAMS.get('debounce') === 'true'; +const DELAY = SEARCH_PARAMS.get('delay') ? +SEARCH_PARAMS.get('delay') : 1000; +const SHOW_DELAY = SEARCH_PARAMS.get('showDelay') === 'true'; const markerElement = document.createElement('div'); markerElement.classList.add('circle'); @@ -173,3 +175,107 @@ function showBounds(bounds) { map.removeChild(entity); }, 1000); } + +function debounce(func, wait) { + let timeout; + return () => { + const args = arguments; + const later = function () { + timeout = null; + func.apply(null, args); + }; + const callNow = !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(null, args); + }; +} + +function throttle(func, ms) { + let isThrottled = false; + let savedArgs = null; + + function wrapper() { + if (isThrottled) { + savedArgs = arguments; + return; + } + + func.apply(null, arguments); + + isThrottled = true; + + setTimeout(function () { + isThrottled = false; + if (savedArgs) { + wrapper.apply(null, savedArgs); + savedArgs = null; + } + }, ms); + } + + return wrapper; +} + +function delayWrapper(wrapper, fn, delay, getBox) { + const setBoxTime = (v) => { + const box = getBox(); + if (!box) { + return; + } + let sec = (v / 1000); + if (1 - sec <= 0.005) { + sec = 1; + } + box.textContent = `${sec.toFixed(3)}\u00A0sec`; + }; + + let startTime = performance.now(); + let startDelay = delay; + setBoxTime(startDelay); + let rafStarted = false; + + function loop() { + rafStarted = false; + const restTime = startDelay - (performance.now() - startTime); + setBoxTime(restTime); + if (restTime > 0) { + rafStarted = true; + requestAnimationFrame(loop); + } else { + setBoxTime(0); + } + } + + requestAnimationFrame(loop); + + const startTimer = () => { + startTime = performance.now(); + startDelay = delay; + + if (!rafStarted) { + rafStarted = true; + requestAnimationFrame(loop); + } + }; + + const delayed = wrapper( + (...args) => { + try { + fn(...args); + } finally { + if (!DEBOUNCE) { + startTimer(); + } + } + }, + delay + ); + + return (...args) => { + delayed(...args); + if (DEBOUNCE) { + startTimer(); + } + }; +} diff --git a/example/vanilla.html b/example/vanilla.html index f7be7df..7b0ccab 100644 --- a/example/vanilla.html +++ b/example/vanilla.html @@ -14,7 +14,6 @@ -