Mit Smooth Zoom meine ich eine Transition von ein paar hundert Millisekunden. die zoom steps ändern sich nicht, soll nur optisch eine "transition" sein. das überall dort wo man zoomen kann (was mir auf die schnelle einfällt, scene view, graph, jegliche art von previews, pixel art, vector art)
Mit Smooth Zoom meine ich eine Transition von ein paar hundert Millisekunden. die zoom steps ändern sich nicht, soll nur optisch eine "transition" sein. das überall dort wo man zoomen kann (was mir auf die schnelle einfällt, scene view, graph, jegliche art von previews, pixel art, vector art)
admin
added this to the Development project 2026-10-03 19:39:44 +02:00
admin
moved this to Next in Development on 2026-10-03 19:39:50 +02:00
Gemessen am Code: Mit dem Mausrad gezoomt wird an sieben Stellen, in vier Familien:
Familie
Tabs
FreeViewport
Scene, Container, Vorschau im Animation-Tab
SheetCanvas
Texture, Curve, Pixel Art, Vector Art
Graph (GraphCanvas, panAndZoom)
Graph-Editor, Board im Tile-Tab, Plugin-Board
TimelineCanvas
Timeline im Animation-Tab (nur waagrecht)
Die Shader-Vorschau zoomt nicht mit dem Rad, sie passt sich nur an die Größe an. Der Game-Tab zoomt über das Menü, das Rad gehört dort dem Spiel (On mouse wheel).
Ohne vierfachen Code
Alle vier rechnen gleich: Bildschirmpunkt = Weltpunkt * Faktor + Verschiebung. Nur heißen die Felder überall anders (pan/zoom, panX/panY/zoom, Mittelpunkt + Zoom, panX/cellWidth).
Eine reine FunktiontweenView(from, to, t) in src/ui/. Sie blendet zwischen zwei Ansichten über und hält dabei den Punkt fest, der in beiden an derselben Stelle liegt. Bei einem Radschritt ist das genau der Punkt unter der Maus. Der Faktor läuft logarithmisch, damit jeder Schritt gleich schnell wirkt.
Ein kleiner TreiberZoomTransition: Er hängt sich für die Dauer des Übergangs an den Pixi-Ticker und meldet je Frame die Zwischenansicht. Danach hängt er sich wieder ab.
Je Familie ein Adapter, der ihre Felder in die gemeinsame Form bringt und zurück. Die vier onWheel-Stellen rufen dann statt this.view = …; redraw() den Treiber.
Regeln
Die Stufen ändern sich nicht. Ziel eines Radschritts bleibt genau die heutige Ansicht, inklusive Ganzzahl-Pan im Pixel-Art-Tab und der Gerätepixel-Stufen in Scene und Tile-Board.
Rad während des Übergangs: Der nächste Schritt rechnet vom Ziel aus, nicht von der Zwischenansicht. Der Übergang startet neu, von der Ansicht, die gerade zu sehen ist. Drei schnelle Rastungen ergeben also genau drei Stufen.
Klicks und Ziehen treffen immer das, was gerade zu sehen ist. Ein Pan, ein Fit, ein Dokumentwechsel und ein Resize brechen den Übergang ab und springen aufs Ziel.
settle() im Harness wartet nur zwei Frames. Sechs e2e-Module (06, 13, 31, 38, 39, 44) lesen Zoom oder Pixel kurz nach dem Rad und würden mitten im Übergang messen. Deshalb:
Der Harness schaltet den Übergang beim Laden ab (Testschalter am __gm, Dauer 0). Alle bestehenden Module bleiben, wie sie sind.
Unit-Tests für tweenView (Anfang, Ende, fester Punkt unter der Maus, Neustart) und für die Adapter.
Ein e2e-Check schaltet den Übergang ein und misst im Scene-Tab mitten drin: Der Zoom liegt zwischen den Stufen und der Weltpunkt unter der Maus bleibt liegen.
Fragen, jeweils mit meinem Vorschlag
Dauer und Kurve: Ich schlage 200 ms mit ease-out vor. Länger fühlt sich beim schnellen Drehen träge an.
Nur das Rad oder auch Fit? Ich schlage nur das Rad vor. Fit beim Öffnen eines Dokuments muss ohnehin springen, und der Fit-Knopf wäre ein eigener Wunsch.
Timeline: Mit dabei, sie zoomt ja auch mit dem Rad. Wenn du nur Bilder meinst, lasse ich sie weg.
Ein Schalter in den Einstellungen zum Abschalten: Ich schlage keinen vor.
Ein Risiko: Scene und Container zeichnen beim Zoomen heute alles neu (die Linienstärken hängen an der Skala). Während des Übergangs passiert das jeden Frame, also etwa zwölfmal. Bei großen Szenen messe ich das, bevor ich es so lasse.
## Plan
Gemessen am Code: Mit dem Mausrad gezoomt wird an **sieben Stellen**, in vier Familien:
| Familie | Tabs |
|---|---|
| `FreeViewport` | Scene, Container, Vorschau im Animation-Tab |
| `SheetCanvas` | Texture, Curve, Pixel Art, Vector Art |
| Graph (`GraphCanvas`, `panAndZoom`) | Graph-Editor, Board im Tile-Tab, Plugin-Board |
| `TimelineCanvas` | Timeline im Animation-Tab (nur waagrecht) |
Die Shader-Vorschau zoomt nicht mit dem Rad, sie passt sich nur an die Größe an. Der Game-Tab zoomt über das Menü, das Rad gehört dort dem Spiel (`On mouse wheel`).
### Ohne vierfachen Code
Alle vier rechnen gleich: Bildschirmpunkt = Weltpunkt * Faktor + Verschiebung. Nur heißen die Felder überall anders (`pan`/`zoom`, `panX`/`panY`/`zoom`, Mittelpunkt + Zoom, `panX`/`cellWidth`).
1. **Eine reine Funktion** `tweenView(from, to, t)` in `src/ui/`. Sie blendet zwischen zwei Ansichten über und hält dabei den Punkt fest, der in beiden an derselben Stelle liegt. Bei einem Radschritt ist das genau der Punkt unter der Maus. Der Faktor läuft logarithmisch, damit jeder Schritt gleich schnell wirkt.
2. **Ein kleiner Treiber** `ZoomTransition`: Er hängt sich für die Dauer des Übergangs an den Pixi-Ticker und meldet je Frame die Zwischenansicht. Danach hängt er sich wieder ab.
3. **Je Familie ein Adapter**, der ihre Felder in die gemeinsame Form bringt und zurück. Die vier `onWheel`-Stellen rufen dann statt `this.view = …; redraw()` den Treiber.
### Regeln
- **Die Stufen ändern sich nicht.** Ziel eines Radschritts bleibt genau die heutige Ansicht, inklusive Ganzzahl-Pan im Pixel-Art-Tab und der Gerätepixel-Stufen in Scene und Tile-Board.
- **Rad während des Übergangs:** Der nächste Schritt rechnet vom *Ziel* aus, nicht von der Zwischenansicht. Der Übergang startet neu, von der Ansicht, die gerade zu sehen ist. Drei schnelle Rastungen ergeben also genau drei Stufen.
- **Klicks und Ziehen** treffen immer das, was gerade zu sehen ist. Ein Pan, ein Fit, ein Dokumentwechsel und ein Resize brechen den Übergang ab und springen aufs Ziel.
- **Gespeichert** (`saveView`, #171) wird immer das Ziel.
### Tests
`settle()` im Harness wartet nur zwei Frames. Sechs e2e-Module (06, 13, 31, 38, 39, 44) lesen Zoom oder Pixel kurz nach dem Rad und würden mitten im Übergang messen. Deshalb:
- Der Harness schaltet den Übergang beim Laden ab (Testschalter am `__gm`, Dauer 0). Alle bestehenden Module bleiben, wie sie sind.
- Unit-Tests für `tweenView` (Anfang, Ende, fester Punkt unter der Maus, Neustart) und für die Adapter.
- Ein e2e-Check schaltet den Übergang ein und misst im Scene-Tab mitten drin: Der Zoom liegt zwischen den Stufen und der Weltpunkt unter der Maus bleibt liegen.
### Fragen, jeweils mit meinem Vorschlag
1. **Dauer und Kurve:** Ich schlage **200 ms mit ease-out** vor. Länger fühlt sich beim schnellen Drehen träge an.
2. **Nur das Rad oder auch Fit?** Ich schlage **nur das Rad** vor. Fit beim Öffnen eines Dokuments muss ohnehin springen, und der Fit-Knopf wäre ein eigener Wunsch.
3. **Timeline:** Mit dabei, sie zoomt ja auch mit dem Rad. Wenn du nur Bilder meinst, lasse ich sie weg.
4. **Ein Schalter in den Einstellungen** zum Abschalten: Ich schlage **keinen** vor.
Ein Risiko: Scene und Container zeichnen beim Zoomen heute alles neu (die Linienstärken hängen an der Skala). Während des Übergangs passiert das jeden Frame, also etwa zwölfmal. Bei großen Szenen messe ich das, bevor ich es so lasse.
eigene menü punkt "General settings...", dort millisekunden einstellbar. wenn 0ms dann so wie jetzt (keine transition), default 200ms
nein, fit auch gleich mitnehmen
ja kannst mitnehmen
siehe 1.
1. eigene menü punkt "General settings...", dort millisekunden einstellbar. wenn 0ms dann so wie jetzt (keine transition), default 200ms
2. nein, fit auch gleich mitnehmen
3. ja kannst mitnehmen
4. siehe 1.
Umgesetzt in cf6043a (Wiki: Concepts, Keyboard, Architecture, Development)
Mausrad und Fit zeigen den Zoom jetzt als kurzen Übergang, überall dort, wo der Editor zoomt: Scene, Container, Texture, Curve, Pixel Art, Vector Art, Vorschau und Timeline im Animation-Tab, Graph-Editor, das Board im Tile-Tab und das Plugin-Board.
Wie gewünscht
Eigener Menüpunkt General settings… mit der Dauer in Millisekunden, Standard 200, 0 springt wie bisher sofort. Die Einstellung liegt im Browser (wie die Panelgrößen), nicht im Projekt, und ist kein Undo-Schritt.
Fit ist dabei. Ein Dokument, das sich öffnet, kommt weiter sofort gerahmt hoch.
Die Timeline ist dabei (nur das Zoomen, Shift+Rad scrollt weiter sofort).
Die Zoomstufen sind unverändert. Drei schnelle Rastungen ergeben genau drei Stufen, und der Punkt unter der Maus bleibt den ganzen Weg darunter.
Aufbau
src/editor/viewTween.ts: tweenView (der Weg zwischen zwei Ansichten, reine Funktion) und ViewTween (fährt ihn am Ticker). Jede Ansicht gibt ihm nur Lesen, Schreiben und Zeichnen ihrer eigenen Felder und legt ihren bisherigen Rad- und Fit-Code in change().
Ein Pan, ein Dokumentwechsel oder eine neue Größe beenden den Übergang auf der Zielstufe. Gespeichert wird immer das Ziel.
Die Zoom-Anzeige im Pixel-Art-Tab nennt die Stufe, auf die der Übergang zuläuft.
Gemessen
Scene-Tab bei 200 ms auf melektaus-atx. Jeder Frame des Übergangs ist eine volle Neuzeichnung:
Sprites
eine Neuzeichnung
Frames im Übergang
mittlerer Frame
500
6,7 ms
16
18 ms
1000
13,0 ms
9
27 ms
2000
32,2 ms
5
58 ms
Bis etwa 1000 Objekte läuft es flüssig, bei 2000 ruckelt es, ist aber trotzdem nach der eingestellten Zeit da. Die anderen Tabs habe ich nicht gemessen.
Tests
Gate: 234 Dateien, 3563 Tests (+15 in tests/editor/view-tween.test.ts).
e2e 46i: Bei 1000 ms liegt der Zoom einen Frame nach der Rastung bei 1,033 (zwischen 1 und 2), der Weltpunkt unter der Maus bleibt bei (134, −40). Am Ende steht genau die Ansicht, die ein Sprung mit 0 ms ergibt.
Der Harness stellt beim Laden 0 ms ein, damit die bestehenden Module die Stufe lesen und nicht den Weg.
## Umgesetzt in cf6043a (Wiki: *Concepts*, *Keyboard*, *Architecture*, *Development*)
Mausrad und **Fit** zeigen den Zoom jetzt als kurzen Übergang, überall dort, wo der Editor zoomt: Scene, Container, Texture, Curve, Pixel Art, Vector Art, Vorschau und Timeline im Animation-Tab, Graph-Editor, das Board im Tile-Tab und das Plugin-Board.
### Wie gewünscht
- **Eigener Menüpunkt *General settings…*** mit der Dauer in Millisekunden, Standard 200, 0 springt wie bisher sofort. Die Einstellung liegt im Browser (wie die Panelgrößen), nicht im Projekt, und ist kein Undo-Schritt.
- **Fit ist dabei.** Ein Dokument, das sich öffnet, kommt weiter sofort gerahmt hoch.
- **Die Timeline ist dabei** (nur das Zoomen, `Shift`+Rad scrollt weiter sofort).
- **Die Zoomstufen sind unverändert.** Drei schnelle Rastungen ergeben genau drei Stufen, und der Punkt unter der Maus bleibt den ganzen Weg darunter.
### Aufbau
- `src/editor/viewTween.ts`: `tweenView` (der Weg zwischen zwei Ansichten, reine Funktion) und `ViewTween` (fährt ihn am Ticker). Jede Ansicht gibt ihm nur Lesen, Schreiben und Zeichnen ihrer eigenen Felder und legt ihren bisherigen Rad- und Fit-Code in `change()`.
- Ein Pan, ein Dokumentwechsel oder eine neue Größe beenden den Übergang auf der Zielstufe. Gespeichert wird immer das Ziel.
- Die Zoom-Anzeige im Pixel-Art-Tab nennt die Stufe, auf die der Übergang zuläuft.
### Gemessen
Scene-Tab bei 200 ms auf `melektaus-atx`. Jeder Frame des Übergangs ist eine volle Neuzeichnung:
| Sprites | eine Neuzeichnung | Frames im Übergang | mittlerer Frame |
|---|---|---|---|
| 500 | 6,7 ms | 16 | 18 ms |
| 1000 | 13,0 ms | 9 | 27 ms |
| 2000 | 32,2 ms | 5 | 58 ms |
Bis etwa 1000 Objekte läuft es flüssig, bei 2000 ruckelt es, ist aber trotzdem nach der eingestellten Zeit da. Die anderen Tabs habe ich nicht gemessen.
### Tests
- Gate: 234 Dateien, 3563 Tests (+15 in `tests/editor/view-tween.test.ts`).
- e2e 46i: Bei 1000 ms liegt der Zoom einen Frame nach der Rastung bei 1,033 (zwischen 1 und 2), der Weltpunkt unter der Maus bleibt bei (134, −40). Am Ende steht genau die Ansicht, die ein Sprung mit 0 ms ergibt.
- Der Harness stellt beim Laden 0 ms ein, damit die bestehenden Module die Stufe lesen und nicht den Weg.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Mit Smooth Zoom meine ich eine Transition von ein paar hundert Millisekunden. die zoom steps ändern sich nicht, soll nur optisch eine "transition" sein. das überall dort wo man zoomen kann (was mir auf die schnelle einfällt, scene view, graph, jegliche art von previews, pixel art, vector art)
Plan
Gemessen am Code: Mit dem Mausrad gezoomt wird an sieben Stellen, in vier Familien:
FreeViewportSheetCanvasGraphCanvas,panAndZoom)TimelineCanvasDie Shader-Vorschau zoomt nicht mit dem Rad, sie passt sich nur an die Größe an. Der Game-Tab zoomt über das Menü, das Rad gehört dort dem Spiel (
On mouse wheel).Ohne vierfachen Code
Alle vier rechnen gleich: Bildschirmpunkt = Weltpunkt * Faktor + Verschiebung. Nur heißen die Felder überall anders (
pan/zoom,panX/panY/zoom, Mittelpunkt + Zoom,panX/cellWidth).tweenView(from, to, t)insrc/ui/. Sie blendet zwischen zwei Ansichten über und hält dabei den Punkt fest, der in beiden an derselben Stelle liegt. Bei einem Radschritt ist das genau der Punkt unter der Maus. Der Faktor läuft logarithmisch, damit jeder Schritt gleich schnell wirkt.ZoomTransition: Er hängt sich für die Dauer des Übergangs an den Pixi-Ticker und meldet je Frame die Zwischenansicht. Danach hängt er sich wieder ab.onWheel-Stellen rufen dann stattthis.view = …; redraw()den Treiber.Regeln
saveView, #171) wird immer das Ziel.Tests
settle()im Harness wartet nur zwei Frames. Sechs e2e-Module (06, 13, 31, 38, 39, 44) lesen Zoom oder Pixel kurz nach dem Rad und würden mitten im Übergang messen. Deshalb:__gm, Dauer 0). Alle bestehenden Module bleiben, wie sie sind.tweenView(Anfang, Ende, fester Punkt unter der Maus, Neustart) und für die Adapter.Fragen, jeweils mit meinem Vorschlag
Ein Risiko: Scene und Container zeichnen beim Zoomen heute alles neu (die Linienstärken hängen an der Skala). Während des Übergangs passiert das jeden Frame, also etwa zwölfmal. Bei großen Szenen messe ich das, bevor ich es so lasse.
Umgesetzt in
cf6043a(Wiki: Concepts, Keyboard, Architecture, Development)Mausrad und Fit zeigen den Zoom jetzt als kurzen Übergang, überall dort, wo der Editor zoomt: Scene, Container, Texture, Curve, Pixel Art, Vector Art, Vorschau und Timeline im Animation-Tab, Graph-Editor, das Board im Tile-Tab und das Plugin-Board.
Wie gewünscht
Shift+Rad scrollt weiter sofort).Aufbau
src/editor/viewTween.ts:tweenView(der Weg zwischen zwei Ansichten, reine Funktion) undViewTween(fährt ihn am Ticker). Jede Ansicht gibt ihm nur Lesen, Schreiben und Zeichnen ihrer eigenen Felder und legt ihren bisherigen Rad- und Fit-Code inchange().Gemessen
Scene-Tab bei 200 ms auf
melektaus-atx. Jeder Frame des Übergangs ist eine volle Neuzeichnung:Bis etwa 1000 Objekte läuft es flüssig, bei 2000 ruckelt es, ist aber trotzdem nach der eingestellten Zeit da. Die anderen Tabs habe ich nicht gemessen.
Tests
tests/editor/view-tween.test.ts).