Skalierung mit gedämpfter Schwingung und dynamischer Verdrängung

likedeeler

Grünschnabel
Hi,

ich möchte ein Menü bauen, dessen Felder beim Rollover größer werden und dabei die benachbarten Felder verdrängen, d.h. kleiner machen. Das ganze soll nach Art einer gedämpften Schwingung ablaufen, d.h. erst etwas überschießen, dann wieder etwas kleiner werden, usw. Mit den normalen Easing-Routinen bekomme ich das bislang nicht hin. Zusätzlich sollen die Nachbarfelder reagieren, als ob ihre Grenzen mit elastischen Federn verbunden wären. Also eigentlich zwei Probleme...

Die Physikbuch-Formeln dazu sind einigermaßen kompliziert, und ich kapiere sie auch nicht so ganz. Hat jemand so etwas schon mal gebaut?

Ein gutes Beispiel für das, was ich meine findet sich auf www.mcdonalds.de.

Bisher benutze ich diesen Code, den jeder Movie Clip mitbekommt:

PHP:
// scaleMax - maximum scaling in percent
// scaleMin - minimum scaling in percent
// upscalingFactor - scaling factor for enlargement
// downscalingFactor - scaling factor for reduction
MovieClip.prototype.scale = 
	function(scaleMax, scaleMin, upscalingFactor, downscalingFactor) {
	if (this.isUpscaling == 1) {
		this._xscale += (scaleMax - this._xscale) / upscalingFactor;
		this._yscale += (scaleMax - this._yscale) / upscalingFactor;
	}
	if (this.isUpscaling == 0) {
		this._xscale += (scaleMin - this._xscale) / downscalingFactor;
		this._yscale += (scaleMin - this._yscale) / downscalingFactor;
	}
}

Bei Rollover (isUpscaling == 1) wird vergrößert, bei Rollout (isUpscaling == 0) wird verkleinert. Das sieht gut aus, normales Easing eben, aber es fehlt die Schwingung und auch die Auswirkungen auf die anderen Felder (d.h. Verdrängung benachbarter Movie Clips).

Thx und Gruß

P.S. Ja, ich habe die Easing-Threads durchsucht, aber so ganz passte kein Beitrag. Ist meine erste Frage, hoffentlich verständlich. Ansonsten macht die McDonald's-Seite, glaube ich, alles sonnenklar...
 
Hi,

die Frage nach der Verdrängung mal außen vor gelassen:
PHP:
MovieClip.prototype.scale =
    function(scaleMax, scaleMin, upscalingFactor, downscalingFactor, dampingFactor) {
    if (this.isUpscaling == 1) {
        this.scaleSpeed = (this.scaleSpeen + (scaleMax - this._xscale) / upscalingFactor) / dampingFactor;
    }
    if (this.isUpscaling == 0) {
        this.scaleSpeed = (this.scaleSpeen + (scaleMax - this._xscale) / downscalingFactor) / dampingFactor;
    }
    this._xscale += scaleSpeed;
    this._yscale = this._xscale;
}

Gruß

EDIT: blöde, blöde PHP-Tags, die sich nicht horizontal skalieren lassen... ^^
-
 
Das ging ja fix, danke! Gedämpft war die Skalierung allerdings auch schon vorher, selbst, wenn es nicht offensichtlich ist... D.h. wenn ich mir deinen Code so angucke, schwingt da nix um einen Zielwert hin und her. Wahrscheinlich muss ich doch was mit sin(zeit) machen...

Das eigentliche Problem ist aber nach wie vor die Sache mit der Verdrängung, d.h. die federnd verbundenen Clipgrenzen (s. McDonald's).
 
Hi,

doch, da schwingt was, wenn Du die Faktoren richtig wählst! Probier mal den folgenden Prototype:
PHP:
MovieClip.prototype.swingTo = function(dx, acc, dec) {
	var spd = 0;
	this.onEnterFrame = function() {
		spd = (spd + (dx - this._xscale) / acc) / dec;
		this._xscale += spd;
		this._yscale = this._xscale;
		if (Math.abs(spd) < 1 && Math.abs(dx - this._xscale) < 1) {
			this._xscale = this._yscale = dx;
			delete this.onEnterFrame;
		}
	}
}

Aufruf z.B. mit
PHP:
meinClip.swingTo(300, 5. 1.2);

Gruß

P.S.: die "Verdrängung" lässt sich z.B. relativ leicht lösen, indem Du auf einer übergeordneten Ebene (z.B. _root) onEnterFrame alle Clips durchgehst, und jedem beispielsweise die _x - Eigenschaft des vorherigen + seine Breite + einen Abstand (5px) verpasst. ;)
.
 
Zuletzt bearbeitet:
hey datic,

thx für den tip, das schwingt ja tatsächlich! COOL. und dein tip mit verdrängen geht dann so:

_root.onEnterFrame = function {
clip1_mc._x = // ...
clip2_mc._x = // ...
//...
}

()

heisst das, wenn ich auf _root-ebene in onEnterFrame eine eigenschaft von einem clip abfrage, dass das dann dynamisch den jeweiligen clipzustand berücksichtigt? (also, wenn z.b. die größe des clips hin- und herschwingt.)
 
Ja, denn die Eigenschaften _width und _height ändern sich mit _xscale und _yscale. Global kannst Du dann alle Clips in einer Reihe anordnen, indem Du diese Werte ausliest:
PHP:
clip[0]._x = 100;
for (var i=1; i<clip.length; i++) [
    clip[i]._x = clip[i-1]._x + clip[i-1]._width + 2;
}

Gruß
.
 
Zurück