Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Kinetic Scrolling (https://www.delphipraxis.net/145560-kinetic-scrolling.html)

Prototypjack 4. Jan 2010 12:17


Kinetic Scrolling
 
Moin,

Ich beschäftige mich (guter Vorsatz :) ) im neuen Jahr ein bisschen mit C# (Compact Framework).
Momentan arbeite ich an einem Proof-Of-Concept, das, wenn alles klappt, folgendes tun soll:
Es zeichnet ein Bild auf der Form (geht bereits ;) ), welches man ziehen kann (das auch), an den oberen und unteren Rändern "klebt" --> schnellt zurück, wenn man es zu weit zieht und loslässt (auch dies) und das sich durch Ziehen beschleunigen lässt (hier liegt das Problem).

Mit "durch Ziehen beschleunigen" meine ich ganz einfach diesen iPhone-way-of-scrolling. Das heißt, ich ziehe das Objekt und lasse es dann los (ohne zulange auf einem Punkt zu verweilen), daraufhin bewegt sich das Objekt selbstständig weiter (und verringert mit der Zeit selbst seine Geschwindigkeit).

Ich habe bereits mehrere Gedanken, wie ich das realisieren könnte, aber alle stellen sich nach und nach als suboptimal heraus.

Deshalb meine Frage: Wie gehe ich das am besten (elegantesten) an? Ich brauche nur ein paar Ideen ;)

Danke & Grüße,
Max

himitsu 4. Jan 2010 12:41

Re: Kinetic Scrolling
 
- du mußt das Loslassen und die Zeit, wie lange es auf einem Punkt blieb messen
- dazu dann auch noch die Geschwindigkeit des Ziehens

> läßt sich über OnMouseMove und OnMouseUp und die Speicherung der Zeitpunkte, sowie die Abstände der letzten MouseMove-Ereignisse bestimmen

- tja, und nun das Kinetische
> hierfür einen Timer laufen lassen, welcher bei erfolgreicher Aktion in OnMouseUp gestartet wird
> nun wird einfach nur noch die schon vorher einmal errechnete Geschwindigkeit in Pixel umgerechnet (passend zum Timerinterval)
> das Objekt entsprechend verschoben und die Geschwindigkeit verringert
> tja und das nun so lange, bis die Geschwindigkeit 0 ist

hathor 4. Jan 2010 12:54

Re: Kinetic Scrolling
 
Muss die Entfernung zum Bildschirmrand auch in die Rechnung mit einfliessen? Je näher, desto langsam?

Prototypjack 4. Jan 2010 17:27

Re: Kinetic Scrolling
 
Zitat:

Zitat von himitsu
- du mußt das Loslassen und die Zeit, wie lange es auf einem Punkt blieb messen
- dazu dann auch noch die Geschwindigkeit des Ziehen

Den selben Ansatz hatte ich auch schon, aber genau dort liegt mein Problem. Wie ermittle ich die Geschwindigkeit zuverlässig? Ich weiß zum einen nicht, wann der User das MouseUp Ereignis auslöst, noch dürfte es etwas bringen, die Geschwindigkeit innerhalb eines Punktes zu messen, da die Größen in einem einzelnen Punkt nicht aussagekräftig sein dürften.

Zitat:

Zitat von hathor
Muss die Entfernung zum Bildschirmrand auch in die Rechnung mit einfliessen? Je näher, desto langsam?

Ich bin mir nicht ganz sicher, ob ich dich richtig verstehe, ich denke aber: Nein. Die Geschwindigkeit wird nur durch den "Initialschub" und das natürliche Ausbremsen beeinflusst (außer man stößt eine Kante, dann wird stärker gebremst, weil ja so ein "Gummibandeffekt" entstehen soll).

Grüße,
Max

himitsu 4. Jan 2010 17:43

Re: Kinetic Scrolling
 
Zitat:

Zitat von Prototypjack
Wie ermittle ich die Geschwindigkeit zuverlässig?

eventuell mehrere Punkte (der letzten x Milliseunden) merken und Durchschnitt/Tendenz errechnen

Prototypjack 5. Jan 2010 12:51

Re: Kinetic Scrolling
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von Prototypjack
Wie ermittle ich die Geschwindigkeit zuverlässig?

eventuell mehrere Punkte (der letzten x Milliseunden) merken und Durchschnitt/Tendenz errechnen

Moin,

Ich habe jetzt doch den einfachsten Ansatz gewählt, Hintergrund: Wenn ich nur die letzten X-Pixel beachten will, müsste ich ständig einen Timer mitlaufen lassen und die Zielgruppe (mobile Geräte) hat doch noch sehr begrenzte Ressourcen, da darf ich nichts verschwenden.

Mein Ansatz funktioniert nun so (für die anderen :) - evtl. wird das Programm auch OpenSource):

Ich merke mir im MouseDown-Ereignis die momentane Position des Mauszeigers und speichere diese in zwei Variablen (LastPosition und Currentposition). Dazu setze ich noch ein Flag: MouseIsDown.
Zusätzlich merke ich mir in einer weiteren Variable den momentanen TickCount.

Im MouseMove-Ereignis setze ich dann CurrentPosition neu und zeichne das momentane Bild (welches sich durch den Move ja verändert hat).

Im MouseUp-Ereignis setze ich MouseIsDown (klar) wieder auf false, setze CurrentPosition erneut und errechne mir die Geschwindigkeit der Bewegung: Velocity = (double)(CurrentPosition.Y - LastPosition.Y) / Time; Time ist dabei die Differenz zwischen MouseDown-TickCount und MouseUp-TickCount.

Zusätzlich habe ich noch einen Timer, welcher im MouseUp-Ereignis aktiviert wird und im MouseDown-Ereignis deaktiviert wird (ein Tippen auf den Bildschirm soll die Bewegung anhalten).
Dann kann ich ganz einfach den Weg berechnen, in dem ich die bekannte Formel s = v * t benutze (erneut). v ist die bekannte Geschwindigkeit und t das Timer Intervall.
Der Timer selbst zeichnet das Bild auch bei jedem Aufruf erneut und deaktiviert sich selbst, sobald Velocity unter einen bestimmten Wert fällt.

So, ich hoffe das war verständlich für die Nachwelt ;)

Grüße,
Max


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz