天天看点

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动画