天天看點

svg配合css3動畫_如何使用CSS制作節日SVG圖示動畫

svg配合css3動畫

正是這個季節,是以在本教程中,我将逐漸建立一些CSS動畫,以假日為主題的SVG圖示。 Iconmelon上有一些很棒的圖示,該網站上有許多免費的矢量圖示集,可讓您盡其所能 。 我使用的圖示來自設計師Sam Jones 。 是以,為自己喝一杯蛋酒,将筆記本電腦拉到yule日志上,讓我們開始吧!

SVG和網絡

如果您對在網絡上使用SVG感興趣,則圖示是一個不錯的起點。 SVG靈活,獨立于分辨率且重量輕,是以圖示自然适合于矢量格式。 另外,就像HTML一樣,SVG可以輕松地用CSS樣式化,其中包括CSS3動畫。 在圖示中添加一些與動畫的互動性,可以為使用者帶來愉悅的體驗,還可以添加有關圖示代表的内容。

有關SVG和Web的介紹,請檢視SVG檔案:從Illustrator到Web 。

注意:在撰寫本文時,以下示範使用了尖端技術,在某些浏覽器(例如Internet Explorer)中,尚不支援這些技術。 如果您按照本教程進行操作,則最好使用Chrome或Safari。 使用适當的屬性字首完全可以實作Mozilla支援。 您當然可以期望将來對這些技術的支援會有所改善。

另外:在本文中,為了簡潔和易讀,我從一些CSS屬性中省略了一些必要的浏覽器字首。 如果您想輕松編寫無字首CSS,請檢視Lea Verou的無字首庫。 您也可以嘗試在Codepen上建立示範,可以輕松配置為使用prefixfree。

準備要編輯的SVG代碼

SVG的最大問題之一就是代碼難以處理。 乍一看,我選擇的矢量圖形編輯器Illustrator導出的SVG代碼非常不可讀。 在這方面, Inkscape實際上在導出SVG方面做得更好,但是我發現簡化和格式化代碼可以大大簡化代碼的閱讀和使用。

這是我将示範的第一個動畫示例的SVG代碼,一個閃爍的聖誕燈。

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
<path id="outline" d="M38.178,12.142H25.822v10.723c-1.605,2.67-2.461,6.529-2.461,11.406c0,9.473,4.748,17.587,8.637,17.587
 s8.641-8.114,8.641-17.587c0-4.881-0.854-8.744-2.461-11.412V12.142z"/>
<rect id="basefill" x="29.822" y="16.142" fill="#4D4B4C" width="4.355" height="4.273"/>
<path id="lightfill" fill="#FFFFFF" d="M31.998,47.768c-1.402-0.959-4.637-6.229-4.637-13.497c0-5.775,1.271-8.566,2.207-9.855
 h4.857c0.945,1.293,2.213,4.08,2.213,9.855C36.639,41.542,33.402,46.809,31.998,47.768z"/>
</svg>
           

此代碼是從我的矢量編輯工具Adobe Illustrator導出的。 乍看之下幾乎是不可讀的。 這是簡化的相同标記:

<svg class="svg-light" 
	viewBox="0 0 64 64" 
	xmlns="http://www.w3.org/2000/svg"
	>

	<path class="outline"
		d="M38.178,12.142H25.823v10.723c-1.606,2.67-2.461,6.529-2.461,11.406c0,9.473,4.748,17.587,8.636,17.587c3.889,0,8.641-8.114,8.641-17.587c0-4.881-0.854-8.744-2.461-11.412V12.142z"
		/>

	<rect class="base"
		x="29.822"
		y="16.142"
		width="4.355"
		height="4.273"
	 	/>

	<path class="bulb"
		d="M31.998,47.768c-1.402-0.959-4.637-6.229-4.637-13.497c0-5.775,1.272-8.566,2.207-9.856h4.858c0.945,1.293,2.213,4.081,2.213,9.856C36.639,41.542,33.402,46.809,31.998,47.768"
	 	/>
</svg>
           

我通過删除程式預設輸出的許多額外标記來大大簡化了該xml。 我的基本SVG元素包含以下内容:

  • 一類:

    svg-light

    。 我已經使用

    svg-

    字首輕松定位特定SVG中的元素。
  • viewbox

    屬性。

    viewbox

    屬性的值定義文檔的長寬比,并等于Illustrator中畫闆的大小。
  • xmnls

    屬性。 此屬性定義SVG的XML名稱空間,并幫助某些使用者代理了解标記。

于定義了組成圖像形狀嵌套在SVG内部的元件,如

paths

circles

rects

,我已經内嵌其開口标簽施加類。 元素的所有内聯屬性,例如其坐标,都已換行。 另外,我在SVG基本标簽下縮進了所有内部元素。

所有這些工作是有原因的。 首先,它使代碼更易于閱讀。 其次,在我選擇的代碼編輯器“ Sublime Text 3”中,我可以輕松折疊單個SVG元素或整個SVG,而類名仍有助于保留有關這些元素是什麼的上下文。

聖誕燈飾

好吧,讓我們進入節日氣氛,為閃爍的聖誕燈設定動畫! 這是我們将要實作的目标:

在CodePen上檢視 Noah Blon ( @noahblon )的筆燈

我想做的是為我在SVG中提供一類

bulb

的path元素制作動畫。

<path class="bulb"
	d="M31.998,47.768c-1.402-0.959-4.637-6.229-4.637-13.497c0-5.775,1.272-8.566,2.207-9.856h4.858c0.945,1.293,2.213,4.081,2.213,9.856C36.639,41.542,33.402,46.809,31.998,47.768"
	/>
           

使用CSS,我将給燈泡填充顔色并定義其動畫屬性。

.svg-light .bulb {
    fill: hsl(204, 70%, 23%);
    animation-name: glow-blue;
    animation-duration: 1s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-direction: alternate;
}
           

fill

屬性允許我們設定SVG元素的顔色。 如果可能的話,我喜歡使用HSL(色相,飽和度,亮度)來定義顔色值,因為使用起來非常直覺。 在這裡,我選擇了藍色(色調204),并将亮度值保持在23%的較低水準,這意味着我們将獲得深藍色。

我将燈泡設定為通過稱為

glow-blue

的關鍵幀動畫進行動畫處理。 動畫的持續時間為1秒。 動畫無限疊代,這意味着它将永遠運作。 動畫的時間安排在關鍵幀的開始和結束處得到緩解,進而在動畫的開始和結束點處建立了更加平滑的過渡。 最後,将動畫設定為交替,這意味着它将從頭到尾來回移動并再次來回移動。

提示:您可能知道CSS動畫規則有一種簡化的文法,但是我通常更喜歡将規則拆分開,以便在連結多個動畫時更易于了解,修改和共享。

現在,我将定義

glow-blue

關鍵幀動畫:

@keyframes glow-blue {
    0% { fill: hsl(204, 80%, 23%); }
    100% { fill: hsl(204, 80%, 63%); }
}
           

在這裡,我設定了要應用此動畫的元素的開始和結束填充顔色。 唯一改變的值是顔色的亮度(hsl中的“ l”位),這意味着燈光将從同一色調的較暗版本變亮。 這就是HSL提供的直覺文法。

因為我已經定義了動畫無限交替,是以燈光會從黑暗變為燈光,并且永不停止。 是以,它似乎會閃爍。

動畫多個燈光

好,現在讓我們引導内部的Clark W. Griswold并為整個聖誕燈設定動畫。 這就是我要建立的:

請參閱CodePen上的Noah Blon ( @noahblon )的Pen 540257e4a8b727e435c8e4033602ebb0

我建立了五種不同顔色的燈。 每盞燈都以20%的寬度包裹在div中。 這些div然後向左浮動,使它們彼此内聯。 由于我尚未将SVG設定為設定的高度或寬度并保留了viewbox屬性,是以SVG可以适應其父級的大小而不會丢失其長寬比或品質。 隻是SVG的巨大優勢之一。

<svg class="svg-light svg-light--red">
           

對于每個SVG,我都使用顔色字尾(例如svg-light--red)擴充了svg-light基類。 這是我用來為許多燈光設定動畫的規則的摘錄:

.svg-light .bulb {
	animation-duration: 1s;
	animation-iteration-count: infinite;
	animation-timing-function: ease-in-out;
	animation-direction: alternate;
}

.svg-light--red .bulb {
	fill: hsl(6, 63%, 16%);
	animation-name: glow-red;
	animation-delay: .5s;
	animation-duration: 1.25s;
}

@keyframes glow-red {
	0% { fill: hsl(6, 63%, 16%); }
	100% { fill: hsl(6, 63%, 56%); }
}
           

基本的動畫屬性仍将應用于

svg-light

的基類,以便可以在所有燈光之間共享它們。 對于每種顔色變化,我建立了一個不同的關鍵幀動畫(例如,

glow-red

glow-blue

并為它們賦予了不同的動畫延遲和持續時間。 這樣,訓示燈将以适當的顔色閃爍,并且所有訓示燈不會同時閃爍。

紅鼻子馴鹿魯道夫

我将使用與上述相同的概念來制作最著名的馴鹿魯道夫的動畫。 這是最終結果:

見筆SVG魯道夫動畫圖示使用CSS諾亞倫( @noahblon )上CodePen

首先,我将為他發光的紅鼻子設定動畫:

.svg-rudolph .nose {
    animation-name: glow;
    animation-duration: 6s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-direction: alternate;
}

@keyframes glow {
    0% { fill: hsl(6, 93%, 16%); }
    50% { fill: hsl(6, 93%, 56%); }
    100% { fill: hsl(6, 93%, 56%); }
}
           

這看起來很像我們的聖誕燈。 在關鍵幀動畫中,我設定為50%,然後設定為100%。 動畫持續時間為六秒,這意味着在三秒鐘内,鼻子将變成淺紅色,并在動畫結束前再保持該顔色三秒鐘。 另外,由于我将動畫設定為備用,是以它将從頭到尾運作。 是以,鼻子将在另外三秒鐘内保持全紅狀态,最後在最後三秒鐘内變黑。 了解關鍵幀百分比和動畫定義(例如持續時間)之間的互相作用是建立有效CSS動畫的關鍵。

我還對Rudy鼻子上的亮點應用了過渡:

.svg-rudolph .nose-highlight {
    fill-opacity: 0;
    animation-name: highlight-fade;
    animation-duration: 6s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-direction: alternate;
}

@keyframes highlight-fade {
    0% { fill-opacity: 0; }
    25% { fill-opacity: 0; }
    100% { fill-opacity: 1; }
}
           

在這裡,我為另一個SVG屬性設定了動畫,即

fill-opacity

。 此屬性的取值介于0到1之間; 0為完全透明,1為完全不透明。 最後,我将讓Rudy眨眨眼,為他帶來更多的生活:

.svg-rudolph .eye {
    animation-name: blink;
    animation-duration: 8s;
    animation-iteration-count: infinite;
    transform-origin: 50%;
}

@keyframes blink {
    0% { transform: scaleX(1) scaleY(1); }
    1% { transform: scaleX(1.3) scaleY(0.1); }
    2% { transform: scaleX(1) scaleY(1); }
    60% { transform: scaleX(1) scaleY(1); }
    61% { transform: scaleX(1.3) scaleY(0.1);}
    62% { transform: scaleX(1) scaleY(1); }
    100% { transform: scaleX(1) scaleY(1); }
}
           

我已經建立了一個名為

blink

的動畫。 該動畫運作八秒鐘,永不停止。 這次我不改變動畫,而是動畫将運作到最後,然後從頭開始。

在關鍵幀中,通過操縱X和Y軸上的眼睛比例來建立閃爍的動畫。 例如,在1%的标記處,眼睛在X軸上的大小縮放為1.3倍,在Y軸上的大小縮放為正常大小的0.1倍。 換句話說,它們變寬了一些,變短了一些。 在動畫持續時間的百分之一之後,眼睛的大小恢複正常。 是以,規模變化發生得非常快。 8秒/ 100 = 8分之一秒。

使用transform為SVG元素設定動畫的關鍵組成部分是設定元素

transform-origin

。 在大多數情況下,為了在SVG中正确應用變換,我們必須将變換坐标的原點定義為元素的中心。 與HTML元素不同,預設情況下,SVG元素的變換原點是其左上角,即(0,0)坐标。 通過将transform-origin設定為(50%,50%),變換的X和Y軸的原點将位于元素的中心,然後可以正确應用變換。

注意: Firefox在轉換原點時遇到問題。 不幸的是,将轉換原點設定為50%實際上會重置元素的X / Y坐标。 一種解決方法是将元素轉換回其原始位置。

丁東高中

對于此示範,我将為這樣的鈴聲制作動畫:

請參閱CodePen上的Noah Blon ( @noahblon )的Pen 63cdc3e8e785028deb35132d889b6090

讓我們看一下SVG标記的摘錄:

<svg class="svg-bell" viewBox="0 0 88 72" xmlns="http://www.w3.org/2000/svg">
		<g class="group-striker">
			<circle class="outline"
				cx="43.998" 
				cy="54.571" 
				r="7.99"
				/>
			<circle class="fill"
				cx="43.998" 
				cy="54.567" 
				r="3.99"
				/>
		</g>
		<g class="group-bell">
			<path class="outline"
				d="M71.5,38.184h-3.291l-6.213-21.879c-1.367-4.816-5.951-8.693-10.904-9.514C50.91,3.02,47.812,0,43.996,0c-3.812,0-6.91,3.018-7.092,6.787c-4.957,0.822-9.539,4.697-10.908,9.514l-6.211,21.883h-3.289l-4.498,15.85h19.251H36h15.994h3.963h20.041L71.5,38.184z M40.975,6.611C41.229,5.143,42.455,4,43.996,4c1.543,0,2.77,1.143,3.025,2.615L40.975,6.611z"
				/>
			<path class="fill"
				d="M29.844,17.395c1.045-3.678,5.156-6.783,8.975-6.783l10.355,0.004c3.82,0,7.93,3.105,8.975,6.783l5.902,20.785H23.943L29.844,17.395z"
				/>
			<polygon class="fill"
				points="19.52,42.184 68.477,42.184 70.705,50.033 17.291,50.033"
				/>
		</g>
	</svg>
           

我已經包裝好鐘形輪廓并填充了

<g>

(或組)标簽。 此标記對于組織元素非常有用,類似于您可以使用

<div>

包裝多個HTML元素的方式。 可以将動畫應用于組。 因為在這種情況下,我希望鐘形的填充和輪廓都旋轉,是以我可以隻旋轉組而不是分别旋轉每個元素。

.svg-bell .group-bell {
    animation-name: bell-ring;
    animation-duration: 3s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-delay: -1.5s;
    animation-direction: alternate;
    transform-origin: 50%;
}

@keyframes bell-ring {
    0% { transform: rotate(27deg); }
    100% { transform: rotate(-27deg); }
}
           

到目前為止,這個CSS應該已經很熟悉了,但是有一些新的事情正在發生。 首先,在關鍵幀動畫中,對鐘進行了變換,但是我不是在變換比例,而是在變換元素的旋轉值。 此動畫使鈴铛在27到-27度之間擺動。

我做的另一件事是對

animation-delay

使用負值。 負值會使動畫開始該時間段進入動畫。 在這種情況下,動畫将在動畫開始1.5秒後開始,而不是在1.5秒的延遲後開始動畫。 這樣,鈴铛将從動畫開始1.5秒的空檔位置開始,而不是動畫開始0秒的空轉位置開始。

.svg-bell .striker {
    animation-name: striker-move;
    animation-duration: 3s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
    animation-delay: 1.5s;
    animation-direction: alternate;
    transform-origin: 50%;
}

@keyframes striker-move {
    0% { transform: translateX(3px); }
    100% { transform: translateX(-3px); }
}
           

我對包含鈴铛前鋒元素的組應用了類似的動畫。 但是,這一次,我是沿X軸平移或移動元素,而不是旋轉它們,是以撞針将左右擺動。

讓它下雪吧!

對于此動畫,我将為落在雪球内部的雪設定動畫。

請參閱CodePen上的Noah Blon ( @noahblon )的Pen 2addb5f98c757d61cec87bdcacb5870d

我建立了一堆用于表示雪的圓形元素,并将這些元素放在雪球的周圍,并用

<g>

标簽包裹它們。

由于我已将剪切路徑應用于包含雪的組,是以在雪球之外看不到雪。 剪切路徑是可以應用于SVG元素的形狀,可以掩蓋其中的其他形狀。 在我們的地球儀示例中,我建立了一個圓形的剪切路徑,它覆寫了地球的内部。

<defs>
	<clipPath id="globeClipPath">
  		<circle cx="32" cy="31" r="26.825"/>
	</clipPath>
</defs>
           

<clipPath>

标簽是我們的masking元素,要實作它,我們必須給它一個ID。

我已經将剪切路徑包裝在

defs

标簽中。 SVG允許我們建立以後可以重用的元素,例如剪切路徑,過濾器或可以沖壓出的形狀。 最佳做法是将定義(例如剪切路徑)包裝在defs标簽中,以便可以更輕松地讀取SVG。

要應用剪切路徑,我們在SVG元素的内聯剪切路徑屬性中引用其url,在這種情況下,其ID前面是一個哈希符号:

<g class="group-snow" clip-path="url(#globeClipPath)">
    <circle class="snow" 
        cx="49.498" 
        cy="8.482" 
        r="2.5"
        />
    <circle class="snow" 
        cx="35.748" 
        y="2.783" 
        r="2.5"
        />
    <circle class="snow" 
        cx="21.001" 
        cy="4.728" 
        r="2.5"
        />
    <circle class="snow" 
        cx="28.25" 
        cy="2.783" 
        r="2.5"
        />
    <circle class="snow" 
        cx="42.997" 
        cy="4.728" 
        r="2.5"
        />
    <circle class="snow" 
        cx="14.502" 
        cy="8.482" 
        r="2.5"
        />
    <circle class="snow" 
        cx="9.194" 
        cy="13.793" 
        r="2.5"
        />
    <circle class="snow" 
        cx="54.806" 
        cy="13.793" 
        r="2.5"
        />
</g>
           

現在,雪隻在該圓形剪切路徑的内部可見。

使用與我之前介紹的技術相同的方法對雪進行動畫處理; 沿Y軸平移,并且随着動畫結束,填充不透明度接近零。

.svg-snowglobe .snow { 
	animation-name: snowfall;
	animation-duration: 10s;
	animation-iteration-count: infinite;
	animation-timing-function: ease-in;
}

.svg-snowglobe .snow:nth-child(1) { animation-delay: 2s; }
.svg-snowglobe .snow:nth-child(2) { animation-delay: 4s; }
.svg-snowglobe .snow:nth-child(3) { animation-delay: 6s; }
.svg-snowglobe .snow:nth-child(4) { animation-delay: 8s; }
.svg-snowglobe .snow:nth-child(5) { animation-delay: 10s; }
.svg-snowglobe .snow:nth-child(6) { animation-delay: 12s; }
.svg-snowglobe .snow:nth-child(7) { animation-delay: 14s; }
.svg-snowglobe .snow:nth-child(8) { animation-delay: 16s; }
.svg-snowglobe .snow:nth-child(9) { animation-delay: 18s; }
.svg-snowglobe .snow:nth-child(10) { animation-delay: 20s; }
           

是的,CSS3選擇器可用于SVG元素! 在這裡,我為每個降雪元素賦予了不同的延遲,是以它們不會一次全部掉落。

季節的問候

最後,我将為基于SVG的文本設定動畫,以實作如下結果:

在CodePen上檢視 Noah Blon ( @noahblon )的筆消息

SVG使我們能夠使用CSS将筆觸應用于SVG元素。 在上一個動畫中,我将向您展示如何逐漸繪制元素的筆觸。

為了實作此動畫,我使用了以下筆觸屬性:

  • stroke-width

    :筆劃的寬度。 這是相對于SVG的大小,是以是響應性的。
  • stroke

    :筆觸的顔色。
  • stroke-dasharray

    :定義虛線描邊。 交替值的數組定義虛線繪制部分的長度以及虛線之間的空白區域。
  • stroke-dashoffset

    :定義相對于路徑長度的筆畫起始位置。

設定描邊文本需要在圖形編輯器中進行一些工作。 我的工作流程如下:

  1. 建立一個文本元素。
  2. 将該文本轉換為矢量路徑。
  3. 将這些路徑合并為複合路徑。

這是我設定動畫CSS:

.svg-message .text {
    stroke-width: 1px;
    stroke: hsl(6, 63%, 36%);
    stroke-dasharray: 1865.753px 1865.753px;
    stroke-dashoffset:  1865.753px ;
    fill-opacity: 0;
    fill: hsl(6, 63%, 36%);
    animation-name: stroke, fill;
    animation-duration: 1s;
    animation-delay: 0, 1s;
    animation-iteration-count: 1;
    animation-timing-function: ease-in-out;
    animation-fill-mode: forwards;
}

@keyframes fadeIn {
    0% { fill-opacity: 0; }
    100% { fill-opacity: 1; }
}

@keyframes drawStroke {
    100% { stroke-dashoffset: 0 }
}
           

我已将

stroke-dasharray

屬性定義為總路徑的長度(您可以使用Object選項在Illustrator中的Document Info Palette下找到此值)。 然後,我給

stroke-dashoffset

設定了路徑總長度的值,這将整個筆劃推到可見性之外。 然後,通過關鍵幀為

stroke-dashoffset

屬性設定動畫,筆畫将逐漸在螢幕上繪制。

如果您想了解更多有關此技術的資訊,請檢視Jake Archibald的SVG中的Animated線描 。

我還設定了線條繪制完成後使用淡入淡出的屬性來填充文本,該屬性類似于我之前對snowglobe動畫所做的操作。

借助SVG和CSS進一步發展

在本教程中,我已示範了使用CSS和SVG可以建立一些非常有效的動畫。 如果您想使用所有代碼以及一些其他動畫,可以從Github下載下傳示例,或在Codepen上檢視我的收藏集 。

如果您想變得更進階,可以探索用JavaScript控制CSS動畫,或者用更複雜JavaScript動畫來補充CSS動畫,例如令人驚歎的SVG JS庫Snap SVG支援的動畫。

感謝您跟随本教程的學習,我迫不及待想看到您提出的創意!

翻譯自: https://webdesign.tutsplus.com/tutorials/how-to-animate-festive-svg-icons-with-css--webdesign-17658

svg配合css3動畫