Wir beginnen zunächst mit den nötigen grafischen Komponenten:
- Hintergrund für den Rollbalken
- Anfasser (Slider)
- Pfeile zum schrittweisen Rollen
Der Hintergrund besteht einfach aus einer einfarbigen Fläche. Ich verwende keine Linien oder Rahmen, da diese beim dynamischen Skalieren oft fehlerhaft bzw. unscharf dargestellt werden. Wer eine komplexere Optik möchte, kann den Komponenten eine eigene „ReScale“-Überwachung verpassen und die nötigen Verzierungen bei Bedarf neu zeichnen lassen.
Der Anfasser entspricht (bis auf die andere Farbe) dem Hintergrund.

Die Pfeiltasten bestehen aus zwei MovieClips: einem Hintergrund mit der Fläche 10x10 Pixel und einem Dreieck für den Pfeil selber. Dadurch können wir z.B. beim rollOver nur die Farbe des Pfeils ändern und die Hintergrundfläche unangetastet lassen.

Dem Pfeil geben wir den Instanznamen „arrow“, um ihn später ansprechen zu können.
Nun können wir die Einzelteile zusammensetzen. Wir erstellen einen neuen MovieClip mit dem Bezeichner „scroller“, in dem wir vier Ebenen anlegen:
- bgnd (für den Hintergrund)
- slide (für den Anfasser)
- arrows (für die Pfeiltasten)
- code (für ActionScript)

Für die untere Pfeiltaste spiegeln wir eine Instanz des MCs „arrow“ einfach nach unten (Modifizieren -> Transformieren -> Vertikal Spiegeln).
Die einzelnen MovieClips erhalten folgende Instanznamen:
- Hintergrund: „bgnd“
- Anfasser: „slider“
- Pfeil nach oben: „up“
- Pfeil nach unten: „down“
Zum Prinzip: Um einen Inhalt zu scrollen, benötigen wir einen Container, der sowohl den Inhalt (das kann ein beliebiger MovieClip sein) als auch eine Maske enthält, die dafür sorgt, dass ein gleichbleibend großer Ausschnitt dieses Inhaltes sichtbar ist. Durch Verschieben des Inhaltes unter der Maske ermöglichen wir den Scrollvorgang. Natürlich könnt Ihr sowohl den Inhalt als auch die Maske dynamisch nachskalieren, wenn Ihr z.B. ein Fenster erstellen wollt, das in der Größe veränderbar ist. In diesem Tutorial beschäftigen wir uns allerdings nur mit dem Scroller ansich, obwohl dieser die Voraussetzungen für dynamische Container enthält.
Wir müssen unserem Rollbalken also mitteilen, auf welche Maske und welchen Inhalt er sich beziehen soll. Daher schreiben wir eine Funktion „init()“, der wir unter anderem Referenzen auf diese Objekte übergeben. Zu Beginn initialisieren wir noch zwei Dinge: Wir schalten den Scroller unsichtbar und definieren eine Variable „sliding“, die uns später anzeigt, ob der Scroller im Moment bewegt wird:
PHP-Code:
this._visible = false;
var sliding = false;
Als nächstes legen wir die Funktion „init()“ an, mit der der Rollbalken initialisiert wird:
PHP-Code:
function init(h, c, m) {
bgnd._height = Math.round(h - up._height * 2);
down._y = bgnd._height + down._height;
this.ct = c;
this.mask = m;
startWatch();
}
- h: Die neue Höhe des Rollbalkens in Pixeln. Dadurch können wir die Größe des Scrollers unabhängig von den Maßen des Containers bestimmen.
- c: Eine Referenz auf den zu scrollenden Inhalt
- m: eine Referenz auf die Maske für den Inhalt. Obwohl es sich bei der Maske in den meisten Fällen um eine rechteckige Form handelt, packen wir diese in einen MovieClip, dem wir einen Instanznamen geben. Dadurch können wir die Maske referenzieren, da wir ja die Höhe des Inhaltes mit der Höhe der Maske vergleichen müssen.
Zunächst richten wir die Höhe des Balkens ein, indem wir von dem übergebenen Parameter die Höhe der beiden Pfeiltasten abziehen und den Hintergrund entsprechend skalieren. Die untere Pfeiltaste wird direkt unter den Hintergrund gesetzt.
Nun legen wir zwei Membervariablen „ct“ und „mask“ fest, die unsere Referenzen auf Inhalt und Maske enthalten. Nach der Initialisierung können wir die Funktion „startWatch()“ aufrufen, die die Überwachung und Steuerung startet:
PHP-Code:
function startWatch() {
slider.useHandCursor = false;
slider.onRollOver = function() {
this._alpha = 150;
}
slider.onRollOut = function() {
this._alpha = 100;
}
slider.onPress = function() {
this.startDrag(false, 0, 0, 0, bgnd._height - this._height);
sliding = true;
this._alpha = 150;
}
slider.onRelease = function() {
this.stopDrag();
sliding = false;
}
slider.onReleaseOutside = function() {
this.stopDrag();
sliding = false;
this._alpha = 100;
}
Beim onPress auf dem Anfasser starte ich mit „startDrag()“ eine Drag-Aktion, die durch die Höhe des Hintergrundes und die Maße des Anfassers begrenzt wird. Beim Loslassen der Maustaste wird die Drag-Aktion beendet.
Weiter gehts:
PHP-Code:
. up.useHandCursor = false;
up.onRollOver = function() {
this.arrow._alpha = 150;
}
up.onRollOut = function() {
this.arrow._alpha = 100;
}
up.onPress = function() {
startMove(-1);
}
up.onRelease = function() {
stopMove();
}
up.onReleaseOutside = function() {
this.arrow._alpha = 100;
}
down.useHandCursor = false;
down.onRollOver = function() {
this.arrow._alpha = 150;
}
down.onRollOut = function() {
this.arrow._alpha = 100;
}
down.onPress = function() {
startMove(1);
}
down.onRelease = function() {
stopMove();
}
down.onReleaseOutside = function() {
this.arrow._alpha = 100;
}
this.onEnterFrame = function() {
getPos();
reDraw();
}
}

Beim Druck auf eine Pfeiltaste wird eine Funktion „startMove()“ aufgerufen, die dafür sorgt, dass sich der Anfasser schrittweise nach oben bzw. unten bewegt. Der übergebene Parameter bestimmt die Laufrichtung (-1 = nach oben, 1 = nach unten). Beim release bzw. releaseOutside wird diese Bewegung mit der Funktion „stopMove()“ beendet.
Zuletzt definiere ich eine onEnterFrame-Methode, die periodisch die beiden Funktionen „getPos“ und „reDraw()“ aufruft. „getPos()“ dient zum Bestimmen der Anfasserpsition und Bewegen des Inhaltes, „reDraw()“ skaliert den Anfasser in Abhängigkeit von dem Größenverhältnis Maske - Inhalt und sorgt dafür, dass der Scroller nur sichtbar ist, wenn der Inhalt größer als die Maske ist.
Statt „onEnterFrame“ wäre eine Ereignisbasierte Steuerung sicher eleganter, aber diese Lösung würde eine weitaus stärkere Vernetzung von Inhalt und Scroller erfordern und ich möchte in die Struktur des Inhaltes möglichst wenig eingreifen, da uns dessen Struktur u.U. abgesehen von Inhalts-MC und Masken-MC weitgehend unbekannt ist. Zudem ist eine onEnterFrame-Methode für sich nicht besonders Performancelastig, zumal in „getPos()“ abhängig von unserer Variable „sliding“ die meiste Zeit nichts ausgeführt wird. Eine Alternative wäre für getPos allerdings „onMouseMove“ statt „onEnterFrame“.
PHP-Code:
function getPos() {
if (sliding) {
var smax = bgnd._height - slider._height;
var scur = slider._y;
var percent = scur * 100 / smax;
var ab_pos = percent * (ct._height - mask._height) / 100;
ct._y = -ab_pos;
// mask._parent.setScroll(ab_pos);
}
}
Statt einer direkten Zuweisung können wir in unserem Container auch eine Funktion „setScroll()“ anlegen, der wir den Scrolling-Wert übergeben. So kann der Container für die Bewegung des Inhaltes selbst sorgen und z.B. eine verzögerte oder abgebremste Bewegung realisiert werden.
PHP-Code:
function reDraw() {
var ratio = ct._height / mask._height;
slider._height = Math.round(bgnd._height / ratio);
if (slider._height < bgnd._height) {
this._visible = true;
} else {
this._visible = false;
}
}
Wenn die resultierende Höhe des Anfassers größer als die Höhe des Inhaltes wird (sprich: Inhalt ist kleiner als die Maske), so wird der gesamte Rollbalken ausgeblendet.
Statt dessen könnt Ihr natürlich eine eigene Implementierung verwenden, z.B. einfach eine Deaktivierung des Anfassers. In diesem Falle müsst Ihr zusätzlich darauf achten, dass die Größe des Anfassers die Größe des Hintergrundes nicht überschreitet.
Ausserdem könnte mit einer Abfrage verhindert werden, dass bei sehr großen Inhalten die Höhe des Anfassers z.B. unter 10 Pixel sinkt; darauf habe ich an dieser Stelle verzichtet, um das Tutorial kurz und knackig zu halten.
Zuletzt widmen wir uns den Funktionen zum Scrollen per Pfeiltasten. Der Übersichtlichkeit halber misbrauchen wir den Hintergrund für eine weitere onEnterFrame-Methode, statt eine zusätzliche Abfrage in die Funktion „getPos()“ einzubauen.
PHP-Code:
function startMove(d) {
if (speed == undefined) speed = 2;
sliding = true;
bgnd.onEnterFrame = function() {
slider._y += (d * speed);
if (slider._y < 0) slider._y = 0;
if (slider._y > bgnd._height - slider._height) slider._y = bgnd._height - slider._height;
}
}
Eine automatische Anpassung der Geschwindigkeit an das Verhältnis von Inhaltsgröße zu Maskengröße ist auch möglich. Generell sind noch etliche Erweiterungen und Verbesserungen an diesem Beispiel denkbar, aber aus oben genannten Gründen will ich an dieser Stelle nicht auf alle Möglichkeiten eingehen.
Beim Loslassen der Pfeiltasten wird die onEnterFrame-Methode auf dem Hintergrund einfach gelöscht und die Variable „sliding“ wieder auf „false“ gesetzt:
PHP-Code:
function stopMove() {
sliding = false;
delete bgnd.onEnterFrame;
}
Im Anhang findet Ihr eine Beispieldatei für Flash MX2004, in der ich einen einfachen Container mit Maske und Inhalt angelegt habe.
Um den Scroller zu initialisieren, wird einfach die Funktion „init()“ auf der Hauptzeitleiste aufgerufen:
PHP-Code:
this.onEnterFrame = function() {
scroller.init(180, window.container, window.mask);
delete this.onEnterFrame;
}
Achtung: Ich rufe diese Funktion in einer einmal durchlaufenen onEnterFrame-Methode auf, da Memberfunktionen von MovieClips erst einen Frameaufruf nach dem Laden des Films angesprochen werden können.
Das nächste Mal zeige ich Euch, wie Ihr zusätzlich ein Scrolling per Mausrad mit automatischer Bewegung des Rollbalkens einbauen könnt.

Viel Spaß!
P.S.: Im Anhang findet Ihr ein ZIP-Archiv mit den Beispieldateien und diesem Tutorial als PDF.
.



Kommentar schreiben

Bereiche
Kategorien
Forum - Webmaster & Internet





Artikel bewerten