本文所有內容以 Angular 2 Quick Start 項目為基礎,使用 TypeScript 語言。
如上圖,最近遇到一個需求,需要在一個剛啟動的 Angular 2 項目中使用 snap.svg 操作頁面上的 svg 元素做動畫。
我粗略的看了下, snap.svg 的實現似乎並沒有遵從什么模塊規范,就是常見的提供幾個全局變量完事。如果真的耿直的在 Component 中去用的話,會在執行 tsc 編譯成 js 文件這一過程中報錯。
這是因為 TypeScript 編譯器並不知道 snap.svg.js 提供了怎樣的接口,所以當 ts 代碼中出現了 Snap()
時,編譯器會認為我們調用了一個不存在的方法而報錯。解決方式也很簡單,只需要使用 declare 告知 TypeScript 編譯器這個方法是在別處創建的,沒有出錯不用緊張:-)
簡單的方法
-
bower 或直接下載 snap.svg.js 文件。
-
在 index.html 中引入這個 js 文件。
-
在 app.component.js 上方加上這段聲明:
declare var Snap: any, mina: any;
-
照常使用即可
但是 Angular 2 的其他模塊都是動態加載的,這里寫死在 index.html 就感覺有點弱逼,所以下一步是配置 SystemJS ,然后用它來加載 snap.svg 。
用上 SystemJS
如果你和我這里一樣,是以 Angular 2 Quick Start 項目為基礎,那么你的 SystemJS 配置文件就是項目文件夾下的 systemjs.config.js ,最簡的配置只需要添加一行:
var map = { ... 'snap-svg': 'third-party/snap.svg-min.js', // 添加此行即可 };
你的文件名與路徑可能跟我不同,右側是相對於項目文件夾的相對路徑,看情況修改即可。
這樣一來,我們就可以和 Angular 2 的其它組件一樣動態加載 snap.svg 了。
import { Component } from '@angular/core';
Angular 2 的官方文檔里,經常能看到上面這種 import 形式。如前文所述, snap.svg 提供的交互方式是全局變量,那么我們的 import 語句還比上面的更簡單,最后是這個樣子的:
import 'snap-svn'; // 1. 加載 snap.svg declare var Snap: any, // 2. 消除 tsc 編譯器報錯 mina: any; ... var wave = Snap(this.el.querySelector('#wave')); // 3. 在 Component 中使用 snap.svg wave.animate({ transform: waveOverTrans }, 1500, mina.backout); ...