[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"9_t0YFtO844PW3-iCfPxRTbw8yv0-2zzu2bChZFenjo":3,"btz8hO-MXSFLpybqvfjYVBre4OvrEJO1wFySe3Zmv-s":49,"xv_KU_ykLaieq3iKd2NpYKq_AnuvNjKgvSfeSihnkRU":75,"3Q3-qVcZ2q_-Lkl8FdpNt8k840PY1Zj1AVUrnSTunJA":193,"_apollo:default":235},{"menu":4},{"__typename":5,"id":6,"name":7,"items":8},"Menu","nuxt-main-menu","Nuxt Hauptmenü",[9,24,29,34,39,44],{"__typename":10,"id":11,"title":12,"description":13,"url":14,"langcode":15,"internal":20,"expanded":21,"attributes":22},"MenuItem","9ffc5019-cbd8-4b2e-8eb7-9feae486d4a1","Blog",null,"/know-how",{"__typename":16,"id":17,"name":18,"direction":19},"Language","de","German","ltr",true,false,{"__typename":23,"class":13},"MenuItemAttributes",{"__typename":10,"id":25,"title":26,"description":13,"url":27,"langcode":15,"internal":20,"expanded":21,"attributes":28},"1c7a5430-8a42-4b24-9544-252adabc2f4c","Projekte","/projekte",{"__typename":23,"class":13},{"__typename":10,"id":30,"title":31,"description":13,"url":32,"langcode":15,"internal":20,"expanded":21,"attributes":33},"9c4feedc-79e4-4fbf-b68c-065f33ebfe4c","Sparring","/workshop-ux-sparring-fuer-unternehmen",{"__typename":23,"class":13},{"__typename":10,"id":35,"title":36,"description":13,"url":37,"langcode":15,"internal":20,"expanded":21,"attributes":38},"3b77a27b-272a-489f-843e-53e23ed07741","Trainings","/liechtenecker-ux-academy",{"__typename":23,"class":13},{"__typename":10,"id":40,"title":41,"description":13,"url":42,"langcode":15,"internal":20,"expanded":21,"attributes":43},"ce0bb82b-e1ee-4036-be95-f693a62e9f4a","Über uns","/about",{"__typename":23,"class":13},{"__typename":10,"id":45,"title":46,"description":13,"url":47,"langcode":15,"internal":20,"expanded":21,"attributes":48},"04a19381-81a9-4694-8653-182d8855d2b5","Kontakt","/kontakt",{"__typename":23,"class":13},{"menu":50},{"__typename":5,"id":51,"name":52,"items":53},"footer","Fußzeile",[54,60,65,70],{"__typename":10,"id":55,"title":56,"description":13,"url":57,"langcode":58,"internal":20,"expanded":21,"attributes":59},"e2873307-b50a-4aab-b6b2-1950fd99c72e","Impressum","/impressum",{"__typename":16,"id":17,"name":18,"direction":19},{"__typename":23,"class":13},{"__typename":10,"id":61,"title":62,"description":13,"url":63,"langcode":58,"internal":20,"expanded":21,"attributes":64},"2cd9b7c9-142a-4ea3-b898-a0952c54a195","Datenschutz","/datenschutz",{"__typename":23,"class":13},{"__typename":10,"id":66,"title":67,"description":13,"url":68,"langcode":58,"internal":20,"expanded":21,"attributes":69},"a5effba3-5a8c-4125-8d78-0cdba09824db","AGB","/agb",{"__typename":23,"class":13},{"__typename":10,"id":71,"title":72,"description":13,"url":73,"langcode":58,"internal":21,"expanded":21,"attributes":74},"114bf071-bdbb-44cf-85c1-69e9d9e0777d","Newsletter","https://liechtenecker.at/newsletter-subscribe",{"__typename":23,"class":13},{"route":76},{"__typename":77,"entity":78},"RouteInternal",{"__typename":79,"id":80,"title":81,"changed":82,"created":88,"langcode":91,"path":92,"promote":21,"status":20,"sticky":21,"metatag":93,"postCategory":117,"postContentElements":13,"evergreen":13,"tags":142,"postWpBody":160,"wpHeaderImage":164,"wpHeaderImageOld":13,"wpHeaderImageOldSmall":13,"wpOgImage":177,"wpPromotedTeaserImage":13,"wpShareDescription":13,"wpShareTitle":13,"wpTeaserText":163,"wpYoastHead":186,"author":187},"NodeWpPost","737","Angular Dynamic Page Transitions",{"__typename":83,"timestamp":84,"timezone":85,"offset":86,"time":87},"DateTime",1732624917,"UTC","+00:00","2024-11-26T12:41:57+00:00",{"__typename":83,"timestamp":89,"timezone":85,"offset":86,"time":90},1680000072,"2023-03-28T10:41:12+00:00",{"__typename":16,"id":17,"name":18,"direction":19},"/blog/angular-dynamic-page-transitions",[94,101,108,113],{"__typename":95,"tag":96,"attributes":97},"MetaTagValue","meta",{"__typename":98,"name":99,"content":100},"MetaTagValueAttributes","title","Angular Dynamic Page Transitions | Liechtenecker UX Design Studio",{"__typename":102,"tag":103,"attributes":104},"MetaTagLink","link",{"__typename":105,"href":106,"hreflang":13,"rel":107,"media":13,"sizes":13,"type":13},"MetaTagLinkAttributes","http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/blog/angular-dynamic-page-transitions","canonical",{"__typename":109,"tag":96,"attributes":110},"MetaTagProperty",{"__typename":111,"property":112,"content":81},"MetaTagPropertyAttributes","og:title",{"__typename":109,"tag":96,"attributes":114},{"__typename":111,"property":115,"content":116},"og:image","http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/sites/default/files/styles/meta_og_image/public/wp-migration/wordpress-media-image/2023/03/BLOG_ANGULAR-DYNAMIC-%E2%80%A8PAGE-TRANSITIONS_SHARING-1204x630px.jpg?h=3ecc83bb&itok=enBW3mDs",{"__typename":118,"id":119,"name":120,"path":121,"status":20,"weight":122,"description":123,"langcode":127,"changed":128,"metatag":131},"TermCategories","7","Technologie","/kategorie/technologie",0,{"__typename":124,"processed":125,"format":126},"Text","Development Themen sowie zukünftige Technologien, mit denen wir uns auseinandersetzen. ","wp_html",{"__typename":16,"id":17,"name":18,"direction":19},{"__typename":83,"timestamp":129,"timezone":85,"offset":86,"time":130},1713772777,"2024-04-22T07:59:37+00:00",[132,135,139],{"__typename":95,"tag":96,"attributes":133},{"__typename":98,"name":99,"content":134},"Technologie | Liechtenecker UX Design Studio",{"__typename":95,"tag":96,"attributes":136},{"__typename":98,"name":137,"content":138},"description","Development Themen sowie zukünftige Technologien, mit denen wir uns auseinandersetzen.",{"__typename":102,"tag":103,"attributes":140},{"__typename":105,"href":141,"hreflang":13,"rel":107,"media":13,"sizes":13,"type":13},"http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/kategorie/technologie",[143,148,152,156],{"__typename":144,"id":145,"name":146,"path":147,"weight":122},"TermTags","80","angular","/tag/angular",{"__typename":144,"id":149,"name":150,"path":151,"weight":122},"501","framework","/tag/framework",{"__typename":144,"id":153,"name":154,"path":155,"weight":122},"937","Page Transitions","/tag/page-transitions",{"__typename":144,"id":157,"name":158,"path":159,"weight":122},"1299","technologie","/tag/technologie",{"__typename":161,"processed":162,"format":126,"summary":163},"TextSummary","\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>tl;dr&nbsp;\u003Ca href=\"#Beispiel\">Hier geht es zum Beispiel\u003C/a>\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Page Transitions, bzw. Seitenübergänge, bezeichnen die Art, wie der Übergang von einer Seite zu einer anderen ausgestaltet ist. Gerade bei (Web-)Apps sind dabei Animationen sehr beliebt. Sie helfen dabei zu verstehen, wohin man sich bewegt: Geht man in einem Prozess vorwärts? Dann kommt die neue Seite gleich von rechts reingeflogen. Bewegt man sich im Prozess rückwärts, so ist die Animation umgekehrt. Die Art der Animation kann dabei mannigfaltig erdacht werden, aber wichtig ist: bestimmte Seitenwechsel sollten bestimmte Übergänge haben.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch2>Warum Angular?\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>In diesem Artikel sehen wir uns die Implementierung von Page Transitions in Angular an. Das hat zwei Gründe:\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3 standard-list\">\u003Col>\u003Cli>Als klassisches WebApp-Framework, mit dem auch komplexe Applikationen umzusetzen sind, ist Angular prädestiniert für Projekte, die Page Transitions benötigen.\u003C/li>\u003Cli>Wenn man sich das Angular-Animations-Framework ansieht, oder nach Implementierungsbeispielen sucht, so findet man meist Beispiele, die statisch zwischen zwei “States” animieren. Im echten Leben, mit echten Projekten, sind diese Ansätze aber nicht sonderlich hilfreich. Deshalb möchte ich euch zeigen, wie wir diese Herausforderung angehen.\u003C/li>\u003C/ol>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch2>Angulars Animation Framework\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Angular kommt mit seinem eigenen&nbsp;\u003Ca href=\"https://angular.io/guide/animations\" target=\"_blank\" rel=\"noreferrer noopener\">Animation Framework\u003C/a>, das wir für unser Projekt natürlich gerne nutzen möchten. Es ermöglicht uns, komplexe und ansprechende Animationen zu erstellen und bietet dazu eine Vielzahl von Funktionen, darunter CSS-Transitionen, Keyframe-Animationen und Animationen auf der Grundlage von Eingangsereignissen. Mit dem Angular Animation Framework können wir auch Animationen erstellen, die auf Statusänderungen basieren, beispielsweise wenn ein Element angezeigt oder ausgeblendet wird. Dazu werden sogenannte „States“ definiert.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Eine der größten Stärken des Angular Animation Frameworks ist seine nahtlose Integration mit Angular. Es ermöglicht uns, die Animationen direkt in den Komponenten zu definieren und sie automatisch in die Anwendung zu integrieren. Darüber hinaus bietet das Framework grundsätzlich eine umfassende Dokumentation, wobei wir später noch einen Kritikpunkt finden werden.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Um die Page Transitions umzusetzen, werden wir uns vor allem die Eingangsereignisse in Kombination mit den States ansehen, aber dazu später mehr.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Kurz noch zu den wichtigsten Begriffen, die im Folgenden nun immer wieder auftauchen werden und die innerhalb des Animation Frameworks ihre eigene Bedeutung haben:\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>\u003Cstrong>Trigger\u003C/strong>: Es wird oft als “Auslöser” beschrieben, das ist allerdings etwas zu kurz gegriffen. Der Trigger verknüpft eine Animation (bzw. mehrere, je nach Definition) mit einem Element. Der Wert, den man dem Trigger übergeben kann, bzw. der sich zur Laufzeit ändern kann, bezeichnet den \u003Cem>State\u003C/em>.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>\u003Cstrong>State\u003C/strong>: ein State bezeichnet den “Status” eines Elements. \u003Cem>Transitions\u003C/em> (Animationen) werden von einem Status zu einem anderen ausgeführt. Die (CSS-)Eigenschaften des Elements in einem State können definiert werden, damit für die folgenden \u003Cem>Transitions\u003C/em> klar ist, zwischen welchen Werten die Animation stattfindet. Eine Beispielnotation für eine Animation, die einem Element zugewiesen wird, wäre: &lt;div [@openClose]=“openState“&gt;…&lt;/div&gt;\u003Cbr>Ändert sich der Wert von openState von “open” zu “closed”, so wird die Animation ausgeführt, die im Trigger “openClose” für diese \u003Cem>Transition\u003C/em> “open =&gt; closed” definiert ist.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>\u003Cstrong>Transition\u003C/strong>: Eine Transition definiert, zwischen welchen States welche Animation ausgeführt werden soll. Zum Beispiel wird eine Animation vom State “open” zu State “closed” definiert. Mit einem Stern (*) kann ein beliebiger State Teil der Transition sein (z.B.: “void =&gt; *” würde eine Transition von “nicht vorhanden” zu “irgendein State” beschreiben)&nbsp;\u003Cbr>Eine kleine Besonderheit sind die vordefinierten Transitions: “:enter” und “:leave”: sie sind unabhängig vom State-Wert und lösen die Animation dann aus, wenn das Element erstellt wird (bspw. durch ngIf oder Routing), bzw. zerstört wird. Sie sind eine Kurzform von “void =&gt; *” bzw. “* =&gt; void”&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch2>Das Problem\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Wie eingangs bereits erwähnt, findet man selten echte Beispiele, die einem bei echten Projekten helfen, wenn es darum geht, dynamisch zu entscheiden, in welche Richtung eine Animation ablaufen soll.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Was man immer wieder findet:\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3 standard-list\">\u003Cul>\u003Cli>State Changes werden dazu benutzt, immer wieder dieselbe Animation zu triggern (\u003Ca href=\"https://angular.io/guide/route-animations\" target=\"_blank\" rel=\"noreferrer noopener\">https://angular.io/guide/route-animations\u003C/a>)\u003C/li>\u003Cli>Es wird für einzelnen State-Änderungen (im Sinne von: ‘HomePage’ =&gt; ‘Subpage 1’) explizit definiert, welche Animation getriggert wird (zb hier:&nbsp;\u003Ca href=\"https://medium.com/ngconf/animating-angular-route-transitions-ef02b871cc30\" target=\"_blank\" rel=\"noreferrer noopener\">https://medium.com/ngconf/animating-angular-route-transitions-ef02b871cc30\u003C/a>)&nbsp;\u003C/li>\u003C/ul>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Während ersteres eigentlich nicht wirklich unseren Wunsch abdeckt, dass die Animation das widerspiegelt, was die/der User:in macht, funktioniert letzteres natürlich schon. Allerdings macht diese Art der Definition bei größeren Projekten keinen Spaß mehr. Es müsste dann ja jeder State (in diesem Fall: jede Seite) jede Page Transition zu jeder anderen Seite definieren, was schon bei wenigen Seiten recht unübersichtlich wird.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Was wir machen wollen:&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3 standard-list\">\u003Cul>\u003Cli>Zur Laufzeit entscheiden, welche Animation zwischen den Seiten verwendet wird\u003C/li>\u003C/ul>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Klingt nach einem guten Ziel? Dann los!\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch2>Der Ansatz\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Ziel unserer Animationen ist, dass durch das Routing die Animation ausgelöst wird. Unsere Seiten haben einen Trigger, der sich “@BasePageAnimation” nennt und wir werden uns auf die Transitions “void =&gt; state” und “state =&gt; void” beschränken.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Die States werden die Animationsrichtung bezeichnen: zb. “left” soll dafür sorgen, dass die Animationsrichtung nach links gerichtet ist: die neue Seite bewegt sich von rechts (außerhalb des Bildschirms) nach links herein, die alte Seite verschwindet nach links außen.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Folgende States wird es geben\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3 standard-list\">\u003Cul>\u003Cli>“left”: Bewegung nach links: die alte Seite verschwindet nach links, die neue Seite kommt von rechts rein&nbsp;\u003C/li>\u003Cli>“right”: vice versa, Bewegung nach rechts\u003C/li>\u003Cli>“up”: Bewegung nach oben\u003C/li>\u003Cli>“down”: Bewegung nach unten\u003C/li>\u003Cli>“fade”: keine Bewegung, alte Seite wird transparent, neue wird opak\u003C/li>\u003Cli>“zoom-in”: Skalierungsanimation, alte Seite skaliert recht groß und fadet dabei aus, neue Seite skaliert von 0,7 auf 1\u003C/li>\u003Cli>“zoom-out”: Vice versa\u003C/li>\u003Cli>(und als kleine Spielerei auch noch eine Variation von left und right, aber das seht ihr dann unten in der Beispiel App)\u003C/li>\u003C/ul>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Mit diesen States können wir die üblichsten Page Transitions abdecken.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Die Grundidee ist, dass erst beim Klick auf einen Link oder Button entschieden wird, welche Transition ausgeführt wird.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Und nun ab in den Code:\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch2>Am Beispiel\u003C/h2>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Unser wunderschönes Beispielprojekt hat zwei Routen: die A-Seite und die B-Seite. Zwischen diesen beiden wird navigiert. Das sind auch zwei unabhängige Komponenten (AComponent, BComponent), die allerdings von der selben AnimationBaseComponent erben.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch3>Warum AnimationBaseComponent?&nbsp;\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Die AnimationBaseComponent kümmert sich um alles, was die Komponenten brauchen, damit die Seitenanimationen funktionieren:\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Sie setzt den Animation Trigger auf das Host-Element, importiert die Animationen, nutzt das NavigationService für das Abrufen der Navigationsrichtung, etc.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cpre class=\"wp-block-code\">\u003Ccode class=\"language-plaintext\">@Component({\n selector: 'app-animation-base',\n template: '',\n styleUrls: ['animation-base-page.scss'],\n animations: [basePageAnimations],\n})\n\u003C/code>\u003C/pre>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Die Animations werden der BaseComponent übergeben.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cpre class=\"wp-block-code\">\u003Ccode class=\"language-plaintext\">export class AnimationBaseComponent  implements OnDestroy {\n @HostBinding(\"@basePageAnimation\") containerAnimation = \"fade\";\u003C/code>\u003C/pre>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Der Animation Trigger wird über HostBinding gesetzt.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cpre class=\"wp-block-code\">\u003Ccode class=\"language-plaintext\">private _navigationSubscription: Subscription;\nconstructor(protected _navigationService: NavigationService) {\n   this.containerAnimation =\n     this._navigationService.getBasePageAnimationDirection();\n   this._navigationSubscription =  this._navigationService.animationDirection.subscribe((direction:BasePageAnimationDirection) =&gt;\n       this.setAnimationDirection(direction)\n     );\n }\u003C/code>\u003C/pre>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Im Constructor wird ContainerAnimation (Richtung) geholt, bzw. auf die animationDirection subscribed…\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cpre class=\"wp-block-code\">\u003Ccode class=\"language-plaintext\">public setAnimationDirection(direction:BasePageAnimationDirection) {\n     this.containerAnimation = direction;\n }\u003C/code>\u003C/pre>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>… und die lokale Variable aktualisiert.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch3>Das NavigationService kümmert sich darum&nbsp;\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Das Navigation Service kümmert sich um zwei Dinge: Einerseits entscheidet es über die Animationsrichtung, andererseits informiert es die beteiligten Komponenten über jene Richtung.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Dabei müssen wir 2 Fälle extra beachten:\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch4>Die neue Komponente\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Wird die neue Komponente initialisiert, durchläuft sie ihren Konstruktor, in dem das NavigationService die aktuelle Animationsrichtung (animationDirection) abruft und dem Trigger zuweist.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Dadurch, dass der Konstruktor noch vor dem klassischen Lifecycle von Angular Komponenten befindet, ist der State (z.B.: “left”) bereits gesetzt, wenn die Animation nach passenden Transitions sucht -&gt; in diesem Fall: “void =&gt; left”\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cpre class=\"wp-block-code\">\u003Ccode class=\"language-plaintext\">public getBasePageAnimationDirection():BasePageAnimationDirection {\n return this._animationDirection;\n}\u003C/code>\u003C/pre>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>navigationService: Hier wird die aktuelle Animationsrichtungsvariable geholt.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch4>Die alte Komponente\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Hier müssen wir darauf achten, dass die verschwindende Komponente die Animationsrichtung bekommt, \u003Cem>bevor\u003C/em> die Zerstörung beginnt. Die Komponente subscribed sich zwar auf Aktualisierungen der animationDirection, allerdings muss diese Änderung rechtzeitig erfolgen. Deshalb wird bei einem Klick nicht direkt der Angular Router verwendet, sondern das NavigationService, das zuerst die Entscheidung trifft, welche Richtung nun verwendet werden soll, diese Information an alle subscribenden Komponenten ausspielt und danach erst die Navigationsänderung ausführt.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Somit ist die Transition zum Zeitpunkt der Zerstörung der Komponente dann beispielsweise “left =&gt; void” und die Animation wird korrekt ausgeführt.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cpre class=\"wp-block-code\">\u003Ccode class=\"language-plaintext\">public navigateByUrl(\n url:string,\n animationDirection?:BasePageAnimationDirection\n) {\n let direction = animationDirection? animationDirection : this._animationDirection;\n this.setBasePageAnimationDirection(direction);\n // emit current animation data\n this.animationDirection.next(direction);\n timer(1).subscribe((i) =&gt; {\n   this._router.navigate([url]);\n });\n}\u003C/code>\u003C/pre>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>NavigationService: Die navigateByUrl-Funktion setzt die Richtung, emittiert den Wert an die Subscriber und navigiert dann auf die Route.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch3>Zusätzliche Erklärungen des Beispielprojekts:\u003C/h3>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Dieses Beispiel ist ein bisschen gekürzt, aber nicht in der grundlegenden Funktion. Es wird in diesem Beispiel die Animationsrichtung vom jeweiligen Button mitübergeben und nicht vom Service errechnet oder auf Basis der URL geändert – aber das könnte man ganz einfach im NavigationService machen.&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Die Richtung jedenfalls ist nicht vordefiniert im Sinne von “Der Übergang von Seite A zu Seite B soll so aussehen”, sondern wird durch den AnimationDirection-String direkt definiert.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Ein Nachteil dieser Lösung ist, dass das “native” Routing über das Router-Service, bzw. via ng-route-Parameter nicht verwendet werden kann.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Da der State gesetzt sein muss, \u003Cem>bevor\u003C/em> die eine Komponente destroyed und die andere erstellt wird, müssen wir den Umweg über ein eigenes Navigation Service machen.\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Ch4 id=\"Beispiel\">\u003Cstrong>Und so siehts aus:\u003C/strong>\u003C/h4>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Hier seht ihr nun das Ergebnis: klickt euch durch 😉\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>\u003Ciframe id=\"angularPageTransitions\" title=\"Angular Page Transitions Example App\" frameborder=\"0\" src=\"/sites/default/files/ng-page-transitions/index.html\" width=\"600\" height=\"600\">\n                \u003C/iframe>\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Das Projekt, das ihr hier seht, gibts auch für euch auf github:&nbsp;\u003Ca href=\"https://github.com/snookas/ng-dynamic-page-transitions\" target=\"_blank\" rel=\"noreferrer noopener\">https://github.com/snookas/ng-dynamic-page-transitions\u003C/a>&nbsp;\u003C/p>\u003C/div>\u003C/div>\u003C/div>\u003Cdiv class=\"grid-wrapper\">\u003Cdiv class=\"row ckeditor-grid grid-100-dl\">\u003Cdiv class=\"ckeditor-grid-col default-left col-xsmall-12 col-medium-6 col-medium-offset-2 col-large-6 col-large-offset-3\">\u003Cp>Ich hoffe, unser Ansatz ist interessant und vielleicht sogar hilfreich für euch! Wie macht ihr dynamische Page Transitions in Angular? Habt ihr vielleicht eine ganz andere Idee?\u003C/p>\u003C/div>\u003C/div>\u003C/div>","Reist mit Lukas in alle möglichen Richtungen durch dynamische Page Transitions in Angular Apps.",{"__typename":165,"id":166,"excludeFromScreenreader":13,"mediaImage":167,"name":173,"path":176,"status":20},"MediaImage","373",{"__typename":168,"url":169,"width":170,"height":171,"alt":172,"title":173,"size":174,"mime":175},"Image","http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/sites/default/files/wp-migration/wordpress-media-image/2023/03/BLOG_Angular-Dynamic-Page-Transitions_TITEL-2880x1300px-scaled.jpg",2560,1156,"Headerbild Angular Dynamic Page Transitions","BLOG_Angular Dynamic Page Transitions_TITEL-2880x1300px",359415,"image/jpeg","/media/373/edit",{"__typename":165,"id":178,"excludeFromScreenreader":13,"mediaImage":179,"name":183,"path":185,"status":20},"372",{"__typename":168,"url":180,"width":181,"height":182,"alt":183,"title":183,"size":184,"mime":175},"http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/sites/default/files/wp-migration/wordpress-media-image/2023/03/BLOG_ANGULAR-DYNAMIC-%E2%80%A8PAGE-TRANSITIONS_SHARING-1204x630px.jpg",1204,630,"Sharebild Angular Dynamic Page Transitions",412821,"/media/372/edit","\u003C!-- This site is optimized with the Yoast SEO plugin v15.7 - https://yoast.com/wordpress/plugins/seo/ -->\r\n\u003Cmeta name=\"description\" content=\"Der Blogbeitrag zeigt, wie wir in Angular Apps Page Transitions verwenden. Und warum brauchen wir Page Transitions? Weil die Art und Weise wie zwischen 2 Seiten gewechselt wird, helfen kann, den User:innen zu veranschaulichen, wie sie sich innerhalb der Webapp gerade fortbewegen, auf welcher Ebene sie sich befinden oder ob sie in einem Prozess vorankommen.\" />\r\n\u003Cmeta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" />\r\n\u003Clink rel=\"canonical\" href=\"https://legacy.liechtenecker.dev/blog/angular-dynamic-page-transitions/\" />\r\n\u003Cmeta property=\"og:locale\" content=\"de_DE\" />\r\n\u003Cmeta property=\"og:type\" content=\"article\" />\r\n\u003Cmeta property=\"og:title\" content=\"Angular Dynamic Page Transitions - Liechtenecker\" />\r\n\u003Cmeta property=\"og:description\" content=\"Der Blogbeitrag zeigt, wie wir in Angular Apps Page Transitions verwenden. Und warum brauchen wir Page Transitions? Weil die Art und Weise wie zwischen 2 Seiten gewechselt wird, helfen kann, den User:innen zu veranschaulichen, wie sie sich innerhalb der Webapp gerade fortbewegen, auf welcher Ebene sie sich befinden oder ob sie in einem Prozess vorankommen.\" />\r\n\u003Cmeta property=\"og:url\" content=\"https://legacy.liechtenecker.dev/blog/angular-dynamic-page-transitions/\" />\r\n\u003Cmeta property=\"og:site_name\" content=\"Liechtenecker\" />\r\n\u003Cmeta property=\"article:published_time\" content=\"2023-03-28T12:41:12+00:00\" />\r\n\u003Cmeta property=\"article:modified_time\" content=\"2023-04-24T11:08:42+00:00\" />\r\n\u003Cmeta name=\"twitter:card\" content=\"summary_large_image\" />\r\n\u003Cmeta name=\"twitter:label1\" content=\"Geschätzte Lesezeit\">\r\n\t\u003Cmeta name=\"twitter:data1\" content=\"7 Minuten\">\r\n\u003Cscript type=\"application/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https://legacy.liechtenecker.dev/#website\",\"url\":\"https://legacy.liechtenecker.dev/\",\"name\":\"Liechtenecker\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https://legacy.liechtenecker.dev/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"de-DE\"},{\"@type\":\"WebPage\",\"@id\":\"https://legacy.liechtenecker.dev/blog/angular-dynamic-page-transitions/#webpage\",\"url\":\"https://legacy.liechtenecker.dev/blog/angular-dynamic-page-transitions/\",\"name\":\"Angular Dynamic Page Transitions - Liechtenecker\",\"isPartOf\":{\"@id\":\"https://legacy.liechtenecker.dev/#website\"},\"datePublished\":\"2023-03-28T12:41:12+00:00\",\"dateModified\":\"2023-04-24T11:08:42+00:00\",\"author\":{\"@id\":\"https://legacy.liechtenecker.dev/#/schema/person/0cb8cf424fe0fc1943e1a09a426032c4\"},\"description\":\"Der Blogbeitrag zeigt, wie wir in Angular Apps Page Transitions verwenden. Und warum brauchen wir Page Transitions? Weil die Art und Weise wie zwischen 2 Seiten gewechselt wird, helfen kann, den User:innen zu veranschaulichen, wie sie sich innerhalb der Webapp gerade fortbewegen, auf welcher Ebene sie sich befinden oder ob sie in einem Prozess vorankommen.\",\"inLanguage\":\"de-DE\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https://legacy.liechtenecker.dev/blog/angular-dynamic-page-transitions/\"]}]},{\"@type\":\"Person\",\"@id\":\"https://legacy.liechtenecker.dev/#/schema/person/0cb8cf424fe0fc1943e1a09a426032c4\",\"name\":\"Lukas Kindermann\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https://legacy.liechtenecker.dev/#personlogo\",\"inLanguage\":\"de-DE\",\"url\":\"https://secure.gravatar.com/avatar/116fdcda3e1d9ad0d3b65dd2e1d2dd40?s=96&d=mm&r=g\",\"caption\":\"Lukas Kindermann\"}}]}\u003C/script>\r\n\u003C!-- / Yoast SEO plugin. -->",{"__typename":188,"id":189,"myRole":190,"name":191,"nickname":192},"User","8","Omnom-Fanboy","lukas","Lukas Kindermann",{"latestKnowhow":194},[195,210,223],{"__typename":79,"id":196,"title":197,"path":198,"wpTeaserText":199,"wpPromotedTeaserImage":13,"wpHeaderImage":200},"1619","Behind the scenes: Ein Barrierefreiheits-Audit","/blog/behind-scenes-ein-barrierefreiheits-audit","”Entspricht unsere Website den gesetzlichen Anforderungen und wenn nicht, was genau müssen wir ändern?”\r\nDiese Frage lieben wir. Echt! Und so sieht unsere Antwort aus.",{"__typename":165,"id":201,"excludeFromScreenreader":13,"mediaImage":202,"name":208,"path":209,"status":20},"3364",{"__typename":168,"url":203,"width":204,"height":205,"alt":206,"title":13,"size":207,"mime":175},"http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/sites/default/files/2026-04/Headerbilder%20Blogartikel%20Behind%20the%20scene%20Accessibility%20Audit.jpg",2880,1300,"Headline mit Sujet: Tastatur mit Symbolen für Barrierefreiheit im Fokus auf hellem  Hintergrund",838204,"Headerbilder Blogartikel Behind the scene Accessibility Audit.jpg","/media/3364/edit",{"__typename":79,"id":211,"title":212,"path":213,"wpTeaserText":214,"wpPromotedTeaserImage":13,"wpHeaderImage":215},"1616","Agentic KI trifft Design-System: Wie unser Presentation Maker entstand.","/blog/agentic-ki-trifft-design-system-wie-unser-presentation-maker-entstand","Nein, wir wollen euch jetzt nicht erzählen, was KI alles kann. Aber wir möchten euch zeigen, wie wir mit KI umgehen. \r\n",{"__typename":165,"id":216,"excludeFromScreenreader":13,"mediaImage":217,"name":221,"path":222,"status":20},"3355",{"__typename":168,"url":218,"width":204,"height":205,"alt":219,"title":13,"size":220,"mime":175},"http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/sites/default/files/2026-03/BLOG_Presentation%20Tool_TITEL-2880x1300px_1.jpg","Lukas und Daniel  arbeiten an Computern im Büro.",2621988,"BLOG_Presentation Tool_TITEL-2880x1300px.jpg","/media/3355/edit",{"__typename":79,"id":224,"title":225,"path":226,"wpTeaserText":13,"wpPromotedTeaserImage":13,"wpHeaderImage":227},"1606","UI Trends 2026","/blog/ui-trends-2026",{"__typename":165,"id":228,"excludeFromScreenreader":21,"mediaImage":229,"name":233,"path":234,"status":20},"3303",{"__typename":168,"url":230,"width":204,"height":205,"alt":231,"title":13,"size":232,"mime":175},"http://liechtenecker-cms.liechtenecker-cms.svc.cluster.local/sites/default/files/2026-01/BLOG_Trendbericht%202026.jpg","UI Trends 2026, gelber Hintergrund, schwarze Schrift.",4700748,"BLOG_Trendbericht 2026.jpg","/media/3303/edit",{"Language:de":236,"MenuItem:9ffc5019-cbd8-4b2e-8eb7-9feae486d4a1":237,"MenuItem:1c7a5430-8a42-4b24-9544-252adabc2f4c":241,"MenuItem:9c4feedc-79e4-4fbf-b68c-065f33ebfe4c":244,"MenuItem:3b77a27b-272a-489f-843e-53e23ed07741":247,"MenuItem:ce0bb82b-e1ee-4036-be95-f693a62e9f4a":250,"MenuItem:04a19381-81a9-4694-8653-182d8855d2b5":253,"Menu:nuxt-main-menu":256,"ROOT_QUERY":270,"MenuItem:e2873307-b50a-4aab-b6b2-1950fd99c72e":286,"MenuItem:2cd9b7c9-142a-4ea3-b898-a0952c54a195":289,"MenuItem:a5effba3-5a8c-4125-8d78-0cdba09824db":292,"MenuItem:114bf071-bdbb-44cf-85c1-69e9d9e0777d":295,"Menu:footer":298,"TermCategories:7":308,"TermTags:80":319,"TermTags:501":320,"TermTags:937":321,"TermTags:1299":322,"MediaImage:373":323,"MediaImage:372":325,"User:8":327,"NodeWpPost:737":328,"MediaImage:3364":359,"NodeWpPost:1619":361,"MediaImage:3355":364,"NodeWpPost:1616":366,"MediaImage:3303":369,"NodeWpPost:1606":371},["null","__typename",16,"id",17,"name",18,"direction",19],["null","__typename",10,"id",11,"title",12,"description",13,"url",14,"langcode",238,"internal",20,"expanded",21,"attributes",240],{"__ref":239},"Language:de",["null","__typename",23,"class",13],["null","__typename",10,"id",25,"title",26,"description",13,"url",27,"langcode",242,"internal",20,"expanded",21,"attributes",243],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",30,"title",31,"description",13,"url",32,"langcode",245,"internal",20,"expanded",21,"attributes",246],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",35,"title",36,"description",13,"url",37,"langcode",248,"internal",20,"expanded",21,"attributes",249],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",40,"title",41,"description",13,"url",42,"langcode",251,"internal",20,"expanded",21,"attributes",252],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",45,"title",46,"description",13,"url",47,"langcode",254,"internal",20,"expanded",21,"attributes",255],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",5,"id",6,"name",7,"items",257],[258,260,262,264,266,268],{"__ref":259},"MenuItem:9ffc5019-cbd8-4b2e-8eb7-9feae486d4a1",{"__ref":261},"MenuItem:1c7a5430-8a42-4b24-9544-252adabc2f4c",{"__ref":263},"MenuItem:9c4feedc-79e4-4fbf-b68c-065f33ebfe4c",{"__ref":265},"MenuItem:3b77a27b-272a-489f-843e-53e23ed07741",{"__ref":267},"MenuItem:ce0bb82b-e1ee-4036-be95-f693a62e9f4a",{"__ref":269},"MenuItem:04a19381-81a9-4694-8653-182d8855d2b5",["null","__typename",271,"menu({\"name\":\"NUXT_MAIN_MENU\"})",272,"menu({\"name\":\"FOOTER\"})",274,"route({\"path\":\"/blog/angular-dynamic-page-transitions\"})",276,"latestKnowhow({\"excludeId\":\"737\",\"limit\":3})",279],"Query",{"__ref":273},"Menu:nuxt-main-menu",{"__ref":275},"Menu:footer",["null","__typename",77,"entity",277],{"__ref":278},"NodeWpPost:737",[280,282,284],{"__ref":281},"NodeWpPost:1619",{"__ref":283},"NodeWpPost:1616",{"__ref":285},"NodeWpPost:1606",["null","__typename",10,"id",55,"title",56,"description",13,"url",57,"langcode",287,"internal",20,"expanded",21,"attributes",288],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",61,"title",62,"description",13,"url",63,"langcode",290,"internal",20,"expanded",21,"attributes",291],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",66,"title",67,"description",13,"url",68,"langcode",293,"internal",20,"expanded",21,"attributes",294],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",10,"id",71,"title",72,"description",13,"url",73,"langcode",296,"internal",21,"expanded",21,"attributes",297],{"__ref":239},["null","__typename",23,"class",13],["null","__typename",5,"id",51,"name",52,"items",299],[300,302,304,306],{"__ref":301},"MenuItem:e2873307-b50a-4aab-b6b2-1950fd99c72e",{"__ref":303},"MenuItem:2cd9b7c9-142a-4ea3-b898-a0952c54a195",{"__ref":305},"MenuItem:a5effba3-5a8c-4125-8d78-0cdba09824db",{"__ref":307},"MenuItem:114bf071-bdbb-44cf-85c1-69e9d9e0777d",["null","__typename",118,"id",119,"name",120,"path",121,"status",20,"weight",122,"description",309,"langcode",310,"changed",311,"metatag",312],["null","__typename",124,"processed",125,"format",126],{"__ref":239},["null","__typename",83,"timestamp",129,"timezone",85,"offset",86,"time",130],[313,315,317],["null","__typename",95,"tag",96,"attributes",314],["null","__typename",98,"name",99,"content",134],["null","__typename",95,"tag",96,"attributes",316],["null","__typename",98,"name",137,"content",138],["null","__typename",102,"tag",103,"attributes",318],["null","__typename",105,"href",141,"hreflang",13,"rel",107,"media",13,"sizes",13,"type",13],["null","__typename",144,"id",145,"name",146,"path",147,"weight",122],["null","__typename",144,"id",149,"name",150,"path",151,"weight",122],["null","__typename",144,"id",153,"name",154,"path",155,"weight",122],["null","__typename",144,"id",157,"name",158,"path",159,"weight",122],["null","__typename",165,"id",166,"excludeFromScreenreader",13,"mediaImage",324,"name",173,"path",176,"status",20],["null","__typename",168,"url",169,"width",170,"height",171,"alt",172,"title",173,"size",174,"mime",175],["null","__typename",165,"id",178,"excludeFromScreenreader",13,"mediaImage",326,"name",183,"path",185,"status",20],["null","__typename",168,"url",180,"width",181,"height",182,"alt",183,"title",183,"size",184,"mime",175],["null","__typename",188,"id",189,"myRole",190,"name",191,"nickname",192],["null","__typename",79,"id",80,"title",81,"changed",329,"created",330,"langcode",331,"path",92,"promote",21,"status",20,"sticky",21,"metatag",332,"category",341,"contentElements",13,"evergreen",13,"tags",343,"wpBody",352,"wpHeaderImage",353,"wpHeaderImageOld",13,"wpHeaderImageOldSmall",13,"wpOgImage",355,"wpPromotedTeaserImage",13,"wpShareDescription",13,"wpShareTitle",13,"wpTeaserText",163,"wpYoastHead",186,"author",357],["null","__typename",83,"timestamp",84,"timezone",85,"offset",86,"time",87],["null","__typename",83,"timestamp",89,"timezone",85,"offset",86,"time",90],{"__ref":239},[333,335,337,339],["null","__typename",95,"tag",96,"attributes",334],["null","__typename",98,"name",99,"content",100],["null","__typename",102,"tag",103,"attributes",336],["null","__typename",105,"href",106,"hreflang",13,"rel",107,"media",13,"sizes",13,"type",13],["null","__typename",109,"tag",96,"attributes",338],["null","__typename",111,"property",112,"content",81],["null","__typename",109,"tag",96,"attributes",340],["null","__typename",111,"property",115,"content",116],{"__ref":342},"TermCategories:7",[344,346,348,350],{"__ref":345},"TermTags:80",{"__ref":347},"TermTags:501",{"__ref":349},"TermTags:937",{"__ref":351},"TermTags:1299",["null","__typename",161,"processed",162,"format",126,"summary",163],{"__ref":354},"MediaImage:373",{"__ref":356},"MediaImage:372",{"__ref":358},"User:8",["null","__typename",165,"id",201,"excludeFromScreenreader",13,"mediaImage",360,"name",208,"path",209,"status",20],["null","__typename",168,"url",203,"width",204,"height",205,"alt",206,"title",13,"size",207,"mime",175],["null","__typename",79,"id",196,"title",197,"path",198,"wpTeaserText",199,"wpPromotedTeaserImage",13,"wpHeaderImage",362],{"__ref":363},"MediaImage:3364",["null","__typename",165,"id",216,"excludeFromScreenreader",13,"mediaImage",365,"name",221,"path",222,"status",20],["null","__typename",168,"url",218,"width",204,"height",205,"alt",219,"title",13,"size",220,"mime",175],["null","__typename",79,"id",211,"title",212,"path",213,"wpTeaserText",214,"wpPromotedTeaserImage",13,"wpHeaderImage",367],{"__ref":368},"MediaImage:3355",["null","__typename",165,"id",228,"excludeFromScreenreader",21,"mediaImage",370,"name",233,"path",234,"status",20],["null","__typename",168,"url",230,"width",204,"height",205,"alt",231,"title",13,"size",232,"mime",175],["null","__typename",79,"id",224,"title",225,"path",226,"wpTeaserText",13,"wpPromotedTeaserImage",13,"wpHeaderImage",372],{"__ref":373},"MediaImage:3303"]