SVG/Tutorials/Rube-Goldberg-Maschinen

Aus SELFHTML-Wiki
< SVG‎ | Tutorials
Wechseln zu: Navigation, Suche

Informationen zu diesem Text

Lesedauer
30min
Schwierigkeitsgrad
mittel
Vorausgesetztes Wissen
SVG
CSS-Animation
CSS-Transform

Der Ausdruck Rube-Goldberg-Maschine geht auf den US-amerikanischen Cartoonisten Reuben „Rube“ L. Goldberg zurück, der Comics über einen Professor Lucifer Gorgonzola Butts zeichnete, der unnötig komplizierte Maschinen konstruierte, bei denen eine eigentlich triviale Aktion durch eine Kette nacheinander ablaufender Aktionen ausgelöst wird.[1]

Auch im Film "Zurück in die Zukunft" gibt es in der Eingangsszene einen solchen Mechanismus, mit dem Doc Emmet Brown seinen Hund während seiner Abwesenheit allmorgendlich mit Futter versorgt.

Das Vorbild[Bearbeiten]

2007 stellte Alberto Pacheco vom Chihuahua Institute of Technology den Interpreter SLOGO vor, der aus PHP SVG-Markup ausgab. Berühmtestes Beispiel war die SVG-Animation einer Rube-Goldberg-Maschine.[2]

Ursprünglich in SMIL realisiert, funkioniert diese Variante mit CSS-Animations:

Rube-Goldberg-Machine von Alberto Pacheco, 2007 ansehen …
<rect x='0' y='0' width='8' height='28' rx='3' ry='3' fill='#444444' transform='translate(130,480),rotate(180)' stroke='black' stroke-width='1px'>
	<animateTransform attributeName='transform' type='rotate'  fill='freeze' begin='6.8s' dur='0.2s' from='0' to='70' additive='sum' />
</rect>
<!-- Error: %% Ficha 5 -->
<rect x='0' y='0' width='8' height='28' rx='3' ry='3' fill='#444444' transform='translate(150,480),rotate(180)' stroke='black' stroke-width='1px'>
	<animateTransform attributeName='transform' type='rotate'  fill='freeze' begin='6.9s' dur='0.2s' from='0' to='70' additive='sum' />
</rect>
<!-- Error: %% Ficha 6 -->
<rect x='0' y='0' width='8' height='28' rx='3' ry='3' fill='#444444' transform='translate(170,480),rotate(180)' stroke='black' stroke-width='1px'>
	<animateTransform attributeName='transform' type='rotate'  fill='freeze' begin='7s' dur='0.25s' from='0' to='90' additive='sum' />
</rect>
<!-- Error: %% Ficha 7 -->
<rect x='0' y='0' width='8' height='28' rx='3' ry='3' fill='#999999' transform='translate(190,480),rotate(180)' stroke='black' stroke-width='1px'>
	<animateTransform attributeName='transform' type='translate'  fill='freeze' begin='7.1s' dur='0.2s' from='0,0' to='-10,-5' additive='sum' />
	<animateTransform attributeName='transform' type='rotate'  fill='freeze' begin='7.1s' dur='0.2s' from='0' to='180' additive='sum' />
	<animate attributeName='y'  fill='freeze' begin='7.4s' dur='0.2s' from='0' to='46' />
</rect>

ToDo (weitere ToDos)

mit CSS-Animations realisieren! --Matthias Scharwies (Diskussion) 06:56, 25. Sep. 2020 (CEST)

Warum CSS-Animations???

Einfache Maschinen[Bearbeiten]

Hinter der Idee der Rube-Goldberg-Maschinen steckt die Anwendung Einfacher Maschinen[3], die zur Umwandlung einer Kraft dienen, um diese möglichst zweckmäßig zur Verrichtung von Arbeit einzusetzen. Beispiele für einfache Maschinen sind das Seil, der Hebel, die Rolle und die schiefe Ebene (Keil), die in irgendeiner Kombination in fast jeder Kraftmaschine vorkommen.

Die schiefe Ebene[Bearbeiten]

Eine schiefe, schräge oder geneigte Ebene ist in der Mechanik eine ebene Fläche, die gegen die Horizontale geneigt ist. Sie wird verwendet, um den Kraftaufwand zur Höhenveränderung einer Masse zu verringern – der Arbeitsaufwand bleibt jedoch unverändert.

Bei Kugelbahnen und Rube-Goldberg-Maschinen wird sie meist zum Herabrollen verwendet.


Schiefe Ebene ansehen …
@keyframes roll {
  0% {transform: translate(0,0);}
  75% {transform: translate(600px,-200px);}
  100% {transform: translate(0,0);}
}
      
circle {
  animation: roll 5s infinite ease-in;	
}

In diesem Beispiel wird die Kugel (ein circle-Element) zuerst langsam hochgeschoben und rollt dann von oben schnell nach unten. Dies wird über eine Verschiebung der Kugel mit transform:translate() erreicht.

Beachten Sie: Während das SVG-transform-Attribut von dimensionslosen Einheiten ausgeht und einen reinen Zahlenwert verarbeiten kann, benötigt die CSS-transform-Eigenschaft eine Einheit - hier px.

Hebel[Bearbeiten]

Ein Hebel ist in der Physik und Technik ein mechanischer Kraftwandler bestehend aus einem starren Körper, der um einen Drehpunkt drehbar ist.

Da die folgende Animation aus vier Teilschritten besteht, müssen die einzelnen Schritte getaktet werden. Mit custom properties kann die Dauer und auch der Start (bzw. die Verzögerung gegenüber dem Laden der Seite) der einzelnen Schritte zentral festgelegt werden.

  1. die Box fliegt von oben auf die Wippe
  2. Die Wippe senkt sich
  3. sobald die Box auf dem Hebel liegt, macht sie eine Kreisbewegung mit dem Drehpunkt der Wippe als Zentrum
  4. die rechte Box fliegt nach oben

Dabei starten die letzten drei Animations-Schritte gleichzeitig.

Zweiseitiger Hebel ansehen …
#box1{
	transform: translate(50px,0px) rotate(0deg);
    animation: fall var(--step1-duration) linear forwards;
}

@keyframes fall {
    0% {transform: translate(84px,0) rotate(20deg);}
   50% {transform:translate(100px,199px) rotate(20deg); }
   75% {transform:translate(75px,274px) rotate(0deg); }
  100% {transform:translate(80px,353px) rotate(-20deg);}
}

#board {
	transform: rotate(20deg);
    animation: turn var(--step2-duration) linear forwards var(--step2-delay);
}

@keyframes turn {
  0% {transform: rotate(20deg);}
  100% {transform: rotate(-20deg);}
}

#box2 {
	fill: var(--accent2color);
	transform: translate(473px,337px) rotate(20deg);
    animation: fall2 var(--step3-duration) ease-in forwards var(--step2-delay);
}

@keyframes fall2 {
    0% {transform: translate(473px,337px) rotate(20deg);}
  100% {transform: translate(600px,-100px) rotate(-20deg);}
}

ToDo (weitere ToDos)

Rotation einarbeiten! --Matthias Scharwies (Diskussion) 07:51, 11. Okt. 2020 (CEST)

Pendel[Bearbeiten]

Eine andere Form der Rotation sind Pendel.

CSS-Animation Pendel ansehen …
@keyframes swing {
    0% {transform: rotate(-30deg);}
  100% {transform: rotate(30deg);}
}
    
#pendulum {
    animation: swing 2s infinite alternate ease-in;	 
    transform: rotate(-30deg);           
}

Das Pendel besteht aus einer Gruppierung mit einem Ball, der an einem Faden hängt. Auf einen externen Drehpunkt wird verzichtet, das Pendel rotiert um die Aufhängung des Fadens, dem Ursprung (0|0).

Pendel aus Grundformen ansehen …
<g id="pendulum">
    <line id="thread" y2="200"/>
    <circle id="ball" cx="0" cy="200" r="30" />
</g>

Information: CSS oder XML-Attribute

Wann sollte ich CSS und wann XML-Attribute innerhalb der Elemente verwenden?
Dafür gibt es keine feste Regel. Ich halte es so, dass für alle Einstellungen, die mehrfach verwendet werden können, CSS und für einmalig angewandte Formatierungen XML-Attribute benutze.
--Matthias Scharwies (Diskussion) 07:51, 11. Okt. 2020 (CEST)

Das line-Element enthält nur ein Attribut für den Y-Wert des Endpunkts, für alle anderen Werte wird 0 angenommen.

Das Pendel wird von einer weiteren Gruppierung umschlossen, um es mit einem transform-Attribut an den richtigen Platz zu verschieben.

Kugelstoßpendel[Bearbeiten]

Ein Kugelstoßpendel ist eine Anordnung von identischen elastischen Kugeln, die in einer Reihe aufgehängt sind.Wenn eine der äußeren Kugeln abgehoben wird und gegen die Reihe der anderen Kugeln zurückfällt, bewirkt der Anprall, dass genau eine Kugel gegenüberliegend abgestoßen wird, während die anderen Kugeln in Ruhe bleiben. Pendelt diese Kugel zurück und prallt auf, wird durch den Stoß wieder die äußerste Kugel auf der anderen Seite abgestoßen – das System „schwingt“.

Auch dies lässt sich mit CSS animieren:

Kugelstoßpendel ansehen …
@keyframes swing {
=== Pendel ===
Eine andere Form der Rotation sind Pendel. 

* [[CSS/Tutorials/Transform/Drehen,_Kreisen_und_Pendeln#Kreisen_und_Pendeln_von_Elementen|CSS/Tutorials/Transform/Drehen, Kreisen und Pendeln]]

{{Beispiel|titel=CSS-Animation Pendel|zeige=Beispiel:SVG-Rube-Goldberg-4.html|
{{BeispielCode|<source lang="css">
@keyframes swing {
    0% {transform: rotate(-30deg);}
  100% {transform: rotate(30deg);}
}
    
#pendulum {
    animation: swing 2s infinite alternate ease-in;	 
    transform: rotate(-30deg);           
}

Das Pendel besteht aus einer Gruppierung mit einem Ball, der an einem Faden hängt. Auf einen externen Drehpunkt wird verzichtet, das Pendel rotiert um die Aufhängung des Fadens, dem Ursprung (0|0).

Pendel aus Grundformen ansehen …
<g id="pendulum">
    <line id="thread" y2="200"/>
    <circle id="ball" cx="0" cy="200" r="30" />
</g>

Information: CSS oder XML-Attribute

Wann sollte ich CSS und wann XML-Attribute innerhalb der Elemente verwenden?
Dafür gibt es keine feste Regel. Ich halte es so, dass für alle Einstellungen, die mehrfach verwendet werden können, CSS und für einmalig angewandte Formatierungen XML-Attribute benutze.
--Matthias Scharwies (Diskussion) 07:51, 11. Okt. 2020 (CEST)

Das line-Element enthält nur ein Attribut für den Y-Wert des Endpunkts, für alle anderen Werte wird 0 angenommen.

Das Pendel wird von einer weiteren Gruppierung umschlossen, um es mit einem transform-Attribut an den richtigen Platz zu verschieben.

Kugelstoßpendel[Bearbeiten]

Ein Kugelstoßpendel ist eine Anordnung von identischen elastischen Kugeln, die in einer Reihe aufgehängt sind.Wenn eine der äußeren Kugeln abgehoben wird und gegen die Reihe der anderen Kugeln zurückfällt, bewirkt der Anprall, dass genau eine Kugel gegenüberliegend abgestoßen wird, während die anderen Kugeln in Ruhe bleiben. Pendelt diese Kugel zurück und prallt auf, wird durch den Stoß wieder die äußerste Kugel auf der anderen Seite abgestoßen – das System „schwingt“.

Auch dies lässt sich mit CSS animieren:

Kugelstoßpendel ansehen …
@keyframes swing {
    0% {transform: rotate(-30deg);}
  100% {transform: rotate(30deg);}
}


</source>}}}}



Flaschenzug[Bearbeiten]


ToDo (weitere ToDos)

500px


Wikimedia Commons:Flaschenzug.svg

Zahnräder[Bearbeiten]

Zahnräder (englisch: cog wheels) sorgen ähnlich wie Flaschenzüge für die Über- oder Untersetzung von Bewegung. Mit SVG lässt sich der Effekt eines drehenden Zahnrads leicht erzeugen:[4]

Zahnräder mit stroke-dashoffset ansehen …
<circle cx="140" cy="100" r="50" stroke-dasharray="12,12">
	<animate attributeName="stroke-dashoffset" repeatCount="indefinite" values="24;1" dur="0.5s"  />
</circle>

<circle cx="250" cy="100" r="50" stroke-dasharray="12,12" >
	<animate attributeName="stroke-dashoffset" repeatCount="indefinite" values="12;36" dur="0.5s"  />
</circle>

In diesem Beispiel drehen sich aber nicht die Räder selbst, sondern nur die Randlinie (stroke). Selbst diese wird nicht rotiert, sondern verändert nur ihre Strichelung. Besser wäre es natürlich, wenn sich das gesamte Zahnrad drehen würde.


Peter Collingridge schuf Zahnräder, die er dann mit animateTransform um sich selbst rotieren ließ.[5]. Wir nehmen seine Idee auf, zentrieren jedoch alle Zahnräder um den Ursprung (0|0), was eine spätere Drehung vereinfacht und verschieben sie erst nach der Rotation:

komplexere Zahnräder ansehen …
svg {
  --ani-duration:20s;
}  

svg:hover .animated {
    animation: turn var(--ani-duration) infinite linear;
}

@keyframes turn {
    0% {transform: rotate(0deg);}
  100% {transform: rotate(360deg);}
}

#gear2 .animated {
	animation-duration: calc(var(--ani-duration) * 0.25);
	animation-direction: reverse;
}

Jedes Zahnrad besteht aus einer Gruppierung, die das um den Ursprung zentrierte Zahnrad als path-Element und ein circle als Radnabe enthält. Diese Gruppierung wird dann mit einer SVG-Transformation an die passende Stelle verschoben.

Beachten Sie: Eine Verschiebung an den richtigen Ort und eine dort folgende Rotation für das gleiche Element sind nicht möglich, weil die erste Transformation von der zweiten überschrieben würde. Es wäre möglich Verschiebung und Rotation innerhalb der @keyframes-Regel zu kombinieren, dann wäre sie aber nicht mehr universell einsetzbar.

Über Klassen werden die path-Elemente der Zahnräder farbig formatiert und animiert. Für jedes rotierende Element muss die richtige Umdrehungsdauer festgelegt werden. Hier wird die Variable --ani-duration verwendet und mit der calc()-Funktion passend berechnet.

Empfehlung: Das Zeichnen von Zahnrädern ist nicht trivial - da die Zähne unterschiedlich großer Zahnräder ja eineinander greifen müssen.
Es wäre zu überlegen, mit JavaScript einen gegebenen Zahnrad-Radius mit passenden Zähnen zu berechenen und ein path-Element zu generieren. Über den Radius kann dann der Umfang und so die nötige Drehgeschwindigkeit für jedes Zahnrad berechnet werden.[6]

Ideen[Bearbeiten]

  • Becher - Wasser - Gewicht
  • Blasebalg - Segelboot / Ball
  • Archimedische Schraube
  • Gaußsche Kanone / Impulskanone
  • Mausefalle / Katapult

Anwendungsbeispiele[Bearbeiten]

Während des SELF-Treffens 2020 wurden in einem Workshop verschiedene Rube-Goldberg-Maschinen entworfen, die hier präsentiert werden:

ToDo (weitere ToDos)

Beispiele

Weblinks[Bearbeiten]

  1. Wikipedia: Rube-Goldberg-Maschine
  2. SLOGO: A Vector Graphic Application Prototyping Language von Alberto Pacheco, Instituto Tecnológico de Chihuahua
  3. Wikipedia: Einfache Maschine
  4. cs.sru.edu: Timing von David Dailey, 2011
  5. Peter Collingridge: SVG animation: Rotating elements Zahnräder erzeugen und rotieren
  6. MSDN SVG-Animation für Anfänger