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);