使用 Angular 管理圖像斷點
已發表: 2022-03-10作為 Web 開發人員,我們經常需要創建響應式和媒體豐富的應用程序。 有這樣的要求意味著我們需要處理圖像斷點以及媒體查詢,因為我們希望為最終用戶提供最佳體驗。 添加到需求列表中,我們可能需要使用前端框架,例如 Angular,它非常適合創建 SPA 和其他應用程序類型。
在本文中,我們將了解圖像斷點、它們的用例以及整個動手示例; 我們將使用 Angular 自己的 BreakPoint Observer 在 Angular 應用程序中實現它們。 在使用這種方法時,我們還將強調為什麼這個流行的框架可以幫助我們以無縫的方式使用上述技術。
圖像斷點和響應式圖像
在響應式佈局時代(我們根據視口大小捕獲斷點並根據斷點更改頁面佈局),我們還需要確保圖像可以以正確的尺寸顯示——即使在佈局之後改變。 對於現代響應式網站來說,選擇正確的圖像是相當具有挑戰性的。
讓我們討論一下開發人員目前可以使用的兩個選項。
srcset
srcset
讓我們定義一個圖像列表,瀏覽器根據渲染的<img>
大小和顯示的密度在這些圖像之間切換。
我們來看一個例子:
<img src="tuscany.jpg" />
在上面,我們指定了 3 張圖像,其中w
表示圖像的像素寬度。 當將上述內容與srcset
一起使用時,我們還需要指定sizes
屬性(這是必需的,因為規範要求如果我們使用srcset
和w
,我們也必須有一個 sizes 屬性)。 這個屬性的目的是什麼? 瀏覽器需要在佈局頁面之前從源集中選擇要加載的資源(在他們知道圖像最終會有多大之前)。 我們可以將sizes
視為對瀏覽器的提示,在佈局之後,圖像將佔據視口寬度的 100%(這就是vw
所指的)。 瀏覽器在加載時知道實際的視口寬度(以及圖像的 DPR),因此它可以通過數學計算來確定它需要什麼大小的資源並從源集中選擇一個。
<picture>
和<source media="">
元素組合讓我們可以切換圖像資源以響應媒體查詢,例如佈局斷點處的那些。
讓我們也看一個這樣的例子:
<picture> <source media="(min-width: 1440px)"> <source media="(min-width: 900px)"> <source media="(min-width: 600px)"> <img src="../assets/images/tuscany-sm.jpg" /> </picture>
使用您選擇的具有小尺寸、中尺寸和大尺寸的圖像在本地更改上面的代碼。 請注意,通過調整瀏覽器大小,您將獲得不同的圖像。
以上所有內容的關鍵要點是,如果我們想在特定斷點處交換圖像,我們可以使用<picture>
元素將媒體查詢直接放入標記中。
注意:如果您有興趣探索<picture>
和srcset
+ sizes
之間的區別,我建議您閱讀 Eric Portis 的精彩文章: srcset
and sizes
。
到目前為止,我們已經討論瞭如何在純 HTML 環境中使用圖像斷點和媒體查詢。 即使根本不需要指定媒體查詢,如果有一種方便的、幾乎半自動化的方式來生成圖像斷點以及斷點的相應圖像,難道不是更好嗎? 幸運的是,Angular 有一個內置機制來幫助我們,我們還將看看使用第三方服務根據特定條件動態生成適當的圖像。
角度佈局模塊
Angular 帶有一個佈局模塊,它位於 CDK(組件開發工具包)工具集中。 Angular CDK 包含經過充分測試的工具來幫助進行組件開發。 CDK 的一部分是包含BreakpointObserver
的佈局模塊。 這個助手提供了對媒體查詢斷點的訪問,這意味著當瀏覽器大小(屏幕大小)直觀地改變時,組件(及其內容)可以適應變化。
推薦閱讀:佈局模塊
現在我們已經了解了理論,讓我們開始做生意並創建一個將實現響應式圖像斷點的應用程序。 在第一次迭代中,我們將通過 Angular CLI 創建應用程序的外殼: ng new bpo
並選擇必要的選項。
要使用BreakpointObserver
,我們還需要安裝 Angular 的 CDK 佈局模塊,我們可以通過 npm 來完成: npm i @angular/cdk
。
安裝後,我們將能夠向我們希望的任何組件添加必要的導入語句:
// app.component.ts import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
使用BreakpointObserver
我們可以訂閱視口寬度的變化,Angular 為我們提供了方便的訪問器,這意味著我們根本不需要使用媒體查詢! 讓我們繼續嘗試一下:
// app.component.ts constructor(public breakpointObserver: BreakpointObserver) { } ngOnInit() { this.breakpointObserver.observe([ Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge ]).subscribe(result => { if (result.breakpoints[Breakpoints.XSmall]) { // handle XSmall breakpoint } if (result.breakpoints[Breakpoints.Small]) { // handle Small breakpoint } if (result.breakpoints[Breakpoints.Medium]) { // handle Medium breakpoint } if (result.breakpoints[Breakpoints.Large]) { // handle Large breakpoint } if (result.breakpoints[Breakpoints.XLarge]) { // handle XLarge breakpoint } }); }
如前所述,上面的訪問器屬性以下列方式反映媒體查詢:

-
Breakpoints.XSmall
: 最大寬度 = 599.99px -
Breakpoints.Small
:最小寬度 = 600 像素和最大寬度 = 959.99 像素 Breakpoints.Medium
:最小寬度 = 960px 和最大寬度 = 1279.99px-
Breakpoints.Large
: min-width = 1280px 和 max-width = 1919.99px -
Breakpoints.XLarge
: 最小寬度 = 1920px
我們現在一切就緒,這意味著我們可以開始生成適當的圖像。
圖像的響應斷點
我們有幾個選項來生成響應式圖像:
- 響應式圖像斷點生成器
使用這個工具,我們可以上傳任何圖像,設置各種選項,例如我們希望生成的圖像數量。 運行該工具後,我們將獲得有關生成圖像的可視化表示,我們可以將它們下載為 zip 文件以及一些使用前面提到的<picture>
元素的生成代碼。 - 另一種解決方案是為我們的項目創建一個構建步驟,以通過 NPM 存儲庫中可用的一些包生成斷點,例如
gulp-responsive
或grunt-responsive-images
。 這兩者都依賴於我們需要為我們的操作系統安裝的其他庫。 (請檢查相應的存儲庫以獲取更多信息。) - 另一種解決方案是使用 Cloudinary 之類的服務來存儲圖像並以我們只需要修改所請求資源的 URL 的大小和格式提供它們。 這將是我們的方法,因為這給了我們最大的靈活性。
推薦閱讀: Eric Portis 使用響應式圖像斷點生成器自動化藝術指導
我已將原始圖像上傳到我的 Cloudinary 帳戶,這意味著我可以通過以下 URL 訪問該圖像:
https://res.cloudinary.com/tamas-demo/image/upload/breakpoints-article/tuscany.jpg
這是我們將使用的全尺寸、原始、原始和未更改的圖像。
我們可以修改圖像的 URL 以生成更小的版本。 例如,如果我們想要一個寬度為 600 像素的圖像,我們可以將 Cloudinary URL* 更新為以下內容:
https://res.cloudinary.com/tamas-demo/image/upload/w_600/breakpoints-article/tuscany.jpg
* 注意添加到 URL 的w_600
。
希望到此為止,您會看到這一切的發展方向。 基於上述方法,我們可以很快開始為正確的斷點生成正確的圖像。
使用 Cloudinary 意味著我們不需要創建、存儲和管理同一圖像的多個版本——它由 Cloudinary 即時為我們完成。
讓我們更新我們的代碼:
<!-- app.component.html --> <div> <h1>Current breakpoint: {{ breakpoint }}</h1> <img [src]="imagePath"> </div>
// app.component.ts import { Component, OnInit } from '@angular/core'; // ... export class AppComponent implements OnInit { imagePath; constructor(public breakpointObserver: BreakpointObserver) { } ngOnInit() { this.breakpointObserver.observe([ ... } }
我們可以從前面提到的列表中選擇任意數量的斷點來觀察,並且由於我們有一個觀察者,我們可以訂閱更改並對其採取行動:
this.breakpointObserver.observe([ Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge ]).subscribe(result => { if (result.breakpoints[Breakpoints.XSmall]) { // handle this case } });
為了處理 Cloudinary 中不同圖像的選項,我們將使用一種非常容易遵循的方法。 對於每種情況,我們將創建一個選項變量並更新最終的 Cloudinary URL。
在組件定義的頂部添加以下內容:
// app.component.ts imagePath; breakpoint; cloudinaryOptions; baseURL = 'https://res.cloudinary.com/tamas-demo/image/upload/breakpoints-article/tuscany.jpg';
並將以下內容添加到第一個if
語句中:
// app.component.ts let url = this.baseURL.split('/'); let insertIndex = url.indexOf('upload'); const options = 'c_thumb,g_auto,f_auto,q_auto,w_400'; url.splice(insertIndex + 1, 0, options); this.imagePath = url.join('/'); this.breakpoint = Breakpoints.XSmall;
結果將是一個更新的 Cloudinary URL:
https://res.cloudinary.com/tamas-demo/image/upload/c_thumb,g_auto,f_auto,q_auto,w_400/breakpoints-article/tuscany.jpg
我們在這裡設置的選項是什麼?
-
c_thumb
(生成圖像的縮略圖); -
g_auto
(專注於最有趣的部分;我們在縮略圖中看到了大教堂); -
f_auto
(為給定瀏覽器提供最合適的格式,即 Chrome 的 WebP); -
q_auto
(在不影響視覺效果的情況下降低圖像的質量,從而降低整體尺寸); -
w_400
(將圖像的寬度設置為 400 像素)。
出於好奇,讓我們將原始圖像大小與這個新生成的圖像進行比較:2.28 MB 與 29.08 KB!
我們現在有一個簡單的工作:我們需要為不同的斷點創建不同的選項。 我在 StackBlitz 上創建了一個示例應用程序,因此您可以立即對其進行測試(您也可以在此處查看預覽)。
結論
當今網絡中使用的各種桌面和移動設備以及媒體數量已經達到了驚人的水平。 作為 Web 開發人員,我們必須站在創建可在任何設備上運行且不影響視覺體驗的 Web 應用程序的最前沿。
有很多方法可以確保將正確的圖像加載到正確的設備(甚至在調整設備大小時)。 在本文中,我們回顧了一種利用稱為 BreakPoint Observer 的內置 Angular 功能的方法,它為我們提供了一個強大的界面來處理響應式圖像。 此外,我們還研究了一項允許我們在雲中提供、轉換和管理圖像的服務。 擁有如此引人注目的工具,我們仍然可以創建身臨其境的視覺網絡體驗,而不會失去訪問者。