diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 30cb7bb..e5995ce 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -764,7 +764,7 @@ - + diff --git a/src/static/js/tutorial.js b/src/static/js/tutorial.js index 76229b8..1dc5e38 100644 --- a/src/static/js/tutorial.js +++ b/src/static/js/tutorial.js @@ -374,14 +374,14 @@ const Tutorial = { }).setView([53.545, 9.98], 13); // Tile-Layer (Theme-abhängig) - var isDark = !document.documentElement.getAttribute('data-theme') || document.documentElement.getAttribute('data-theme') !== 'light'; + var isDark = document.documentElement.getAttribute('data-theme') !== 'light'; if (isDark) { - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { + L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', { attribution: '\u00a9 OpenStreetMap, \u00a9 CARTO', maxZoom: 19, }).addTo(this._demoMap); } else { - L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { + L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', { attribution: '\u00a9 OpenStreetMap, \u00a9 CARTO', maxZoom: 19, }).addTo(this._demoMap); @@ -1519,19 +1519,17 @@ const Tutorial = { mapDiv.style.cssText = 'width:100%;height:100%;min-height:400px;'; fsContainer.appendChild(mapDiv); - var isDark = !document.documentElement.getAttribute('data-theme') || document.documentElement.getAttribute('data-theme') !== 'light'; // Start weit herausgezoomt (Europa) this._demoMap = L.map(mapDiv, { zoomControl: true, attributionControl: true, }).setView([51.0, 10.0], 5); - var tileUrl = isDark - ? 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png' - : 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png'; - L.tileLayer(tileUrl, { - attribution: '\u00a9 OpenStreetMap, \u00a9 CARTO', - maxZoom: 19, + // Gleiche Tile-Quelle wie die echte App (deutsche OSM-Kacheln) + L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap', + maxZoom: 18, + noWrap: true, }).addTo(this._demoMap); // Marker (aber noch nicht sichtbar bei Zoom 5) @@ -2013,12 +2011,14 @@ const Tutorial = { this._els.cursor.classList.add('tutorial-cursor-resize'); await this._wait(200); - // Kachel vergrößern (visuell) + // Rein visuelle Vergrößerung per CSS transform (kein width/height!) + // So bleibt GridStack komplett unberührt tile.style.transition = 'none'; tile.style.zIndex = '9002'; - var origW = tile.offsetWidth; - var origH = tile.offsetHeight; + tile.style.transformOrigin = 'top left'; var self = this; + var origW = rect.width; + var origH = rect.height; var start = null; await new Promise(function(resolve) { @@ -2027,12 +2027,11 @@ const Tutorial = { if (!start) start = ts; var progress = Math.min((ts - start) / 1000, 1); var eased = progress < 0.5 ? 4*progress*progress*progress : 1 - Math.pow(-2*progress+2,3)/2; - var dx = expandX * eased; - var dy = expandY * eased; - tile.style.width = (origW + dx) + 'px'; - tile.style.height = (origH + dy) + 'px'; - self._els.cursor.style.left = (startX + dx) + 'px'; - self._els.cursor.style.top = (startY + dy) + 'px'; + var scaleX = 1 + (expandX / origW) * eased; + var scaleY = 1 + (expandY / origH) * eased; + tile.style.transform = 'scale(' + scaleX + ', ' + scaleY + ')'; + self._els.cursor.style.left = (startX + expandX * eased) + 'px'; + self._els.cursor.style.top = (startY + expandY * eased) + 'px'; if (progress < 1) requestAnimationFrame(frame); else resolve(); } requestAnimationFrame(frame); @@ -2047,27 +2046,21 @@ const Tutorial = { if (!start) start = ts; var progress = Math.min((ts - start) / 700, 1); var eased = progress < 0.5 ? 4*progress*progress*progress : 1 - Math.pow(-2*progress+2,3)/2; - var dx = expandX * (1 - eased); - var dy = expandY * (1 - eased); - tile.style.width = (origW + dx) + 'px'; - tile.style.height = (origH + dy) + 'px'; - self._els.cursor.style.left = (startX + dx) + 'px'; - self._els.cursor.style.top = (startY + dy) + 'px'; + var scaleX = 1 + (expandX / origW) * (1 - eased); + var scaleY = 1 + (expandY / origH) * (1 - eased); + tile.style.transform = 'scale(' + scaleX + ', ' + scaleY + ')'; + self._els.cursor.style.left = (startX + expandX * (1 - eased)) + 'px'; + self._els.cursor.style.top = (startY + expandY * (1 - eased)) + 'px'; if (progress < 1) requestAnimationFrame(frame); else resolve(); } requestAnimationFrame(frame); }); - // Aufräumen - exakte Originalgröße wiederherstellen - tile.style.width = origW + 'px'; - tile.style.height = origH + 'px'; + // Aufräumen + tile.style.transform = ''; + tile.style.transformOrigin = ''; tile.style.transition = ''; tile.style.zIndex = ''; - // Nach kurzer Verzögerung CSS-Werte entfernen damit GridStack wieder übernimmt - setTimeout(function() { - tile.style.width = ''; - tile.style.height = ''; - }, 100); this._hideCursor(); await this._wait(200);