tutorials.de Buch-Aktion 05/2012
RSS-Feed anzeigen

Datics Blog

dynamische Klasse für Eigenschaftsänderungen

Bewerten
von Tobias Menzel am 23.05.07 um 16:11 (406 Hits)
Angeregt Durch dieses Thema und in Anlehnung an Lukes Prototyp ist eine Klasse entstanden, die mehrere abbremsende oder elastische Eigenschaftsänderungen an einem MovieClip gleichzeitig durchführen kann.

Im Gegensatz zu Lukes Ansatz ist diese Klasse explizit für MovieClips gedacht, und arbeitet statt mit Intervallen mit einer zentralen onEnterFrame-Methode.

Für alle Animationen können Callback-Methoden definiert werden, denen den Namen der jeweiligen Eigenschaft und den erreichten Endwert übergeben wird.

Die Methoden:
  • startAni
    public startAni(propName:String, destVal:Number, speed:Number, [callback:Function, [mult:Number]]):Void

    Startet eine Änderung der angegebenen Eigenschaft

    Parameter:
    propName:String - Der Name der zu ändernden Eigenschaft (z.B. "_alpha")

    destVal:Number - Der zu erreichende Endwert der Eigenschaft (z.B. 100)

    speed:Number - Faktor für das abbremsende Verhalten (z.B. 5)

    callback:Function [optional] - Callbackfunktion, die nach dem Beenden der Animation ausgeführt wird

    mult:Number [optional] - Wenn angegeben, wird eine elastische Eigenschaftsänderung durchgeführt, wobei dieser Wert den elastischen Multiplikator angibt (z.B. 1.5)
  • stopAni
    public stopAni(propName:string):Number

    Beendet die Animation für die angegebene Eigenschaft aprupt und gibt den momentanen Wert dieser Eigenschaft zurück.

    Parameter:
    propName:String - Der Name der zu ändernden Eigenschaft (z.B. "_alpha")

Die Eigenschaft "minDist" legt minimalen Abstand zwischen momentanem und Zielwert fest, bei dem die Animation beendet wird.

Die Eigenschaft "minSpeed" legt bei elastischen Eigenschaftsänderungen als zusätzliches Kriterium die minimale Änderungsgeschwindigkeit fest, bei der die Animation beendet wird.

Beide Eigenschaften werden über Getter/Setter gesetzt bzw. abgefragt.

Code actionscript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class PropFade {
    private var _tgt:MovieClip;
    private var _aniFramer:MovieClip;
    private var _events:Array;
    private var _minDist:Number = 1;
    private var _minSpeed:Number = 0.5;
 
    public function PropFade(t:MovieClip) {
        this._tgt = t;
        this._events = new Array();
        this._aniFramer = t.createEmptyMovieClip("_aniFramer_" + new Date().valueOf().toString(), t.getNextHighestDepth());
        this._aniFramer.owner = this;
        this._aniFramer.onEnterFrame = function() {
            this.owner.handleEvents();
        }
    }
    
    private function handleEvents():Void {
        for (var i in _events) {
            if (_events[i]._mult == undefined) {
                _tgt[_events[i]._propName] += (_events[i]._destVal - _tgt[_events[i]._propName]) / _events[i]._speed;
            } else {
                _events[i]._spd = (_events[i]._spd + (_events[i]._destVal - _tgt[_events[i]._propName]) / _events[i]._speed) / _events[i]._mult;
                _tgt[_events[i]._propName] += _events[i]._spd;
            }
            if (Math.abs(_tgt[_events[i]._propName] - _events[i]._destVal) < _minDist) {
                if (_events[i]._mult == undefined || Math.abs(_events[i]._spd) < _minSpeed)  {
                    _tgt[_events[i]._propName] = _events[i]._destVal;
                    var _cb:Function = _events[i]._callback;
                    var _pn:String = _events[i]._propName;
                    _cb(_pn, stopAni(_events[i]._propName));
                }
            }
        }
    }
    
    public function startAni(propName:String, destVal:Number, speed:Number, callback:Function, mult:Number):Void {
        var overwrite:Boolean = false;
        for (var i in this._events) {
            var obj:Object = this._events[i];
            if (obj._propName == propName) {
                obj._destVal = destVal;
                obj._speed = speed;
                obj._callback = callback;
                obj._mult = mult;
                overwrite = true;
            }
        }
        if (!overwrite) {
            this._events.push({_propName:propName, _destVal:destVal, _speed:speed, _callback:callback, _mult:mult, _spd:0});
        }
    }
    
    public function stopAni(propName:String):Number {
        for (var i=0; i<_events.length; i++) {
            var obj:Object = _events[i];
            if (obj._propName == propName) {
                _events.splice(i, 1);
                break;
            }
        }
        return _tgt[propName];
    }
    
    public function set minDist(d:Number):Void {
        _minDist = d;
    }
    
    public function get minDist():Number {
        return _minDist;
    }
    
    public function set minSpeed(d:Number):Void {
        _minSpeed = d;
    }
    
    public function get minSpeed():Number {
        return _minSpeed;
    }
}

Exemplarischer Aufruf für einen MovieClip:
Code actionscript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import propFade;
 
var a = new propFade(meinMC);
 
a.minDist = 0.5; // Minimale Distanz festlegen (Standard: 1)
 
a.minSpeed = 0.5; // Minimale Geschwindigkeit festlegen (Standard: 0.5)
 
a.startAni("_alpha", 50, 5, onFinished); // Abbremsende Eigenschaftsänderung
 
a.startAni("_x", 400, 10, onFinished, 1.2); // Elastische Eigenschaftsänderung
 
function onFinished(propName, v) {
    trace("fertig: " + propName + " @" + v);
}

Viel Spaß

P.S.: Hier gibts den Quelltext als Copy&Paste-freundliche Version:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
[SIZE="1"]
class PropFade {
    private var _tgt:MovieClip;
    private var _aniFramer:MovieClip;
    private var _events:Array;
    private var _minDist:Number = 1;
    private var _minSpeed:Number = 0.5;
 
    public function PropFade(t:MovieClip) {
        this._tgt = t;
        this._events = new Array();
        this._aniFramer = t.createEmptyMovieClip("_aniFramer_" + new Date().valueOf().toString(), t.getNextHighestDepth());
        this._aniFramer.owner = this;
        this._aniFramer.onEnterFrame = function() {
            this.owner.handleEvents();
        }
    }
    
    private function handleEvents():Void {
        for (var i in _events) {
            if (_events[i]._mult == undefined) {
                _tgt[_events[i]._propName] += (_events[i]._destVal - _tgt[_events[i]._propName]) / _events[i]._speed;
            } else {
                _events[i]._spd = (_events[i]._spd + (_events[i]._destVal - _tgt[_events[i]._propName]) / _events[i]._speed) / _events[i]._mult;
                _tgt[_events[i]._propName] += _events[i]._spd;
            }
            if (Math.abs(_tgt[_events[i]._propName] - _events[i]._destVal) < _minDist) {
                if (_events[i]._mult == undefined || Math.abs(_events[i]._spd) < _minSpeed)  {
                    _tgt[_events[i]._propName] = _events[i]._destVal;
                    var _cb:Function = _events[i]._callback;
                    var _pn:String = _events[i]._propName;
                    _cb(_pn, stopAni(_events[i]._propName));
                }
            }
        }
    }
    
    public function startAni(propName:String, destVal:Number, speed:Number, callback:Function, mult:Number):Void {
        var overwrite:Boolean = false;
        for (var i in this._events) {
            var obj:Object = this._events[i];
            if (obj._propName == propName) {
                obj._destVal = destVal;
                obj._speed = speed;
                obj._callback = callback;
                obj._mult = mult;
                overwrite = true;
            }
        }
        if (!overwrite) {
            this._events.push({_propName:propName, _destVal:destVal, _speed:speed, _callback:callback, _mult:mult, _spd:0});
        }
    }
    
    public function stopAni(propName:String):Number {
        for (var i=0; i<_events.length; i++) {
            var obj:Object = _events[i];
            if (obj._propName == propName) {
                _events.splice(i, 1);
                break;
            }
        }
        return _tgt[propName];
    }
    
    public function set minDist(d:Number):Void {
        _minDist = d;
    }
    
    public function get minDist():Number {
        return _minDist;
    }
    
    public function set minSpeed(d:Number):Void {
        _minSpeed = d;
    }
    
    public function get minSpeed():Number {
        return _minSpeed;
    }
}[/SIZE]

EDIT 29.07.07: Einige Fehler korrigiert. u.a. wurde das Array _events versehentlich als statischer Member angelegt.

"dynamische Klasse für Eigenschaftsänderungen" bei Twitter speichern "dynamische Klasse für Eigenschaftsänderungen" bei Facebook speichern

Kategorien
Codeschnipsel

Kommentare