Tutorial: Ein Tag mit Bobby

Beitragsbild Tutorial zur Animation: Ein Tag mit Bobby

Autor*in: Julia Solohub 


Animation anschauen

Quellcode (Zip-Archiv zum Download)

Dieser Beitrag ist ein Tutorial zu der Animation „Ein Tag mit Bobby“ bei dem auf die Details zum Code, Inhalt, Besonderheiten, das Konzept und Schwierigkeiten eingegangen wird. Die Bilder dienen zur Veranschaulichung und Nachvollziehbarkeit und sind anklickbar, sodass man diese in Vollbildmodus und besserer Auflösung betrachten kann.

Inhaltsverzeichnis

Das Konzept

Die Animation ist ein Storytelling, bei dem der User mit Hilfe von Buttonklicks durch die einzelnen Szenen geleitet wird.  Dieser begleitet den Hauptcharakter Bobby durch den Tag und führt verschiedene Anweisungen durch, die Bobby in der Sprechblase gibt. Diese können durch einen Buttonklick realisiert werden. Sobald der User auf einen Button klickt, wird entweder die Szene gewechselt oder ein visueller Effekt erzeugt.

Das Ziel ist es mit dem User eine Interaktion zu starten, wobei dieser den Ablauf der Animation lenkt. Der User wird zu Beginn auch direkt von Bobby mit dem Namen angesprochen und aufgefordert mit ihm den Tag zu verbringen.

Die Idee eine Animation mit Hund(en) zu erstellen, kommt von der persönlichen Liebe zu Tieren und insbesondere zu Hunden. Die kindliche und amüsante Darstellung soll den User animieren und erfreuen. Die Hintergrundmusik sorgt für eine zusätzliche entspannte Atmosphäre, die die Stimmung der Animation unterstützt. Der User kann sich somit entspannen, zurücklehnen und die Animation genießen.

Aufbau

Die Animation ist in vier Szenen aufgeteilt:

  1. Start-Szene (div class=“ story_start_scene“)
  2. Bobby im Wohnzimmer (div-class= „dog_in_livingroom_scene“)
  3. Bobby im Park (div class=”background_image_park_day”)
  4. Schluss-Szene bei der Bobby im Park nachts ist (div class=”dog_in_park_night”)

Start Szene

Bei der Start Szene sieht man den schlafenden Bobby auf einem Teppich ohne jeglichen Hintergrund, das sich zu den restlichen Szenen unterscheidet. Der Grund dafür ist, dass man zum einen den beweglichen und farbwechselnden Hintergrund auf sich wirken lassen kann und zum anderen sollte es schlicht gehalten werden, damit der Wechsel zu den Hauptszenen spannender gestaltet wird. Zudem soll der Fokus zu Beginn auf dem Hauptcharakter liegen. Mit dem Buttonklick auf „Aufwecken“ startet die ganze Animation.

Start Szene

Zweite Szene

In der zweiten Szene befindet sich Bobby im Wohnzimmer, wo er zuvor auf dem Teppich geschlafen hat. Der User hat ihn aufgeweckt und nun fragt Bobby ihn nach seinem Namen. Die Abfrage passiert zwischen der ersten und der zweiten Szene, die mit Hilfe von JavaScript erzeugt wurde. Je nachdem welchen Namen der User eingibt, erscheint dieser in dem Begrüßungstext in der Sprechblase. Hier wird der User aufgefordert die Anweisungen von Bobby durchzuführen. In dieser Szene soll der User mit Bobby in den Park gehen.

Zweite Szene
Zweite Szene

Dritte Szene

Die dritte Szene spielt sich im Park tagsüber ab in den mehrere Aktionen passieren. Zu Beginn sieht man den Park, in dem sich ein Grill und Bobby befinden. Bobby weist darauf hin, dass es vom Grill sehr gut riecht und er gerne einen Hot Dog haben möchte. Dieser Bitte kann der User nachgehen, indem er auf den langsam erscheinenden Button „Hot Dog geben“ klicken kann. Sobald dies gemacht wurde, erscheint ein animierter Hot Dog, der vom Grill aus zu Bobby in einer 360 Grad Drehung geworfen wird. Daraufhin bedankt sich Bobby und gibt den nächsten Hinweis, dass er seinen Freund Bello sieht und mit ihm Ball spielen möchte.

Dritte Szene
Dritte Szene

Auch hier kann der User der Anweisung nachgehen, indem er auf den nächsterscheinenden Button „Mit Bello spielen“ klickt. Hier erfolgt die nächste Animation, bei der sich Bello und Bobby den Ball zu werfen. Dabei springen beide versetzt hoch und werfen den Ball mit ihrem Kopf einander zu. Nun erscheint der fünfte Button „Weiter“, der den User darauf hinweist, dass danach die nächste Szene erscheint.

Vierte Szene

Vierte Szene
Vierte Szene

Die vierte und letzte Szene findet in dem selben Park statt. Jedoch ist es schon spät geworden und Bobby ist müde. Er macht vor Freude Rückwärtssaltos und bedankt sich für den großartigen Tag, den er mit dem User erlebt hat. Auch hier weist Bobby daraufhin, dass er müde und erschöpft ist. Hier ist es Zeit sich von Bobby zu verabschieden und ihm eine Gute Nacht zu wünschen.

Letzte Szene
Letzte Szene

Mit dem Buttonklick kann man dies tun, wobei das Bild von Bobby in den ursprünglich schlafenden Zustand zurückgebracht wird. Es taucht ein Eyecatcher auf, der zoomt und sich hin und her in verschiedene Winkel dreht. Dies ist der Abschluss der Animation, der durch den animierten Text „Gute Nacht, Bobby“ kenntlich gemacht wird. Der letzte Button unterscheidet sich in der Erscheinungsweise von allen anderen, denn dieser macht auf sich Aufmerksam, indem sich dieser hin und her bewegt und dabei vertikal spiegelt. Der Grund für diese Erscheinungsweise ist das Aufmerksam machen, dass ab hier keine neue Szene erscheint, sondern alles nochmal vom Anfang beginnt. Somit ermöglicht dieser Button die Animation nochmal neu zu starten

Der Code

Für die Animationen wurden HTML5, CSS3 sowie JavaScript und jQuery benutzt. HTML5 wurde für das Grundgerüst und Aufbau, CSS3 für die Animation sowie das Styling und JavaScript bzw. jQuery für das Auslösen/Verstecken verschiedener Animationsobjekte benutzt.

Allgemeine Einstellungen

In der ID „animation_start“ in HTML5 spielt sich die gesamte Animation ab. Die jeweiligen Szenen sind in einzelne div-classes unterteilt in denen die dazugehörigen Objekte enthalten sind. Die div-classes sind nach den Szenarien benannt, das das Erkennen der Inhalte vereinfacht.

<div id="animation_start"class="whole_animation"> <!--ID der gesamten Animation-->
      <div class="story_start_scene"><!--Erste Szene: Startbildschrim-->
         <img src="sleeping_dog.png" id="sleep"/>
         <img src="carpet.png" id="carpet"/>
       </div>
    
       <div class="dog_in_livingroom_scene"> <!---Zweite Szene: Bobby im Wohnzimmer Szene samt Begrüßung-->
          <div class="living_room_background">
            <img src="room.png" class="backgroundimage_livingroom" style="visibility: hidden;"/>
           </div> 
           <div class="dog_character">
             <img src="standing_dog.png" id="hello_dog" style="visibility: hidden;"/>
             <img src="sprechblase.png" id="speak1" style="visibility: hidden;"/> 
             <p id="welcome_text" style="visibility: hidden;">Hallo! Ich bin Bobby. Lass uns den Tag zusammen verbringen.</p>
           </div>
       </div>

       <div class="dog_in_park_day"> <!--Dritte Szene: Bobby im Park Szene mit dazugehörigen Objekten-->
           <div class="background_image_park_day">
             <img src="meadow_at_day.png" class="backgroundimage_park_day" style="visibility: hidden;"/>        
           </div>
           <div class="park_items">
             <img src="grill.png" id="bbq" style="visibility: hidden;"/>
             <img src="food.png" id="hot_dog" style="visibility: hidden;"/>
             <img src="standing_dog2.png" id="dog_at_park" style="visibility: hidden;"/>
             <img src="sprechblase2.png" id="speak2" style="visibility: hidden;"/>
             <p id="hot_dog_text" style="visibility: hidden;">Das riecht aber toll! Kannst du mir einen Hot Dog geben?</p>
             <p id="thank_you_hot_dog_text" style="visibility: hidden;">Danke! Ouh Schau! Da ist Bello. Ich möchte mit ihm Ball spielen.</p>
             <img src="playing_dog_brown.png" id="bello" style="visibility: hidden;"/>
             <img src="playing_dog_grey.png" id="bobby" style= "visibility: hidden;"/>
             <img src="ball.png" id="toy" style="visibility: hidden;"/>    
           </div> 
       </div>

       <div class="dog_in_park_night"><!--Abschlussszene: Bobby im Park nachts.--> 
           <div class="background_image_park_night">
             <img src="meadow_at_night.png" id="backgroundimage2" style="visibility: hidden;"/> 
             <img src="dog_by_night.png" id="night_dog" style="visibility: hidden;"/>
             <img src="sprechblase3.png" id="speak4" style="visibility: hidden;"/>
             <img src="sleeping_dog2.png" id="tired" style="visibility: hidden;"/>  
             <p id="thank_you_for_the_day" style="visibility: hidden;">Danke dir für den schönen Tag! Ich bin jetzt aber müde.</p>
             <p id="good_night_bobby" style="visibility: hidden;">Gute Nacht, Bobby</p>
           </div>
       </div>
 </div><!--Ende der "animation_start"-->

In der aside-class wurden alle Buttons und der Titel der der Animation eingetragen, da diese Inhalte sich immer an der selben Position befinden.

<body>
  <!--Alle Elemente sind auf "visibility:hidden" gesetzt, die über JavaScript aktiviert werden, wenn man auf einen Button klickt-->
  <script src="animation_functions.js"></script> <!--Einbindung der JavaScript Datei-->
  <aside class="title_and_buttons"> <!--Übergreifende Class für alle Buttons und Titel der Animation (h1) damit die Position die selbe bleibt-->
    <h1> Ein Tag mit Bobby</h1>
    <button id="button_aufwecken">
       <a class="button_1">Aufwecken</a>
    </button>
    <button id="button_park" style="visibility: hidden;">
      <a class="button_2">Lass uns in den Park gehen</a>
   </button>
   <button id="button_hot_dog" style="visibility: hidden;">
      <a class="button_3">Hot Dog geben </a>
    </button>
    <button id="button_play" style="visibility: hidden;">
      <a class="button_4">Mit Bello spielen</a>
    </button>
    <button id="button_next" style="visibility: hidden;">
     <a class="button_5">Weiter</a>
   </button>
   <button id="button_good_night" style="visibility: hidden;">
     <a class="button_6">Gute Nacht!</a>
  </button>
   <button id="button_reload" style="visibility: hidden;">
     <a class="button_7">Neustart</a>
 </button>
</aside> 

Auffallend im Code ist, dass alle Objekte nicht sichtbar sind (visibility: hidden). Diese werden zu dem Zeitpunkt wann die jeweiligen Objekte zu sehen sein sollen mit Hilfe von jQuery sichtbar gemacht. Die allgemeine Position aller Elemente ist in der ID „animation“ sowie dessen class „whole_animation“ zu sehen. So entsteht ein Rahmen für die verschiedenen Bilder, das die Zentrierung der Szenen möglich macht. Die gewählte Größe und Position erstellt eine Box, wo sich die Animation abspielt. Dies soll ein Gefühl erzeugen, als würde man in einem Kino vor einer Leinwand sitzen.

#animation { /*Ausrichtung der gesamten Animation*/
  align-items: center;
  min-height: 100%;
  position: absolute;
}

.whole_animation {
  max-width: 900px;
  margin: 0em auto 0;
  text-align: center;
  max-height:800px;  
  overflow: hidden;
}
  
.title_and_buttons { /*Ausrichtung aller Buttons und der h1*/
  max-width: 900px;
  text-align: center;
  margin: 1em auto; 
  padding:1px;
}
   
h1 {
  color: white;
  font-size: 1.7rem;
}

Im Body ist die Animation des ineinanderfließenden Hintergrundes zu sehen. Die keyframes bringen diese Animation zum Laufen. Zunächst muss man drei Farben definieren, die man in dem Übergang haben möchte. Des Weiteren war es wichtig die Dauer und Länge zu definieren. In diesem Fall sollte der gesamte Übergang 13 Sekunden dauern und unbegrenzt durchlaufen.

body {
  font-family: "Comic sans MS"; 
  background-size: cover; 
  justify-content:center;
  background-position: center;
  background: -webkit-linear-gradient(132deg, #FC415A, #591BC5, #4a8ead); 
  background-size: 400% 400%;
  align-items: center;
  min-height: 100%;
  overflow:hidden;
  -webkit-animation: moving_background 13s ease infinite;
  animation: moving_background 13s ease infinite;
}

@-webkit-keyframes moving_background {  /*Animation des Backgrounds, der in Dauerschleife die Farben wechselt*/
  0% {
      background-position: 0% 50%;
  }
  50% {
      background-position: 100% 50%; /*Inspired by https://www.sliderrevolution.com/resources/css-animated-background/*/
  }
  100% {
      background-position: 0% 50%;
  }
}

Die Buttons

Die Buttons haben wie schon zuvor erwähnt den funktionalen Zweck den User durch die Szenen zu geleiten und verschiedene Animationen hervorzurufen. Somit sind diese essenziel für das Abspielen der Animation. Aus diesem Grund werden diese oberhalb der Animationsbox dargestellt, damit die Aufmerksamkeit des Users zu den bestimmten Zeitpunkten darauf gelenkt wird.

Die Buttons haben alle den selben Stil, jedoch haben alle verschiedene Dauer und Art und Weise der Animation. Daher wurde jeder einzelne Button in CSS3 angelegt. Das Aussehen der Buttons ist Oval und hat drei Farbverläufe, das in zarten und hellen Farben gehalten ist, um mit dem Hintergrund zu harmonieren. Beim Hovern erfolgt ein Spiegeleffekt bei dem die Farben von rechts nach links ineinander laufen. Durch das bewegte Gelb wir ein Relief- bzw. Spiegeleffekt erzeugt. Die transition ermöglicht dies.

#button_aufwecken { /*Design und Animation der Buttons. Alle haben die gleiche Einstellung nur andere Animationsangaben. Daher jeden Button einzeln angelegt, anstatt die zusammenzufassen*/
  border-radius: 50%;
  align-items: center;
  font-size: 15px;
  display: flex;
  margin: auto;
  background-image: linear-gradient(135deg, #ee9ca7 0%, #fbed96 51%, #ee9ca7 100%);  /*Inspired by https://blog.avada.io/css/button-hover-effects/*/
  background-size: 200% auto;
  box-shadow: #a05a9c 0px 0px 5px;
  -webkit-animation: push_buttom 3s infinite;
  animation: push_button 3s infinite;
  outline: none;
}


@-webkit-keyframes push_button {                       /*Inspired by https://css-tricks.com/css-animation-libraries/*/
  0% {
    box-shadow: 0px 0px 4px rgb(255,250,250);
  }
          
  
  50% {
    box-shadow: 0px 0px 23px rgb(255,250,250);
  
  }
  100% {
    box-shadow: 0px 0px 12px rgb(255,250,250);
  }
}

@keyframes push_button {                       
0% {
  box-shadow: 0px 0px 4px rgb(255,250,250);
}
        

50% {
  box-shadow: 0px 0px 23px rgb(255,250,250);

}
100% {
  box-shadow: 0px 0px 12px rgb(255,250,250);
 }
} 

#button_aufwecken:hover {
  background-position: right center;
  transition: all 0.5s ease-out;
  }
      
.button_1{
  flex: 1 auto;
  margin:5px;
  padding:10px 25px;
  text-align:center;
  transition: all 0.5s ease-out;
  cursor:pointer;
  background-size: 200% auto;
  font-family: "Comic sans MS";
}

Animierte Objekte

Alle benutzen Bilder, bis auf die Hintergrundbilder der Szenen, haben einen funktionalen Zweck. Alle Bilder sind PNG Dateien und von Pixabay. Durch die position: relativ war es einfach alle Objekte in einer Szene zu platzieren. Ausgerichtet und an den gewünschten Platz gebracht wurde mit bottom, top, left, right und margin.  Keyframes erzeugen die Animationen der Objekte. Die nachfolgenden Abschnitte beschreiben die einzelnen animierten Objekte.

Text in Sprechblase

Der sprechende Text, den Bobby in der Sprechblase sagt zoomt rein und raus und wechselt dabei zwischen drei Farben. So sollte die Aufmerksamkeit auf den Text gelenkt werden, damit der User den Anweisungen folgen kann. Dazu wird die animation-timing-function auf ease gesetzt. Zudem soll der Zoomeffekt in Dauerschleife ablaufen. Daher der Wert infinite. Durch scale() konnte die Größe der Transformation des Textes eingerichtet werden. Color sorgt für den Farbverlauf, der sich über die verschiedenen Sequenzen (0%, 50%, 100%) ändert.

#welcome_text { /*Annimation für Text in der Sprechblase. Wird in jeder Szene eingesetzt*/
  position: relative;
  bottom: 392px;
  left: 475px;
  z-index: 4;
  font-size: 10px;
  box-sizing: border-box;  
  overflow: hidden;
  border-width: 20px;
  border: 1px hidden;
  width: 135px;

  -webkit-animation: typing_hello 1.5s ease infinite; 
  -webkit-animation-delay: 0s;
  -webkit-animation-play-state: paused;
  -webkit-animation-fill-mode: forwards;

  animation: typing_hello 1.5s ease infinite;
  animation-delay: 0s;
  animation-fill-mode: forwards;
  animation-play-state: paused;     
}

  @-webkit-keyframes typing_hello {
   0% {
    transform: 
       scale(0.7, 0.7);
       color:rgb(116, 9, 107)
  }
   50% {
    transform: 
       scale(0.9, 0.9);
       color:rgb(85, 25, 134)
  }
   100% {
    transform: 
      scale(0.7, 0.7);
      color:rgb(73, 41, 214)
  }
}

Fliegender Hot Dog

Für die Animation des fliegenden Hot Dogs wurden in den keyframes die Werte translateX(), translateY() und rotate() verwendet. Die beiden ersten Werte sorgen für die Verschiebung auf der X- und Y-Aschse, wobei ein negativer translateY() Wert das Objekt nach oben versetzt. Daher ist bei 50%, das der höchste Punkt der Flugbahn sein soll, ein negativer Wert von -80px. rotate() sorgt für die Rotation des Objektes. Hierbei müssen Gradzahlen eingetragen werden.

#hot_dog { /*Animation des fliegenden Hot-Dogs*/
  width: 47px;
  z-index: 2;
  position: relative;
  bottom: 300px;
  right: 225px;

  -webkit-animation-name: flying_hot_dog;
  -webkit-animation-duration: 2s;
  -webkit-animation-timing-function: linear;
  -webkit-animation-fill-mode: forwards;
  -webkit-animation-delay: 0s;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-play-state: paused;
  
  animation-name: flying_hot_dog; 
  animation-duration: 2s;
  animation-fill-mode:forwards;
  animation-delay: 0s;
  animation-timing-function: linear;
  animation-iteration-count: 1;
  animation-play-state: paused;
}
 
  @-webkit-keyframes flying_hot_dog {
    from  { transform: translateX(0px) translateY(20px)  rotate(0deg) }
    50%   { transform: translateX(220px) translateY(-80px) rotate(180deg) }
    to    { transform: translateX(440px) translateY(95px)rotate(360deg) }
  }

  @keyframes flying_hot_dog {
    from  { transform: translateX(0px) translateY(20px)  rotate(0deg) }
    50%   { transform: translateX(220px) translateY(-80px) rotate(180deg) }
    to    { transform: translateX(440px) translateY(95px)rotate(360deg) }
  }

Bello und Bobby beim Ballspielen

Die Animation der zwei spielenden Hunde war am schwierigsten zu gestalten, da hier der Zeitfaktor eine große Rolle spielt, damit alles synchron abläuft. Zunächst die Gestaltung der beiden springenden Hunde. Hierbei muss man die Sequenzen (0%-100%) der bottom-Wert ändern. Je größer der Wert, desto höher steigen die Objekte auf. Die ease-out Eigenschaft sorgt dafür, dass das Ende der Sequenz langsamer abläuft. So kommt der fließende Sprung zustande. Beide Hunde haben die selben Animationseigenschaften. Der Unterschied liegt im animation-delay. Bello fängt eine Sekunde später an zu springen als Bobby. So entsteht der abwechselnde Sprung.

#bello { /*Ab hier folgt die Animation der zwei mit dem Ball spielenden Hunde*/
  width: 90px;
  z-index: 3;
  position: relative;
  bottom: 430px;

  -webkit-animation: move_bello 2s infinite;
  -webkit-animation-delay: 1s;

  animation: move_bello 2s infinite;
  animation-delay: 1s;
}

@-webkit-keyframes move_bello {
  from { bottom: 477px; animation-timing-function: ease-out; }
  50% { bottom: 570px; animation-timing-function: ease-out; }
   to { bottom: 477px; }
}

@keyframes move_bello {
  from { bottom: 477px; animation-timing-function: ease-out; }
  50% { bottom: 570px; animation-timing-function: ease-out; }
   to { bottom: 477px; }
}

#bobby {
  width: 90px;
  z-index: 3;
  position: relative;
  left: 200px;
  bottom: 430px;

  -webkit-animation: move_bobby 2s infinite;
  animation: move_bobby 2s infinite;;
}

@-webkit-keyframes move_bobby {
  from {  bottom: 477px; animation-timing-function: ease-out; }
    50% { bottom: 570px; animation-timing-function: ease-out; }
     to { bottom: 477px; }
}

Die Animation des Balls wurde nach dem selben Konzept wie die des Hot Dogs gestaltet. Hier bestand die Schwierigkeit mit der Positionierung und der Dauer des fliegenden Balls. Es musste alles auf die beiden springenden Hunde angepasst werden, sodass der Effekt eines Kopfballs entsteht.

Saltomachender Bobby

In der letzten Szene macht Bobby ein Rückwärtssalto. Dieser Effekt wurde mit den gleichen Eigenschaften wie bei dem fliegenden Hot Dog und Ball animiert. Da der Charakter sich auf einer Stelle bewegt und nur hochspringt und dreht, bleibt der translateX()vWert bei 0px. Dem entsprechend muss der translateY() und rotate() angepasst werden.

#night_dog {
  width: 80px;
  position: relative;
  right: 380px;
  bottom: 1039px;
  -webkit-animation: salto_dog 2s infinite;
  -webkit-animation-timing-function: linear;
  animation: salto_dog 2s infinite;
  animation-timing-function: linear;
}

@-webkit-keyframes salto_dog {  /*Animation von Bobby, der eine Rückwärtsrolle macht*/
  from  { transform: translateX(0px) translateY(0px)  rotate(0deg) }
  50%   { transform: translateX(0px) translateY(-80px) rotate(-180deg) }
  to    { transform: translateX(0px) translateY(0px)rotate(-360deg) }
}

Buttons

#button_reload {
border-radius: 50%;
align-items: center;
font-size: 15px;
display: flex;
margin: auto;
background-image: linear-gradient(135deg, #ee9ca7 0%, #fbed96 51%, #ee9ca7 100%); /*https://blog.avada.io/css/button-hover-effects/*/
background-size: 200% auto;
box-shadow: #a05a9c 0px 0px 5px; 
margin-top: -50px;
}

#button_reload {
-webkit-animation-name: button_load;
-webkit-animation-duration: 3s;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: forwards;
-webkit-animation-iteration-count: infinite;
-webkit-animation-play-state: paused;
-webkit-animation-direction: alternate-reverse;

animation-name: button_load; 
animation-duration: 3s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-iteration-count:infinite;
animation-play-state: paused;
animation-direction: alternate-reverse;
}

@-webkit-keyframes button_load {
  from  { transform: translateX(-20px) scaleX(1.0)}
  to    { transform: translateX(20px) scaleX(-1.0)}
} 

Die Buttons wurden im vorherigen Kapitel schon beschrieben. Nun wird näher auf die animierenden Effekte eingegangen. Der Effekt des Einblendens wurde durch die opacity Eigenschaft erzeugt, der von 0 auf 1 steigt und durch die animation-duration in die Länge gezogen wird. Der erste und letzte Button haben jedoch ein paar zusätzliche Effekte. Beim ersten Button „Aufwecken“ leuchtet der Button-Hintergrund in Weiß. Durch den versetzten box-shadow und der Dauerschleife (infinite) wird das pulsierende Leuchten erzeugt (siehe Bild ). Der letzte Button „Neustart“ dreht und bewegt sich von links nach rechts und rückwärtsrum, während sich dieser vertikal spiegelt. Die animation-direction: alternate-reverse gibt an, dass die Animation sich vor- und zurückspielen soll. Animation-timing-function sorgt für den linearen. also gleichbleibenden/flüssigen Ablauf. translateX() sorgt dafür, dass sich der Button von links nach rechts bewegt. scaleX() hingegen sorgt für die Spiegelung, wobei der negative Wert die Spiegelung an der X-Achse erzeugt.

Gute Nacht, Bobby Schrift

Der Abschließende Text „Gute Nacht, Bobby“ wurde mit einer Zoom-, Leucht- und Rotations-Funktion gestaltet. Wie schon zuvor erwähnt erzeugt scale() den Zoomeffekt. Für das Textleuchten ist text-shadow zuständig. rotate() sorgt für die Drehung des Textes. Der Unterschied bei dieser Textanimation liegt in der animation-timing-function. Hierbei setzt man cubic-bezier () ein um, einen Verzerrungseffekt zu erstellen.

#good_night_bobby{ /*Verabschiedung durch "Gute Nacht" Text Animation*/
  position: relative;
  bottom: 1500px;
  font-size: 30px;
  color: white;
  -webkit-animation: push_good_night 3s infinite;
  animation: push_good_night 3s infinite;
  animation-timing-function: cubic-bezier(.1,0,.7,1);
  outline: none;
}

  @-webkit-keyframes push_good_night {
   0% {
    transform: scale(1);
    text-shadow: 2px 3px 6px rgb(3, 246, 255);
  }
   20% {
    transform: scale(1.1) rotate(2deg);
  }                                                  
   40% {
    transform: scale(.97);
  }
   50% {
    text-shadow: 6px 6px 8px rgb(19, 236, 184);
 }
   60% {
    transform: scale(.99) rotate(-2deg);
 }
   80% {
    transform: scale(1.05);
 }
   100% {
    transform: scale(1);
    text-shadow: 2px 3px 6px rgb(135, 222, 241);
 }
 }

  @keyframes push_good_night {
   0% {
    transform: scale(1);
    text-shadow: 2px 3px 6px rgb(3, 246, 255);
  }
   20% {
   transform: scale(1.1) rotate(2deg);
  }                                                  
   40% {
   transform: scale(.97);
  }
   50% {
   text-shadow: 6px 6px 8px rgb(19, 236, 184);
}
   60% {
   transform: scale(.99) rotate(-2deg);
}
   80% {
   transform: scale(1.05);
}
   100% {
   transform: scale(1);
   text-shadow: 2px 3px 6px rgb(135, 222, 241);
}
}

JavaScript/jQuery

var name = "Snoopy" /*Variable für die Namensabfrage für die Begrüßung von Bobby*/

$(document).ready(function(){
/*Funktion, bei der bei einem Buttonklick bestimmte Objekte sichtbar oder ausgeblendet werden*/
$("#button_aufwecken").on("click", function() {  /*Button "Aufwecken"*/
    $(".story_start_scene").css({"visibility": "hidden"});
    $(".backgroundimage_livingroom").css({"visibility": "visible"}); 
    $("#hello_dog").css({"visibility": "visible"});
    $("#speak1").css({"visibility": "visible"});
    $("#button_park").css({"visibility": "visible"});
    $("#button_aufwecken").css({"visibility": "hidden"})
    $("#welcome_text").css({"visibility": "visible"});
    $("#name_text").css({"visibility": "visible"});
    $("form").css({"visibility": "visible"});
    
    $("#button_park").css({"-webkit-animation-play-state": "running"}); /*Animationen, die pausiert werden, werden hierbei zum Abspielen gebracht*/
    $("#welcome_text").css({"-webkit-animation-play-state": "running"});

    name = prompt("Bitte gib deinen Namen ein", "Snoopy");     /*Namensabfrage. Inspired by https://www.w3schools.com/jsref/met_win_prompt.asp*/
    console.log(name);

    if (name != null) {                                                                    
        document.getElementById("welcome_text").innerHTML =
        "Hallo " + name + "! Ich bin Bobby. Lass uns den Tag zusammen verbringen.";
      }

});

Um die Übergänge zwischen den einzelnen Szenen und Animationen möglich zu machen, wurde jQuery eingesetzt. Durch den Buttonklick werden Objekte, die in HTML5 auf „hidden“ gesetzt sind, sichtbar gemacht. Dafür nutzt man die $(“#button”).on(“click”, function() {}}); . Diese zeigt welche Objekte beim Buttonklick gezeigt werden und welche verschwinden sollen. Die Namensabfrage zwischen der ersten und der zweiten Szene erfolgte über JavaScript mit der promt() Methode.

Bobby JS
Bobby JS

Hierbei wurde eine Variable erstellt, das einen default Wert liefert, der in der promp() Abfrage und if-loop eingefügt ist. Es öffnet sich ein Pop-up Fenster bei dem die Aufforderung „Bitte gib deinen Namen ein“ und dem default Wert „Snoopy“ steht. Diese wurden zuvor definiert. Wenn der User seinen Namen eintippt, nimmt die p id=“welcome_text“ diesen entgegen und Bobby begrüßt den User mit „Hallo [Username]! Ich bin Bobby. Lass und den Tag zusammen verbringen“. Falls das Eingabefeld leer bleibt, begrüßt Bobby den User mit dem Namen null. Durch diese Funktion wird eine Bindung zum User aufgebaut.

Die Animationen, die mit Hilfe von transitions und keyframes in CSS3 erstellt wurden, wurden bei webkit-animation-play-state auf paused gesetzt. Der Grund dafür ist, dass bestimmte Funktionen wie animation-delay oder animation-duration ab der Start Szene anfangen zu zählen. Das war aber nicht die Intention. Es sollten alle Abläufe erst nach einem Buttonklick starten. So war das Problem z.B. bei dem zweiten Button „Lass und in den Park gehen“. Dieser wird nach 3 Sekunden eingeblendet. Wäre -webkit-animation-play-state auf running gesetzt, so hätte das Einblenden des Buttons nach 3 Sekunden nicht funktioniert, wenn man sich länger als 3 Sekunden in der Start Szene befunden hätte. Der Button wäre dann beim Szenenwechsel schon da und der Einblende Effekt wäre nicht sichtbar. Damit die einzelnen Animationen erst beim Buttonklick abspielen, muss man diese über jQuery bei -webkit-animation-play-state auf running setzen.

$("#hot_dog_text").css({"-webkit-animation-play-state": "running"});
$("#button_hot_dog").css({"-webkit-animation-play-state": "running"});

Besonderheiten

Eine Besonderheit ist die im Hintergrund eingesetzte Musik, um die Animation spannender zu gestalten und den User in eine angenehme Stimmung zu versetzen. Des Weiteren wurden so gut wie alle benutzen Objekte animiert. Es wurde versucht jedes Animationselement individuell zu gestalten, um verschiedene visuelle Effekte zu erzeugen. Die letzte Besonderheit ist, dass der letzte Button einen Neustart der Animation ermöglicht, falls man erneut das Story Telling durchspielen möchte.

Schwierigkeiten

Beim Erstellen der Animation traten zwei Probleme auf.

  1. Der animierte Sprechtext sollte ursprünglich abgetippt werden. Dafür wurde die step() Methode verwendet. Leider konnte ein Zeilenumbruch für die Animation nicht erstellt werden, da ansonsten der “abgetippte Text” nicht korrekt funktioniert hat wie er es sollte. Dieser hätte in die Sprechblase passen müssen. Daher wurde eine alternative Darstellung des Textes eingebaut.
  2. Die Hintergrundmusik wird manchmal in Google Chrome nicht abgespielt. Daher wird empfohlen sich die Animation in Microsoft Edge anzuschauen.

Dieser Beitrag ist im Studiengang Informationsmanagement an der Hochschule Hannover im Rahmen des Kurses Entwicklung von Multimediasystemen (Sommersemester 2021, Amy Linh Hoang,  Prof. Dr.-Ing. Steinberg) entstanden. Verwendete Techniken sind HTML5, CSS3 und JavaScript. Die besten Tutorials stellen wir Euch hier in den nächsten Wochen nach und nach vor.

Tutorial: Visual Graphic Novel Animation

Tutorial: Visual Graphic Novel Animation

Autori*n: Julia Karaschewski


Vollansicht: Visual Graphic Novel Animation auf Codepen.io
Quellcodeansicht: Visual Graphic Novel Animation auf Codepen.io
ZIP-Datei zum Download (direkt von Codepen.io)

Das Konzept

Die Idee der Animation ist, ein erheiterndes, kleines Visual Graphic Novel zu erstellen, durch das der User mit visuellen Effekten durchgeführt wird.

Das Ziel ist, den User von Anfang bis Ende durch mehrere kleine Animationen zu führen, während er Interaktionen ausführt und Feedback zu den ausgeführten Aktionen erhält. Das Feedback besteht ebenfalls aus visuellen Effekten, sodass der User jederzeit weiß, wo und in welcher Ebene er sich befindet.

Die Führung durch das Visual Graphic Novel erfolgt visuell durch verschieden aufleuchtende Buttons. Durch sich farblich (türkis) abgrenzende Umrandungen der Buttons wird der User zu den gewünschten Aktionen gelotst, da diese am meisten auffallen (über Bewegung und Farbe).

Das Visual Graphic Novel besteht aus zwei Szenen, die der Nutzer frei wählen kann. Die Reihenfolge der Auswahl hat dabei keine Auswirkungen.

Inhaltsverzeichnis des Beitrags

Aufbau des Visual Graphic Novels

Es gibt 4 Ebenen:

  • 1. Start-Bildschirm
  • 2. Szenen-Wahl
  • 3. Home-Scene
  • 3. Outdoor-Scene
  • 4. End-Bildschirm

Die erste Ebene, der Startbildschirm, dient dem User dazu, das Visual Graphic Novel zu starten.
Auf der zweiten Ebene kann der User eine Szene (Home- oder Outdoor-Szene) auswählen, ohne jedoch das Szenenbild vorher zu sehen. Hier liest er nur den Text der Entscheidungsmöglichkeiten, was auch einen kleinen Überraschungseffekt bei der Auswahl geben soll.
Auf der dritten Ebene kann der User dann zwischen den beiden Szenen hin und her springen, so oft er möchte. Um das ganze unterhaltsamer zu machen, spricht die Figur einen Text. Die Sprechblase wiederholt sich hierbei unendlich oft, sodass der User den Text gut lesen kann, ungeachtete der Lesegeschwindigkeit.
Die vierte Ebene ist der Endbildschirm, wo sich ein “Thanks for playing” (DE: “Danke für das Spielen”) bei dem User verabschiedet. Auf dieser Ebene hat der User die Möglichkeit, das Visual Graphic Novel erneut zu starten.

Verwendete Programmiersprachen:

Die ganze Animation wurde auf Codepen erstellt. Für die Erstellung der einzelnen Animation/-en wurden verwendet:

    • HTML5
    • CSS3
    • JavaScript & JQuery

Um JQuery zu verwenden, muss dies bei den Codepen-Einstellungen erst mit diesem Link https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js importiert werden, wie auf der folgenden Abbildung:

Eigene Abbildung: Bei Codepen JQuery importieren
Eigene Abbildung: Bei Codepen JQuery importieren

Besonderheiten

Die Besonderheiten bei dem Visual Graphic Novel sind klein, haben jedoch einen großen Effekt und Einfluss.
Zunächst ist das Design schlicht gehalten, bzw. der Hintergrund und die Hauptfarbe der Buttons. Dadurch wird die Aufmerksamkeit des Users auf die Szenen(-bilder) und die einzelnen, visuellen Effekte gelenkt.

Die Effekte der Klasse ‘hint

Die Klasse ‘hint’ hat das Ziel, den User durch das Visual Graphic Novel zu führen. Der visuelle Effekt ist ein türkis-farbenes Pulsieren (in CSS definiert). Beim Startbildschirm (Ebene 1) wird die Aufmerksamkeit des Users somit vor allem auf den Start-Button gelenkt. Danach (Ebene 2) wird der Effekt “verschoben” und ist nun nur auf der Szenen-Auswahl zu sehen, damit der User weiß, dass er sich nun für eine der beiden Optionen entscheiden soll. Ist nun eine Szene ausgewählt (Ebene 3), wird der pulsierende Farb-Effekt auf die nicht ausgewählte Option verschoben, sowie den Stop-Button. Damit weiß der User zum Einen, dass die andere Option noch ausgewählt werden kann, und zum Anderen, dass jederzeit das Spiel nun beendet werden kann. Wird nun auf den Stop-Button geklickt, wird der Farb-Effekt erneut auf den Start-Button geschoben, damit der User nun die Möglichkeit erkennt, erneut auf Start zu klicken. Die Steuerung, wann der Farb-Effekt, bzw. die Klasse ‘hint’ wo hin verschoben werden soll, wird mit Hilfe der Buttons in JavaScript festgelegt. Der Effekt selbst wird mit CSS erstellt, mehr dazu unter dem Abschnitt Visuelle Effekte.

Die Figur und Objekte

Die Figur ist nicht nur eine Dekoration, sondern erfüllt auch einen Zweck: Ein Feedback an den User. Das Feedback ist simpel: Wurde sich nun für eine Szene entschieden, taucht eine Sprechblase von der Figur auf. Damit wird dem User gezeigt, dass die Szenen-Auswahl durchgeführt wurde und etwas passiert ist. Dabei wird der gesprochene Text in der Sprechblase unendlich oft wiederholt, damit der User jederzeit den Text erneut und so oft er will lesen kann. Des Weiteren erheitert der gesprochene Text der Figur (hoffentlich!) den User und hinterlässt somit einen positiven Eindruck. Die Figur wird in CSS mit der Klasse ‘figure’ definiert.
Die anderen Objekte / Graphiken dienen hier der Dekoration und erhöhen den Spaß-Effekt beim Umschalten der Szenen.

Der Wegweiser

Der Wegweiser (eine SVG-Graphik), der einzig allein in Ebene 2 auftaucht, besitzt eine wichtige Funktion: Das Wegweisen. Da Graphiken, bzw. Bilder, meist mehr für sich sprechen als Text, wird dem User vor dem Lesen der Optionen bereits gezeigt, dass nun eine Entscheidung auf ihn zukommt. Ein Wegweiser ist hierbei ein allgemein bekanntes Symbol, dass von dem User nicht falsch verstanden werden kann, und dabei schneller auffällt als der Text in den Optionen. Der Wegweiser wird mit der ID ‘#signpost’ in CSS definiert und mit Hilfe von JavaScript gesteuert. Mehr dazu unter dem Abschnitt Buttons & Option.

Grundbausteine

Da es in dem Visual Graphic Novel viele verschiedene Elemente gibt, die von JavaScript gesteuert werden und auf verschiedenen Instanzen auftauchen sollen, schließen verschiedene div-Container diese ein.

Body

body {
background-size:cover;
font-family: "Comic Sans MS", Helvetica, sans-serif;
border: 1px dashed #ffffff;
border-radius: 30%;
box-shadow:0px 0px 350px; #000000;;
background: radial-gradient(#28427B,#14213D, #0d001f);
justify-content:center;
background-position: center;

Im ‘body’ wird alles Wichtige wie background-size, background-color, sowie die Inhaltsplatzierung innerhalb des ‘bodys’ und die Schriftart definiert. Die border- und box-shadow-Einstellungen schaffen hierbei eine Abgrenzung von dem restlichen Browserfenster und begrenzen die Darstellungsoberfläche des Visual Graphic Novels.

Main-Content-Container

.main-content {
max-width: 700 px;
margin: 0em auto 0;
text-align: center;
max-height:500px;
overflow: hidden;

Der div-Container mit der Klasse ‘main-content’ ist dafür da, um den gesamten Inhalt (also alle Graphiken) als eine Einheit zu platzieren und sie durch JavaScript und JQuery zu steuern, d.h. einen Start-Bildschirm zu erschaffen. Damit kann der gesamte Inhalt in ‘main-content‘ mit einem Klick aus- und eingeblendet werden, wenn einer der Buttons gedrückt wird. Das geschieht dadurch, dass dieser Klasse eine Id ‘gamestop’ und ‘gamestart’ (definiert in CSS) mit der Eigenschaft ‘visibility:hidden’ zugewiesen und wieder entfernt wird.

<!-- die Id wird in JS genutzt, um einen Startbildschirm zu erschaffen --!>
<div id="gamestart" class="main-content"> <!-- wird genutzt, um den main-content zu steuern und zu positionieren -->
$(".start-button").on("click", function() {
$(".main-content").removeAttr("id", "gamestart");
$(".stop-button").on("click", function() {
$(".main-content").attr("id", "gamestop");

 

Mehr zu den Buttons später.

Illustration-Container

.illustration {
position: relative;
align-self: flex-end;
marfin: auto;
height: 250px;
width: 250px;

Der div-Container ‘illustration’ enthält alle Graphiken, bzw. SVG-Graphiken, und fixiert diese. Da nicht alle SVG-Graphiken eine geeignete Proportionalität besitzen, um zusammen dargestellt zu werden, hilft das Fixieren auch dabei, um sie gegenseitig aufeinander abzustimmen.

Person-type: Home-Body & Outdoor-Person

<div class="person-type home-body active"> <!-- hier ist die home-scene mit dazugehörigen Objekten -->
<div class="scenery">
<img src="https://image.freepik.com/free-vector/living-room-interior-with-panoramic-window-night-time_33099-1735.jpg" class="backgroundimg"/>
</div>
<div class="background.items">
<img src="https://image.flaticon.com/icons/svg/214/214283.svg" width="100px" height="400px"/>
</div>
<div class="foreground-items">
>img src="http://image.flatcon.com/icons/svg/198/198916.svg" width="65px" style="margin-left:-10%"/>
<img src="Http://image.flaticon.com/icons/svg/3145/3145435.svg" width="65px" style="padding-left:30%;"/>
</div>
</div>

Mit der Klasse ‘person-type‘ werden in CSS alle Kindelemente dieser Klasse definiert und in JavaScript zwischen den Szenen hin- und hergewechselt, wenn die jeweilige Option ausgewählt wird.

.person-type > div {
transform: scale(0);
opacity:0;
}
.person-type.active > div {
transform: scale(1);
opacity: 1;

Durch ‘person-type > div’ werden alle Kindelemente der Klasse ‘person-type‘ ausgewählt. Es gibt ‘person-type‘ einmal für die Home-Szene (inklusive der dazugehörigen Graphiken) und dann für die Outdoor-Szene. Wenn eine der Szenen ausgewählt wird, wird diese Szene durch ‘person-type.active’ (definiert in CSS) nach “vorne geschoben‘(transform:scale (1))’ und durch ‘opacity:1’ sichtbar gemacht. Die andere Szene wird durch ‘person-type > div’ nach “hinten geschoben ‘(transform:scale(0))’ und mit ‘opacity:0’ unsichtbar gemacht. Dadurch können beide Szenen an den gleichen Platz im Container geschoben werden, ohne dass sie sich gegenseitig verdrängen. Die Szenenauswahl wird durch den Button mit JavaScript ausgelöst. Darauf wird später in Buttons & Option noch mehr eingegangen.

Container Scenery & Backgroundimg

Der div-Container ‘scenery’ umfasst das Szenenbild (für jeweils die Home- und Outdoor-Szene). Mit dieser Klasse wird der Einblendungseffekt / Übergangseffekt beim Szenenwechsel in CSS mit ‘transition:’ definiert.

<div class="scenery">
<img src="https://image.freepik.com/free-vector/living-room-interior-with-panoramic-window-night-time_33099-1735.jpg" class="backgroundimg"/>
</div>

Der div-Container ‘backgroundimg’ wird in CSS definiert und erfüllt den Zweck, die Hintergrundbilder der Szenen auf die gleiche Größe zu skalieren und dem Bild mit ‘border-radius’ und ‘box-shadow’ eine Form und einen visuellen Tiefen-Effekt zu geben.

.scenery 7
transition: all 200ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
z-index: -2;
0/* Styled die Hintergrundbilder der Scenen */
.backgroundimg7
border-radius:50%;
margin-left:-73%;
width:626px;
height: 3356px;
box-shadow: 0px 0px 15px #000000;

Foreground-items Container

<div class="foreground-items">
<img src="https://image.flaticon.com/icons/svg/198/198916.svg" width="65px" style="margin-left:-10%;"/>
<img src="https://image.flaticon.com/icons/svg/3145/3145435.svg" width="65px" style="padding-left:30%;"/>
</div>

Der ‘foreground-items’ div-Container beinhaltet die Graphiken, die sich in den beiden Szenen jeweils weiter vorne befinden und bei einem Szenenwechsel später eingeblendet werden als die Graphik im Hintergrund und das Hintergrundbild.

.forground-items {
transition: all 300ms cubuic-bezier(0.68, -0,55, 0.265, 1.55) 200ms;
margin-top:100%;
}

Mit ‘transition:’ wird der Einblendungseffekt / Übergangseffekt dieser Objekte beim Szenenwechsel festgelegt.

Background-items Container

Der div-Container mit der Klasse “background-items” beinhaltet die eine Graphik (jeweils in beiden Szenen), die zu einem früheren Zeitpunkt als die Graphiken in dem ‘foreground-items container’ in der ausgewählten Szene auftauchen. Dies ist in CSS mit ‘transition:’ definiert, wie in der folgenden Abbildung zu sehen ist.

.backgrouznd-items {
transition: all 200ms cubic-bezier(0.68, -0.55, 0.265, 1.55) 100ms;
top: 23px;
}

Option-Wrapper

Der div-Container ‘option-wrapper’ beinhaltet beide Szenen-Optionen und umschließt diese, damit sie zusammen in einem Button erscheinen können. Außerdem wird mit dieser Klasse der div-Container per JavaScript “anvisiert”, bzw. mit einem Leuchteffekt versehen, damit dieser zum geeigneten Augenblick die Aufmerksamkeit des Users bekommt. Zu den Buttons unter Buttons und zu dem Leucht-Effekt unter Visuelle Effekte mehr.

<div class="option-wrapper">
<aclass="option active wobble-vertical-on-hover homeoption hint" data-option="home">
I'm gonna read a nice book and stay in. </a>
<a class="option wobble-vertical-on-hover outdooroption hint" data-option="outdoor">
I'm gonna explore the wide world and beyond! </a>
</div>

Buttons & Option

Die Klasse ‘option’ ist allen Buttons zugeteilt. Also jeweils dem Start- und Stop-Button sowie beiden Szenen-Optionen. Die Klasse ‘option’ regelt mit ‘transition:’ in CSS den Übergang der ausgewählten Option sowie den Style der einzelnen Optionen. Somit grenzen sich z.B. die Outdoor-Szene und Home-Szene innerhalb des ‘Option-Wrappers’ voneinander ab und erscheinen als zwei eigene Buttons. Mit ‘cursor’ wird zudem der Cursor über dem Button definiert.
Die Klasse ‘active’ definiert, wie die ausgewählte Option aussieht. Durch die Klasse ‘active’ verändert sich die Hintergrundfarbe und Schriftfarbe des Buttons (gelber Hintergrund, schwarze Schrift), wenn dieser angeklickt wird.

.option {
transition: all 200ms ease;
padding: 10px 10px 8px;
width: 50%;
border-radius: 50px;
cursor: pointer;
color: #ffffff;
} /* gibt aktiver Option style */
.active{
background: #FFB200;
pointer-events: none;
color: '000000;
}
.option:hover: {
text-decoration: none;
}

Bei der Szenenauswahl wird der ‘person-type’ der jeweiligen Option angesprochen, der bei beiden Szenen unterschiedlich ist und in der JavaScript-Funktion jeweils definiert ist, bzw. welche Elemente dazugehören. Der Wechsel der Optionen, sowie die Zuweisung der Klasse ‘active’, geschieht mit folgender Funktion in JavaScript:

$(".option").on("click", function() {
$(".person-type").removeClass(active");
$(".option").removeClass("active");
$(this).addClass("active");
var type = $(this).data("option");
console.log($(type));

Die beiden Person-Types (‘data-option’ in HTML) der Optionen, also ‘person-type home’ und ‘person-type outdoor’ in JavaScript, bestimmen, welche weiteren Grafiken / Objekte dargestellt werden. Dies ist definiert als if und else if (untere Abbildung) in der Funktion “click”, (obere Abbildung). Wird also die ‘option’ mit dem ‘type == “home”‘ (in HTML data-option) angeklickt, wird der Klasse ‘home-body’ die Klasse ‘active’ zugewiesen. Desweiteren werden damit alle benötigten Elemente für diese Szene eingeblendet, sowie nicht benötigte ausgeblendet, mit folgender Funktion:

setTimeout(function() {
if (type === "home") {
$(".home-body").addClass("active");
$("#signpost").css({"visibility": "hidden"});
$("#bubbletoggle1").css({"visibility": "visible"});
// Hier der Wechsel der Sprachblasen
$(".bubble2").hidden();
$(".bubble1").show();
$".stop-button").addClass("hint");
$(".homeoption").removeClass("hint");
}
<div class="option-wrapper ">
<a class="option active wobble-vertical-on-hover homeoption hint" data-option="home">
I'm gonna read a nice book and stay in.</a>
<a class="option wobble-vertical-on-hover outdooroption hint" data-option="outdoor">
I'm gonna explore the wide world and beyond! </a>
</div>

Der ‘Signpost’ ist eine Grafik, die in Ebene 2 eingeblendet wird, hier jedoch ausgeblendet werden soll. Mit der Klasse ‘hint’ wird eine farbliche (türkis-farbene) Umrandung um den Stop-Button gesetzt, damit der User darauf aufmerksam gemacht wird, dass er das Visual Graphic Novel ab jetzt beenden kann. Gleichzeitig wird diese Klasse der jetzt ausgewählten Option entzogen, da die Aufmerksamkeit des Users bereits auf diesem Button liegt. Die ID ‘#bubbletoggle1’ ist in einem anderen Abschnitt erklärt.

Der Start- und Stop-Button

Der Start- und Stop-Button dient dazu, einen Start-Bildschirm und einen End-Bildschirm zu erschaffen, sowie dem User die Möglichkeit zu geben, dass Visual Graphic Novel jederzeit zu verlassen. Dazu wird den beiden Buttons die Klasse ‘active’ gegeben, damit diese genauso wie die Szenen-Options reagieren (weiter oben beschrieben). Ebenso wird zum Zwecke der User-Lenkung und User-Aufmerksamkeit die Klasse ‘hint’ vergeben, die farbliche Effekte (türkis-farbene Umrandung) vergibt.

<span class="hint">
<div class="button hint" style="">
<a class="Start-button option wobble-veretical-on-hover hint">Star !</a>
<a class="stop-button option wobble-vertical-on-hover">Stop playing !</a>
</div>
</span>

Der Style der beiden Buttons wird in CSS festgelegt. Dafür wird die Klasse ‘buttons’ vergeben. Der Zweck der Klasse ‘hint’ wird im Abschnitt ‘Besonderheiten’ und die CSS-Definition unter Visuelle Effekte  mehr erläutert.

.button{
display: flex;
position: center;
margin:0en auto;
background: rgba(255,255,255,0.25);
border-radius: 50px;
padding: 5px;
max-width: 300px;
font-size: 15px;
line-height: 1.2;
} /* Wird genutzt, um per JS zu steuern, wann der Inhalt auftaucht, wenn die buttons gedrückt werden*/
#gamestart{
visibility:hidden;
}
#gamestop{
visibility:hidden;
}/* Danke-Text am Ende des Spiels */

Die ID ‘#gamestart{visibility:hidden;}’ und ‘#gamestop{visibility:hidden;}’ werden in JavaScript dafür verwendet, um beim Klicken der Buttons den ‘main-content’ einzublenden und beim Drücken des Stop-Buttons den ‘main-content’ auszublenden. Zur Übersichtlichkeit der Steuerung in JavaScript wurden also die beiden ID’s jeweils einzeln in CSS definiert, obwohl sie die gleichen Attributwerte besitzen. Die beiden Funktionen für den Start-Button und den Stop-Button sehen wie folgt aus:

$(".star-button").on("click", function() {
$(".main-content").removeAttr("id", "gamestart");
$(".thanks").css({"visibility": "hidden"});
$("#signpost").css({"visibility": "visible"});
// "hint" gibt dem User Hinweise, wo hingeklickt werde
$(".button").removeClass("hint");
$(".start-button").removeClass("hint");
$(".option-wrapper").addClass("hint");
});
//Funktion und eizelne Aktionen, die ausgeführt werde
$(".stop-button").on("click", function() {
$(".mnain-content").attr("id", "gamestop");
$(".bubble").hide();
$("#signpost").removeAttr("style", "visible");
$(".thanks").css({"visibility": "visible"});
$(".button").addClass("hint");
// wenn der stop-button geklickt wird, muss das lightni
$(".stop-button").removeClass("hint");
//hiermit wird die Klasse "hint" den beiden Scenen-Opt
$(".homeoption").addClass("hint");
$(":outdooroption").addClass("hint");
});

Die beiden Funktionen definieren auch, was beim Drücken des Buttons eingeblendet und ausgeblendet werden soll. Dies geschieht durch die Klassen und ID’s, die in CSS definiert sind (wenige Ausnahmen befinden sich als Attributwert in HTML).

Sprechblase

Die Sprechblase der Figur in beiden Szenen hat jeweils einen verschiedenen Text. Aus diesem Grund wurden einmal die Klassen ‘bubble1’, ‘bubbletoggle1’, ‘bubble2’, ‘bubbletoggle2’ vergeben und an beide jeweils die Klassen ‘bubble’ und ‘anim-typewriter’.

<div id="bubbletoggle1" class="buble1" style="visibility:hidden;">
<a lass="bubble bubble1 anim-typewriter "> Ah! That was a good desicion! Now a nice cup of tea...would you set the kettle on? </a>
</div>
<div id="bubbletoggle2" class="bubble2" style="visibilioty:hidden;">
<a class="bubble bubble2 anim-typewriter">What a lovely day, isn't it? Ans such charming strangeers visiting!</a>
</div>

Die Klasse bubble

Die Klasse ‘bubble’ ist dafür da, um die Sprechblase per CSS zu stylen. Die CSS-Attributwerte von ‘min-width’, ‘max-width’, ‘max-height’ sind hierbei besonders wichtig, da sie bestimmen, wie groß die Sprechblase werden kann, wenn der Text auftaucht. Je nachdem, wie lang der Text ist, muss natürlich auch die ‘min-width’, ‘max-width’ und ‘max-height’ angepasst werden. Wäre ‘max-height’ in diesem Fall kleiner als die festgelegten ’50px’, würde nicht der ganze Text auftauchen können.

.bubble {
z-index:4;
min-width: 0px;
max-width: 210px;
max-height: 50px;
font-size: 15px;
line-height: 1.2;
display: flex;
text-align: center;
position: absolute;
border-radius: 50px;
margin-right:auto;
margin-left: auto;
left: 85%;
righht:0;
top:50%;
padding:1px;

Des Weiteren ist die Klasse ‘bubble’ auch dafür da, um mit dem Stop-Button die Sprechblase an sich vollends auszublenden (siehe Abschnitt Buttons.

Die Klasse anim-typewriter

Diese Klasse ist in CSS definiert. Sie sorgt für den Effekt der auftauchenden Sprechblase, wo der Text nach und nach erscheint.

.anim-typewriter{
animation: typing 7s steps(8,end) intinite normal both;
-webkit-animation-duration: 7s;
}
@keyframes typing{
from{width: 0;}
to{width: 20em;}

Wichtig hierbei ist der Attributwert infinite, der leider etwas schwierig zu handhaben ist. Darauf wird in “bubbletoggle: Der unendliche Text” weiter eingegangen.

Die Klassen bubble1 und bubble2

Die Klassen ‘bubble1’ und ‘bubble2’ werden in JavaScript verwendet, um die jeweilige Sprechblase in der richtigen Szene einzublenden und auszublenden. Die Klasse ‘bubble1’ ist hierbei für die Home-Szene, ‘bubble2’ für die Outdoor-Szene. Aus- und eingeblendet wird die Klasse in JavaScript mit ‘$(.bubble1).hide()’ und ‘$(.bubble1).show()’. Da beide Szenen auch unterschiedlich helle Hintergründe haben, wird mit dieser Klasse in CSS auch die Farbe der Sprechblasen angepasst.

.bubble.bubble1{
background:rgba(255, 255, 255, 0.30);
padding: 6px 6px 4px;
}
.bubble.bubble2{
background:rgba(26, 22, 95, 0.55);
padding: 6px 6px 4px;

Bubbletoggle: Der unendliche Text

Eigene Abbildung: Der unendliche Text der Sprechblase
Eigene Abbildung: Der unendliche Text der Sprechblase

Der Text in den Sprechblasen wird unendlich wiederholt, um dem User das Lesen zu ermöglichen und zu vereinfachen, wann auch immer die Szene ausgewählt wird und unabhängig davon, wie schnell die Lesegeschwindigkeit des Users ist. Die Klassen ‘bubbletoggle1’ und ‘bubbletoggle2’ werden dafür verwendet, um den Text der Sprechblasen durch JavaScript (und CSS) in HTML mit ‘visibility:hidden’ und ‘visibility:visible’ unsichtbar und sichtbar zu machen. Dies ist sehr ähnlich wie das, was die Klassen ‘bubble’ und ‘bubble1’ (oder bubble2) schon machen. Hierbei gibt es aber ein Problem: Unendlich heißt unendlich. Die einzige Möglichkeit in diesem Fall, den sich unendlich wiederholenden Text in der Sprechblase unsichtbar zu machen, ist über eine extra ID und ein dazugehöriger Style-Attributwert in HTML, der in JavaScript gezielt angesprochen wird. Damit wird keine andere Klasse beeinflusst oder verändert, was später zu Komplikationen führen könnte. In JavaScript sieht das dann folgendermaßen aus: $(“bubbletoggle1″).css({visibility:”visible”}); für die Home-Szene und für die Outdoor-Szene $(“#bubbletoggle2”).css({“visibility:”visible”}); . In dem Abschnitt Buttons ist die gesamte Funktion erklärt und zu sehen.

<div id="bubbletoggle1" class="bubble1" style="visibility:hidden;">
<a class="bubble bubble1 anim-typewriter ">Ah! That was a good decision! Now a nice cup of tea...would you set the kettle on?</a>
</div>
<div id="bubbletoggle2" class="bubble2" style="visibility:hidden;">
<a class="bubble bubble2 anim-typewriter">What a lovely day, isn't it? And such charming strangers visiting!</a>
</div>

Visuelle Effekte

Die Klasse hint

Eigene Abbildung: Klasse hint beim Start-Button und Stop-Button
Eigene Abbildung: Klasse hint beim Start-Button und Stop-Button

Die User-Lenkung durch die Klasse ‘hint’ wurde vom Zweck und der Funktion her im Abschnitt Besonderheiten erläutert. Der Licht-Pulse-Effekt wird in CSS erstellt und definiert.

.hint{
-moz-border-radius: 200px/200px;
-webkit-border-radius: 200px 200px;
border-radius: 200px/ 200px;;
border:1px solid #52c7aa;
width: auto;
height:auto;
outline:none;
-webkit-animation-name: hintPulse;
-webkit-animation-duration: 2s;
-webkit-animation-interation-count: infinite;
}
@-webkit-keyframe hintPulse {
from { -webkit-box-shadow: 0 0 3px #0c2720; }
50% { -webkit-box-shado: 0 0 21px #52c7aa; }
to {-webkit-box-shadow: 0 0 12px #246E5B; }
}

Die Dauer der Animation ist mit ‘-webkit-animation-duration:2s;’ festgelegt. Der Farbwechsel (oder auch die Intensität) im Verlauf der Animation ist durch die ‘@-webkit-keyframes hintpulse’ definiert. Dabei wurden verschiedene Abstufungen des original Farbtons für die Intensität verwendet.

Der Wobble-Effekt

Der Wobble-Effekt wird durch die Klasse ‘wobble-vertical-on-hover’ in CSS definiert. Beim Hovern über ein Element mit dieser Klasse “wobbelt” jenes. Damit weiß der User, dass mit diesem Element interagiert werden kann. Die Definition und Animation ist in CSS festgelegt.

.wobble-vertical-on-hover:hover, .wobble-vertical-on-hover:focus, .wobble-verical-on-hover:active {
-webkit-animation-name: wobble-vertical-on-hover;
animation-name: wobble-vertical-on-hover;
-webkit-animation-duration: 1s;
animation-duration: 1.5s;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: 1;
-webkit-animation-interation-count: 1;
animation-interation-count: infinite;
} /* Bewegungen der Animation wobble, aufgeteilt nach Prozent */
@keyframes wobble-vertical-on-hover {
16.65% {-webkit-transform: translateY(8px);transform: translateY(8px);}
33.3% {-webkit-transform: translateY(-6px);transform: translateY(-6px);}
49.95% {-webkit-transform: translateY(4px);transform: translateY(4px);}
66.6% {-webkit-transform: translateY(-2px);transform: translateY(-2px);}
83.25% {-webkit-transform: translateY(1px);transform: translateY(1px);}
100% {-webkit-transform: translateY(0);transform: translateY(0);}
}

Mit der Klasse ‘wobble-vertical-on-hover’ und zusätzlich ‘:hover’, ‘:focus’, ‘:active’ wird festgelegt, dass sowohl beim hover, als auch so lange die Maus darauf ist der Effekt gilt. Mit ‘animation-iteration-count:infinite’ wird dieser Effekt so lange wiederholt, bis weder ‘hover’,’active’ noch ‘focus’ für dieses Element gilt, bzw. es dadurch nicht mehr ausgelöst wird. Mit ‘@keyframes wobble-vertical-on-hover’ wird die Bewegung nach oben und unten definiert/ festgelegt; also die Vektoren, wo sich das Element mit dieser Klasse an einem bestimmten Prozent(-punkt) der Bewegung befinden muss.

Und nun sind alle wichtigen Code-Abschnitte erklärt. Falls das Interesse an dem Quellcode (inklusive Kommentare darin!) vorhanden ist, muss nur wieder nach zum Seitenanfang gesprungen, die ZIP-Datei heruntergeladen und entpackt werden!


Dieser Beitrag ist im Studiengang Informationsmanagement an der Hochschule Hannover im Rahmen des Kurses Entwicklung von Multimediasystemen (Sommersemester 2020, Amy Linh Hoang,  Prof. Dr.-Ing. Steinberg) entstanden. Verwendete Techniken sind HTML5, CSS3 und JavaScript.

Die besten Tutorials stellen wir Euch hier in den nächsten Wochen nach und nach vor.

InfoInMotion2019: Das WebLab stellt sich vor

Das WebLab bei InfoInMotion2019

Am Freitag, 11. Oktober 2019 ist es soweit:

Unsere Veranstaltung “InfoInMotion2019: Information in Transformation” findet im DesignCenter auf der Expo Plaza 2 statt. Auch das WebLab ist dabei und stellt einige seiner besten, studentischen Arbeiten vor.

Mehr zu InfoInMotion2019 samt Online-Anmeldung und Programm finden Sie auf der Website des Studiengangs Informationsmanagement.

Wir freuen uns auf ihren Besuch!
🙂

BestOf Bachelor: Interaktives Storytelling zum Bauhaus100 Jubiläum

Storytelling Bauhaus100 von Amy Hoang

Amy Linh Hoang hat ihre sehr gute Bachelorarbeit im Studiengang Informationsmanagement mit dem Titel “Konzeption und Realisierung eines interaktiven Storytelling anlässlich des Bauhausjubiläums” abgeschlossen und ein sehenswertes, interaktives Storytelling mittels JavaScript, CSS3 und HTML5 erstellt. Der Titel des Storytellings lautet “Oscar Schlemmers Weg zum Bauhaus“. Amys Bachelorarbeit ist als Kooperation der Abteilungen “Information und Kommunikation” und “Design und Medien” entstanden. Anlass für ihr interaktives Storytelling ist das Bauhaus100 Jubiläum 2019, zu dem es neben weiteren interaktiven Angeboten gesammelt bereitgestellt wird.

Hier geht’s zu Amys Storytelling.

Viel Spaß beim Anschauen!