﻿
{"id":26809,"date":"2023-12-13T09:19:50","date_gmt":"2023-12-13T09:19:50","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=26809"},"modified":"2023-12-13T09:19:50","modified_gmt":"2023-12-13T09:19:50","slug":"angular-17-view-transitions-api","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/angular-17-view-transitions-api\/","title":{"rendered":"Angular 17 &#8211; View Transitions API"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde Angular 17 ile gelmi\u015f olan taray\u0131c\u0131lar\u0131n <em>View Transitions API<\/em> \u00f6zelli\u011fini yap\u0131land\u0131rma davran\u0131\u015f\u0131n\u0131n nas\u0131l kullan\u0131labilece\u011fini inceliyor olaca\u011f\u0131z.<\/p>\n<h4>View Transitions API Nedir?<\/h4>\n<p>View Transitions API, web uygulamalar\u0131nda kullan\u0131c\u0131lar\u0131n bili\u015fsel y\u00fck\u00fcn\u00fc azaltmak, ba\u011flamda kalmalar\u0131na yard\u0131mc\u0131 olmak ve uygulamalar\u0131n sayfalar\u0131 aras\u0131nda ge\u00e7i\u015fler yaparken alg\u0131lanan y\u00fckleme gecikmesinden kaynakl\u0131 kopu\u015flar\u0131 azaltmak i\u00e7in kullan\u0131lan animasyonel bir \u00f6zelliktir. Bu \u00f6zelli\u011fi daha net bir \u015fekilde izah edebilmek i\u00e7in a\u015fa\u011f\u0131daki ekran al\u0131nt\u0131lar\u0131n\u0131 g\u00f6zlemlemeniz yeterlidir;<div id=\"attachment_26811\" style=\"width: 810px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/Angular-17-View-Transitions-API.gif\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-26811\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/Angular-17-View-Transitions-API.gif\" alt=\"Angular 17 - View Transitions API\" width=\"800\" height=\"172\" class=\"size-full wp-image-26811\" \/><\/a><p id=\"caption-attachment-26811\" class=\"wp-caption-text\">View Transitions API kullanmaks\u0131z\u0131n&#8230;<\/p><\/div><div id=\"attachment_26812\" style=\"width: 810px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/Angular-17-View-Transitions-API-1.gif\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-26812\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/Angular-17-View-Transitions-API-1.gif\" alt=\"Angular 17 - View Transitions API\" width=\"800\" height=\"172\" class=\"size-full wp-image-26812\" \/><\/a><p id=\"caption-attachment-26812\" class=\"wp-caption-text\">View Transitions API kullan\u0131ld\u0131\u011f\u0131nda&#8230;<\/p><\/div>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere View Transitions API sayesinde okuma konumunun kayb\u0131 ve odak kar\u0131\u015f\u0131kl\u0131\u011f\u0131 gibi sorunlara \u00e7\u00f6z\u00fcm getirilebilmekte ve b\u00f6ylece sayfa ge\u00e7i\u015flerini destekleyerek kullan\u0131c\u0131 dostlu\u011fu a\u00e7\u0131s\u0131ndan daha elveri\u015fli bir ortam sa\u011flanabilmektedir.<\/p>\n<h4>Angular&#8217;da View Transitions API Kullan\u0131m\u0131<\/h4>\n<p>Angular mimarisinde View Transitions API&#8217;\u0131 kullanmak olduk\u00e7a basit bir konfig\u00fcrasyona bakmaktad\u0131r. Bunu sade bir senaryo \u00fczerinden tecr\u00fcbe etmemizde fayda g\u00f6rmekteyim.<\/p>\n<p>\u015eimdi bir Angular 17 projesi olu\u015ftural\u0131m ve i\u00e7erisine &#8216;persons&#8217; ve &#8216;person-detail&#8217; component&#8217;lerini ekleyelim.<\/p>\n<p>Ard\u0131ndan &#8216;app.routes.ts&#8217; dosyas\u0131nda a\u015fa\u011f\u0131daki gibi route path&#8217;lerini ayarlayal\u0131m.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Routes } from '@angular\/router';\r\n\r\nexport const routes: Routes = &#x5B;\r\n    { path: &quot;persons&quot;, loadComponent: async () =&gt; (await import(&quot;.\/components\/persons\/persons.component&quot;)).PersonsComponent },\r\n    { path: &quot;person-detail\/:id&quot;, loadComponent: async () =&gt; (await import(&quot;.\/components\/person-detail\/person-detail.component&quot;)).PersonDetailComponent }\r\n];\r\n<\/pre>\n<\/div>\n<p>\u015eimdi gerekli altyap\u0131y\u0131 kurgulad\u0131\u011f\u0131m\u0131za g\u00f6re esas meseleye odaklanabiliriz. Burada &#8216;PersonsComponent&#8217;te personel listelemesinde bulunaca\u011f\u0131z ve t\u0131klanan personelin detay\u0131n\u0131 da kullan\u0131c\u0131y\u0131 &#8216;PersonDetailComponent&#8217;e y\u00f6nlendirerek sunaca\u011f\u0131z. Bu y\u00f6nlendirme s\u00fcrecinde de personel foto\u011fraf\u0131n\u0131 View Transitions \u00f6zelli\u011fi sayesinde animasyonel olarak detay sayfas\u0131na kayd\u0131r\u0131yor olaca\u011f\u0131z.<\/p>\n<p>Bunun i\u00e7in a\u015fa\u011f\u0131daki dummy data&#8217;dan istifade edece\u011fiz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nexport const persons: any&#x5B;] = &#x5B;\r\n    {\r\n        id: 1,\r\n        name: &quot;Hilmi&quot;,\r\n        photo: &quot;https:\/\/randomuser.me\/api\/portraits\/men\/7.jpg&quot;,\r\n    },\r\n    {\r\n        id: 2,\r\n        name: &quot;M\u00fcsl\u00fcm&quot;,\r\n        photo: &quot;https:\/\/randomuser.me\/api\/portraits\/men\/11.jpg&quot;,\r\n    },\r\n    {\r\n        id: 3,\r\n        name: &quot;\u00c7o\u015fgun&quot;,\r\n        photo: &quot;https:\/\/randomuser.me\/api\/portraits\/men\/12.jpg&quot;,\r\n    },\r\n    {\r\n        id: 4,\r\n        name: &quot;\u015euayip&quot;,\r\n        photo: &quot;https:\/\/randomuser.me\/api\/portraits\/men\/19.jpg&quot;,\r\n    },\r\n].map(person =&gt; {\r\n    return {\r\n        ...person,\r\n        viewTransitionName: `view-transition-name: person-${person.id}`\r\n    }\r\n});\r\n<\/pre>\n<\/div>\n<p>Burada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere 4 adet personel bilgisi mevcuttur. Lakin son noktada bir <code>map<\/code> i\u015fleminin yap\u0131ld\u0131\u011f\u0131n\u0131 ve t\u00fcm personellere &#8216;viewTransitionName&#8217; field&#8217;\u0131na kar\u015f\u0131l\u0131k<br \/>\n<code style=\"color:green;\">view-transition-name: person-${person.id}<\/code> de\u011ferinin verildi\u011fini g\u00f6r\u00fcyoruz. \u0130\u015fte bu de\u011feri view transition animasyonu i\u00e7in her iki component&#8217;in ilgili noktalar\u0131nda(img nesnesinde) style de\u011feri olarak kullanaca\u011f\u0131z ve b\u00f6ylece her iki component&#8217;te de match olan bu de\u011fer sayesinde ge\u00e7i\u015f s\u00fcrecinde animasyonu ba\u015flatm\u0131\u015f olaca\u011f\u0131z. <\/p>\n<p>\u015eimdi her iki component&#8217;in de i\u00e7eri\u011fini geli\u015ftirelim.<\/p>\n<p>&#8216;PersonsComponent&#8217;;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, inject } from '@angular\/core';\r\nimport { RouterModule } from '@angular\/router';\r\nimport { persons } from '..\/..\/datas';\r\n\r\n@Component({\r\n  selector: 'app-persons',\r\n  standalone: true,\r\n  imports: &#x5B;RouterModule],\r\n  template: `\r\n    &lt;div class=&quot;row&quot;&gt;\r\n      @for(person of personDatas; track $index)\r\n      {\r\n        &lt;div class=&quot;col-md-3&quot;&gt;\r\n              &lt;a routerLink=&quot;\/person-detail\/{{person.id}}&quot;&gt;\r\n                {{person.name}} &lt;br&gt;\r\n                &lt;img &#x5B;src]=&quot;person.photo&quot; &#x5B;style]=&quot;person.viewTransitionName&quot;&gt;\r\n              &lt;\/a&gt;\r\n        &lt;\/div&gt;\r\n      }\r\n    &lt;\/div&gt;\r\n  `\r\n})\r\nexport class PersonsComponent {\r\n  personDatas: any&#x5B;] = persons;\r\n}\r\n<\/pre>\n<\/div>\n<p>&#8216;PersonDetailComponent&#8217;;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, inject } from '@angular\/core';\r\nimport { persons } from '..\/..\/datas';\r\nimport { ActivatedRoute } from '@angular\/router';\r\n\r\n@Component({\r\n  selector: 'app-person-detail',\r\n  standalone: true,\r\n  imports: &#x5B;],\r\n  template: `\r\n  {{person.name}} &lt;br&gt;\r\n  &lt;img &#x5B;src]=&quot;person.photo&quot; &#x5B;style]=&quot;person.viewTransitionName&quot;&gt;\r\n  `\r\n})\r\nexport class PersonDetailComponent {\r\n  activatedRoute: ActivatedRoute = inject(ActivatedRoute);\r\n  person: any;\r\n  ngOnInit() {\r\n    const id = this.activatedRoute.snapshot.params&#x5B;&quot;id&quot;];\r\n    this.person = persons.find(p =&gt; p.id == id);\r\n    console.log(this.person);\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>Yukar\u0131daki sat\u0131rlarda mevzu bahis olan &#8216;viewTransitionName&#8217; de\u011ferlerinin her iki component&#8217;te de img nesnesinin style attribute&#8217;una verildi\u011fini g\u00f6r\u00fcyorsunuz.<\/p>\n<p>T\u00fcm bu yapt\u0131\u011f\u0131m\u0131z \u00e7al\u0131\u015fma neticesinde art\u0131k view transition&#8217;\u0131n uygulama \u00e7ap\u0131nda davran\u0131\u015f g\u00f6stermesini istiyorsak e\u011fer &#8216;app.config.ts&#8217; dosyas\u0131nda route&#8217;lar\u0131n provide edildi\u011fi noktada a\u015fa\u011f\u0131daki gibi <code>withViewTransitions<\/code> metodunu da \u00e7a\u011f\u0131rmam\u0131z gerekmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { ApplicationConfig } from '@angular\/core';\r\nimport { provideRouter, withViewTransitions } from '@angular\/router';\r\nimport { routes } from '.\/app.routes';\r\n\r\nexport const appConfig: ApplicationConfig = {\r\n  providers: &#x5B;\r\n    provideRouter(\r\n      routes,\r\n      withViewTransitions()\r\n    )]\r\n};\r\n<\/pre>\n<\/div>\n<p>Bu a\u015famadan sonra art\u0131k uygulamam\u0131zda view transition animasyonu ba\u015far\u0131yla devrededir diyebiliriz.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek projeye a\u015fa\u011f\u0131daki github adresinden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/view-transitions-example\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/view-transitions-example<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde Angular 17 ile gelmi\u015f olan taray\u0131c\u0131lar\u0131n View Transitions API \u00f6zelli\u011fini yap\u0131land\u0131rma davran\u0131\u015f\u0131n\u0131n nas\u0131l kullan\u0131labilece\u011fini inceliyor olaca\u011f\u0131z. View Transitions API Nedir? View Transitions API, web uygulamalar\u0131nda kullan\u0131c\u0131lar\u0131n bili\u015fsel y\u00fck\u00fcn\u00fc azaltmak, ba\u011flamda kalmalar\u0131na&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":26698,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2420,4958],"tags":[4960,4992,4991],"class_list":["post-26809","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-angular-17","tag-angular-17","tag-angular-17-view-transitions-api","tag-view-transitions-api"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=26809"}],"version-history":[{"count":4,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26809\/revisions"}],"predecessor-version":[{"id":26815,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26809\/revisions\/26815"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/26698"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=26809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=26809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=26809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}