了解
網(wǎng)站開(kāi)發(fā)的都知道SVG 是一種非常簡(jiǎn)潔的格式,可以在網(wǎng)站上顯示任何插圖、圖標(biāo)或徽標(biāo)。此外,它們可以在 CSS 或 JavaScript 中進(jìn)行動(dòng)畫(huà)處理,以使它們更具吸引力。但是 SVG 也可以只用于他們的數(shù)據(jù),沒(méi)有視覺(jué)效果!讓我解釋…
SVG 是一種矢量圖像格式,這意味著它不是由彩色像素組成,而是數(shù)學(xué)函數(shù),一旦被解釋?zhuān)涂梢栽谄聊簧铣尸F(xiàn)。由于瀏覽器必須將文件從函數(shù)轉(zhuǎn)換為實(shí)際像素,它還允許我們?cè)L問(wèn)各種方法來(lái)操作或從數(shù)學(xué)中檢索數(shù)據(jù)。如果我們查看有關(guān)該方法的 MDN 文檔頁(yè)面,它說(shuō):該SVGGeometryElement.getPointAtLength()方法返回沿路徑給定距離處的點(diǎn)。該方法將為我們提供一個(gè)點(diǎn)的坐標(biāo),該點(diǎn)恰好位于我們作為參數(shù)發(fā)送的特定距離處的路徑上。
由于我們需要給出我們點(diǎn)的距離,這意味著我們很可能需要知道我們的路徑有多長(zhǎng)。幸運(yùn)的是,SVG API 有一個(gè)方法 getTotalLength() 可用于任何 SVGGeometryElement 返回元素總長(zhǎng)度的方法!為此,我們需要一個(gè)包含動(dòng)畫(huà)值 (as gsap cannot animate number variables directly) 并將屬性 distance 設(shè)置為零的 JavaScript 對(duì)象。
然后我們創(chuàng)建一個(gè)補(bǔ)間,將 distance 值從 0 更新為路徑的總長(zhǎng)度。最后在每一幀上,我們根據(jù)動(dòng)畫(huà)距離值沿路徑檢索一個(gè)點(diǎn),并更新圓的 cx 和 cy 屬性以使其移動(dòng):
// Create an object that gsap can animate
const val = { distance: 0 };
// Create a tween
gsap.to(val, {
// Animate from distance 0 to the total distance
distance: path.getTotalLength(),
// Function call on each frame of the animation
onUpdate: () => {
// Query a point at the new distance value
const point = path.getPointAtLength(val.distance);
// Update the circle coordinates
circle.setAttribute('cx', point.x);
circle.setAttribute('cy', point.y);
}
});
如果您想要實(shí)現(xiàn)的效果只是沿 SVG 路徑為一個(gè)元素設(shè)置動(dòng)畫(huà),它可以讓您輕松地從您提供的路徑中為任何 DOM 元素設(shè)置動(dòng)畫(huà)。我喜歡粒子,這不是突發(fā)新聞。這就是為什么,當(dāng)我學(xué)習(xí)一項(xiàng)新技術(shù)時(shí),我總是嘗試用它們來(lái)實(shí)現(xiàn)一些東西。讓我們看看如何代替沿著路徑移動(dòng)的單個(gè)圓圈,我們可以讓更多的圓圈像炸彈引信一樣爆炸,這個(gè)動(dòng)畫(huà)的整體邏輯和之前完全一樣,只是在每一幀我們都會(huì)創(chuàng)建一個(gè)新的圓形元素并對(duì)其進(jìn)行動(dòng)畫(huà)處理。如您所見(jiàn),設(shè)置非常相似。
const svg = document.querySelector('svg');
const fuse = svg.querySelector('.fuse');
const val = { distance: 0 };
gsap.to(val, {
distance: fuse.getTotalLength(),
repeat: -1,
duration: 5,
onUpdate: () => {
// Query a point at the new distance value
const point = fuse.getPointAtLength(val.distance);
// Create a new particle
createParticle(point);
}
});
該 createParticle 函數(shù)將在每一幀上調(diào)用以使新粒子彈出和淡出。以下是動(dòng)畫(huà)的步驟:創(chuàng)建一個(gè)新的圓形元素并將其附加到 SVG,從我們計(jì)算的點(diǎn)設(shè)置坐標(biāo) getPointAtLength,為每個(gè)定義一個(gè)隨機(jī)半徑和顏色,將該粒子 cx 和 cy 屬性設(shè)置為隨機(jī)位置,動(dòng)畫(huà)完成后,從 DOM 中移除粒子。