付费投稿计划,SVG是最流行的和正在被众多的设计人员和开发人员使用

  • 栏目:前端 时间:2020-04-11 18:49
<返回列表

本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

在当今时代,SVG是最流行的和正在被众多的设计人员和开发人员使用,创建支持视网膜和响应式的网页设计。绘制SVG不是一个艰巨的任务,因为大量的 JavaScript 库可与 SVG 图像搭配使用。这些JS库帮助设计师和开发人员可以轻松地为他们的项目和Web应用程序创建创新和逼真的图形。

关于CSS反射倒影的研究思考,css反射倒影

原文地址:

译者:nzbin

友情提示:该文章篇幅较长,内容庞杂,有一定难度。而我本人学识有限,加之时间仓促,所翻译内容可能有不恰当及晦涩之处。欢迎大家拍砖指正。

 

我最近在codepen上看到了这个 加载程序,一个纯CSS制作的带有渐变反射的3D旋转竖条。它的制作方法是,为每个竖条创建一个元素,然后通过复制每一个元素来创建反射倒影,最后在反射倒影上添加渐变背景来创建渐隐的效果。听上去有点复杂,而且创建渐隐效果的渐变背景在非纯色背景下是无效的。有没有更好的CSS方法呢?

.loader 元素以及在其中创建10个 .bar 元素

HTML

<div class='loader'>
  <div class='bar'></div>
  <!-- repeat to create 9 more bars -->
</div>

把同样的事情写很多遍是一件痛苦的事,所以在该情况下使用一个预处理器会变得很简单。我们在这里使用 Haml 模板,当然也有人会选择其他的模板。

Haml

.loader
  - 10.times do
  .bar

 我们通过绝对定位把所有元素放到视图的中间。大多数情况下,我们使用 top: 50% ,但是现在,使用 bottom: 50% 会使后面的操作更简单。

CSS

div {
  position: absolute;
  bottom: 50%; left: 50%;
}

我们给竖条设置 width 和 height ,为了能看到它再设置一个 background 

SCSS

$bar-w: 1.25em;
$bar-h: 5 * $bar-w;

.bar {
  width: $bar-w; 
  height: $bar-h;
  background: currentColor;
}

我们希望竖条的底部贴合视图的水平中心线。设置 bottom: 50% 已经可以了。

现在所有的竖条都重合在一起,它们的左边贴在垂直中心线上,底部贴在水平中心线上。

See the Pen bar loader 1.1 creating the bars by Zongbin Niu (@nzbin) on CodePen.

 

今天,我想向大家展示如何巧妙地使用HTML、CSS排序动画和SVG滤镜把生活中可能最可爱的东西之一——动物画到网页上。我们将探讨绘制动物的两种技术:一种使用纯HTML和CSS,另一种使用内联SVG背景图像。

1.Textures.js

Textures.js易于改进的数据可视化添加SVG图形。它包括一个巨大的各种纹理,包括直线,圆,路径,甚至自定义模式。

图片 1

在线预览

#定位竖条

我们需要让最左边的竖条和最右边的竖条到垂直中心线的距离相等。这个距离就是竖条数量( $n )的一半乘以竖条的宽度( $bar-w )。原始demo用的是普通的CSS,我们会使用Sass来减少代码量。

See the Pen initial (stacked) vs. final (distributed) by Zongbin Niu (@nzbin) on CodePen.

这意味着,从竖条的起始位置开始,我们需要将第一个竖条向左移动 .5 * $n * $bar-w 。左侧是x轴的负方向,需要在前面加负号。所以第一个竖条的 margin-left 就是 -.5 * $n * $bar-w 。

第二个竖条(以0为基数,索引值是1)就是向右(x轴的正方向)移动 1 个竖条的宽度。所以第二个竖条的 margin-left 就是 -.5 * $n * $bar-w + $bar-w 。

第三个竖条(以0为基数,索引值是2)就是向右(x轴的正方向)移动 2 个竖条的宽度。所以第三个竖条的 margin-left 就是 -.5 * $n * $bar-w + 2 * $bar-w 。

最后一个(以0为基数,索引值是 $n - 1)就是向右(x轴的正方向)移动 $n - 1 个竖条的宽度。所以最后一个竖条 margin-left 就是 -.5 * $n * $bar-w + ($n - 1) * $bar-w 。

See the Pen bar distribution by Zongbin Niu (@nzbin) on CodePen.

通常情况下,如果我们认为当前竖条的索引值是 $i (以0为基数),那么 $i 竖条的 margin-left 就是 -.5 * $n * $bar-w + $i * $bar-w ,可以简化为 ($i - .5 * $n) * $bar-w 。

这就允许我们使用Sass的循环来定位竖条。

SCSS

$n: 10;

@for $i from 0 to $n {
  .bar:nth-child(#{$i + 1}) {
  margin-left: ($i - .5 * $n) * $bar-w;
  }
}

 为了看清楚竖条的边界,我们给它一个 box-shadow 。

See the Pen bar loader 1.2 positioning the bars by Zongbin Niu (@nzbin) on CodePen.

 

此演示高度实验性质——动画SVG滤镜目前仅在Chrome中可用。

2.Circulus.svg

Circulus.svg是一个圆形的菜单生成器,可以生成SVG的菜单,它提供了两个不同的风格,全或半圈,和造型的各种选项。

图片 2

在线预览

#给竖条添加渐变

 竖条的背景色是从最左边的深蓝色( #1e3f57 )过渡到最右边的浅蓝色( #63a6c1 )。这听上去很像 the Sass mix() function 所做的。第一个参数是浅蓝色,第二个参数是深蓝色,第三个参数(称作相对权重)表示将多少(百分比表示)浅蓝色混合进去。

对于第一个竖条,这个数量就是 0% ( 0% 数量的浅蓝色),混合结果就是深蓝色。

对于最后一个竖条,这个数量是 100% ( 100% 数量的浅蓝色,也就是 0% 数量的深蓝色),得到的背景色就是浅蓝色。

对于剩下的竖条,我们需要平均分布的中间值。如果我们有 $n 个竖条,第一个竖条在 0% 的位置,最后一个竖条在 100% 的位置,那么我们需要在两者之间平分成 $n-1 个区间。

See the Pen distribute n points on 100% interval (interactive) by Zongbin Niu (@nzbin) on CodePen.

一般来说,索引值为 $i 的竖条的相对权重是 $i * 100% / ($n - 1) ,这意味着我们要添加如下代码:

SCSS

$c: #63a6c1 #1e3f57; // 1st = light 2nd = dark

@for $i from 0 to $n {
  // list of mix() arguments for current bar
  $args: append($c, $i * 100% / ($n - 1));

  .bar:nth-child(#{$i + 1}) {
  background: mix($args...);
  }
}

现在这些竖条看起来就和原始demo的一样了:

See the Pen bar loader #1.3 shading the bars by Zongbin Niu (@nzbin) on CodePen.

 

 

所涉及的动画也很复杂,因此本教程将重点介绍创建这些动物以及栩栩如生的动作所涉及的不同技术。放飞你的创意,自行创作独特和俏皮的动物动画吧。

3.deSVG

deSVG它使简单的从HTML删除内联SVG的膨胀。它可以让你的风格你的SVG和CSS,并保持您的SVG可即使没有JavaScript。

图片 3

在线预览

探索反射的方案

 

话不多说,开始咯!

4.SVG Morpheus

SVG Morpheus是一个 JavaScript 库,可以让你创建SVG图标变成另一个。它的易于使用和工程与材料设计迷人的细节转换。

图片 4

在线预览

#WebKit浏览器:-webkit-box-reflect

很遗憾,这不是一个标准属性!我不知道为什么这个属性没有标准化。这一属性首次出现在Safari浏览器上时,我还不知道CSS。 但是对于WebKit内核的浏览器,这是一个非常好的实现方法。它做了很多工作。它的使用很简单,即使在不支持该属性的浏览器上,除了不显示反射以外,并没有什么其他影响。

让我们看看它是怎么工作的,它需要三个参数值:

See the Pen how `-webkit-box-reflect` works by Ana Tudor (@thebabydino) on CodePen.

注意linear-gradient()可以有更多的颜色断点,也可以用radial-gradient()替换。

在我们的demo中,我首先想到的就是给 .loader 元素添加这一属性。

SCSS

.loader {
  -webkit-box-reflect: below 0 linear-gradient(rgba(#fff), rgba(#fff, .7));
}

但是在WebKit浏览器中测试时,我们并没有看到反射。

See the Pen bar loader 2.1.1 -webkit-box-reflect by Zongbin Niu (@nzbin) on CodePen.

这里发生了什么?我们给所有的元素设置了绝对定位,但是并没有设置 .loader 元素的尺寸。所以这是一个宽高都为0的元素。

让我们给 .loader 元素一个明确的尺寸,高度 height 等于竖条的高度 $bar-h ,宽度等于所有竖条的宽度之和 $n * $bar-w 。为了看清元素的边界,我们暂时给它一个 box-shadow 。

SCSS

$loader-w: $n * $bar-w;

.loader {
  width: $loader-w; height: $bar-h;
  box-shadow: 0 0 0 1px red;
}

我之所以用 box-shadow 而不用 outline 是因为如果子元素溢出父元素,在不同的浏览器上使用 outline 突出物体的效果是不一样的。

outline属性在WebKit浏览器中的对比。Edge(上)vs. Firefox(下)

 

添加以上代码后的结果可以在WebKit浏览器中看到:

See the Pen bar loader 2.1.2 explicitly sizing the loader by Zongbin Niu (@nzbin) on CodePen.

如果你用的不是WebKit浏览器,看下面的图片,就是这个样子:

bottom: 0 。

SCSS

.loader { margin-left: -.5 * $loader-w; }

.bar { bottom: 0; }

修正位置之后的样子如下:

See the Pen bar loader 2.1.3 tweaking loader and bar positions by Zongbin Niu (@nzbin) on CodePen.

 

图片 5

5.Vivus

Vivus是一个动画SVG无依赖必要的JavaScript类。它提供了异步延迟动画,动画,一行一行的动画。

图片 6

在线预览

#火狐浏览器 element() + mask

##用 element() 制作反射

  element()  函数(现在仍然有效,必须在火狐浏览器中并且添加 -moz- 前缀)给我们提供了一个像真实图片一样可以任意使用的图像值。它需要一个参数值,就是我们希望以 background 还是 border-image 显示的被选元素的 id 。这允许我们做很多事情,比如使用可以控制的图片作为背景。我们也可以在Firefox中制作一个反射元素。

需要了解的一个重要事情就是 element() 函数不是递归函数,我们不能创建使用元素作为自身背景的图像。这在创建反射的loader元素的伪类上使用是安全的,因此我们不用创建额外的元素。

好吧,让我们看看如何操作。首先,我们给 .loader 元素一个 id 。转到样式表,我们从适用WebKit浏览器的CSS着手。我们在loader元素上添加一个 ::after 伪类

CSS

.loader::after {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  box-shadow: 0 0 0 2px currentColor;
  color: crimson;
  content: 'REFLECTION';
}

为了在最终效果中看清伪类的边界和方向,我们设置了一些暂时性的样式,我们想让它是颠倒的。

See the Pen bar loader 2.2.1 adding a pseudo by Zongbin Niu (@nzbin) on CodePen.

现在我们需要以底边为基准把 ::after 伪类镜像过来。为了做到这一点,我们使用 scaleY() 属性并且选择合适的 transform-origin 。

以下的可交互demo说明了包含多个缩放因子以及变换中心的定向缩放是如何工作的:

See the Pen how CSS scaling w.r.t. various origins works by Ana Tudor (@thebabydino) on CodePen.

注意:缩放因子的数值和变换中心可以超出demo中规定的限制。

在我们的例子中,我们需要 scaleY(-1) 并且 transform-origin 在 ::after 伪类的底边上。

使用scaleY(-1)和一个合适的 transform-origin 来镜像元素

 

我们把这些设置添加到代码中,并且用 element () 函数把 ::after 伪类的背景设置为 #loader 

CSS

.loader::after {
  transform-origin: 0 100%;
  transform: scaleY(-1);
  background: -moz-element(#loader);
}

注意:由于特别的原因我们使用 .loader 作为选择器并且由于element() 函数参数的需要我们设置它的 id 为 #loader 。

添加以上代码后的效果如下所示(只在Firefox浏览器中有效)

See the Pen bar loader 2.2.2 -moz-element() for reflecting pseudo by Zongbin Niu (@nzbin) on CodePen.

对于在其他浏览器阅读这篇文章的朋友,以下是截图

在Firefox中使用 element() 制作的反射效果

 

##用 mask 制作渐变

 我们使用和WebKit情况下一样的方法给反射添加渐变。在WebKit的情况下,遮罩是 -webkit-box-reflect 属性的一部分。而现在,我们讨论CSS的 mask 属性,它需要引用SVG作为值。

CSS

mask: url(#fader);

 #fader 元素是一个包含长方形的SVG mask 元素。

SVG

<svg>
  <mask id='fader' maskContentUnits='objectBoundingBox'>
    <rect width='1' height='1'/>
  </mask>
</svg>

我们可以用Haml模板压缩一下

Haml

%svg
  %mask#fader(maskContentUnits='objectBoundingBox')
    %rect(width='1' height='1')

但是,如果我们加上以上代码,我们的反射倒影消失了,在Firefox中查看如下demo

See the Pen bar loader 2.2.3 adding a SVG mask by Zongbin Niu (@nzbin) on CodePen.

这是因为,默认情况下,SVG图形会有一个纯黑色的 fill ,完全不透明,但是,我们的 遮罩 默认是有透明度的。因此为了实现反射渐变的效果我们需要给长方形一个 fill (需引入SVG linearGradient )

Haml

%rect(width='1' height='1' fill='url(#grad)')

一个SVG linearGradient 由定义的两个点 x1 , y1 , x2 , y2 组成。 x1 和 y1 是渐变线的起始点(0%)坐标,而 x2 和 y2 是这条线的终点(100%)坐标。如果这些数值是空的,默认设为 0% , 0% , 100% , 0% 。这些数值描绘了从指定元素(由于 gradientUnits 的默认值是 objectBoundingBox )的左上( 0% 0% )到右上( 100% 0% )的一条线。这意味着,默认情况下,渐变是从左到右。

但是在我们的例子中,我们希望渐变从上到下,所以我们将 x2 的值从 100% 设置为 0% 并且将 y2 的值从 0% 设置为 100% 。这使得指定元素的渐变向量从左上角( 0% 0% )指向左下角( 0% 100% )。

Haml

%linearGradient#grad(x2='0%' y2='100%')

在 linearGradient 元素之内,我们有至少两个 stop 元素。其中有三个特定的属性, 偏移值 , 颜色断点 , 透明度断点。

我们需要记住我们应用渐变遮罩的伪类已经通过 scaleY(-1) 属性镜像过来了,这意味着渐变遮罩的底部在视觉上是顶端。因此我们的渐变是从顶部(视觉下端)的完全透明到底部(视觉上端)的 .7 。

因为我们的渐变从上到下,所以第一个 stop 是完全透明的。

Haml

%linearGradient#grad(x2='0%' y2='100%')
  %stop(offset='0' stop-color='#fff' stop-opacity='0')
  %stop(offset='1' stop-color='#fff' stop-opacity='.7')

添加线性渐变之后,在Firefox中就是我们想要的结果了

实时效果如下:

See the Pen bar loader 2.2.4 linearGradient it by Zongbin Niu (@nzbin) on CodePen.

 

在线演示   源码下载

6.Walkway.js

Walkway.js是你简单的SVG元素的一个简单的方法。它包括内置的缓解功能,还具有用于选择和时间选择。

图片 7

在线预览

 

塑造动物外形

演示使用两种不同的技术来创建动物不同身体部位的形状。哈士奇使用CSS border-radius属性,狐狸使用内联背景SVG图像,因为后者的形状更复杂。

7.ZorroSVG

ZorroSVG可以很容易地添加到您的SVG图像的面具。它可以创建图像的PNG透明的同时保持小的文件大小。

图片 8

在线预览

SVG渐变的问题

在我们的例子中,因为我们的遮罩渐变是垂直的所以看起来很简单。但是如果我们的渐变不是垂直或者水平或者从一个角到另一个角怎么办?如果我们想要一个特定角度的渐变怎么办?

SVG中有一个 gradientTransform 属性,它可以通过指定 x1 , y1 , x2 , y2 来旋转渐变线。有人可能会认为这是制作具有特定角度的CSS渐变的简单方法。但是,并没有想象的那么简单!

想一想从金色到深红色渐变的例子。为了看得清楚一点,我们在两者之间50%的位置设置一个剧烈的过渡。首先我们将这个渐变的CSS角度设置为 0deg 。这意味着渐变会从底部(金色)过渡到顶部(深红色)。创建这个渐变的CSS如下:

CSS

background-image: linear-gradient(0deg, #e18728 50%, #d14730 0);

如果你还不明白CSS线性渐变的工作原理,你可以看一下Patrick Brosset 做的这个 优秀作品。

我们看到的结果如下:

See the Pen CSS linear-gradient at 0deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

为了制作SVG的渐变,我们设置 y1 为 100%  y2 为 0% 以及把 x1 和 x2 设置成相同的数值(简单起见设置为0)。这意味着渐变线从底部垂直上升到顶部。我们同时把断点的偏移值设置为50%。

Jade

linearGradient#g(y1='100%' x2='0%' y2='0%' gradientTransform='rotate(0 .5 .5)')
  stop(offset='50%' stop-color='#e18728')
  stop(offset='50%' stop-color='#d14730')

编辑注:我问Ana为什么她现在要使用Jade模板。她说:我起初使用Haml模板是因为我想避免引入我不需要的循环变量,而之后使用Jade模板是因为它允许变量和计算。

这个渐变还没有旋转,因为 gradientTransform 的值是 rotate(0 .5 .5) 。其中后两个数值表示渐变旋转的坐标。其中 0 0 表示左上角, 1 1 表示右下角, .5 .5 表示中心。

实时效果如下:

See the Pen SVG linearGradient bottom to top rotated by 0deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

如果我们希望渐变从左到右,在CSS渐变中,我们把角度从 0deg 设置为 90deg 

CSS

background-image: linear-gradient(90deg, #e18728 50%, #d14730 0);

See the Pen CSS linear-gradient at 90deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

为了在SVG渐变中得到同样的结果,我们将 gradientTransform 的值设置为 rotate(90 .5 .5) 。

Jade

linearGradient#g(y1='100%' x2='0%' y2='0%' gradientTransform='rotate(90 .5 .5)')
  // same stops as before

See the Pen SVG linearGradient bottom to top rotated by 90deg with sharp stop at 50% by Ana Tudor (@thebabydino) on CodePen.

目前为止,一起正常。用SVG来代替CSS渐变并没有遇到太多问题。让我们尝试一下其他的角度。在下面的可交互demo中,左侧是一个CSS渐变,右边是一个SVG渐变。紫色的线是渐变线,它与金色和深红色的交界线是垂直的。拖拽滑块可以同时改变CSS和SVG的渐变角度。我们会看到一些错误:有些数值不是 90deg 的倍数。

See the Pen CSS vs. SVG gradient, same angle (interactive, responsive) by Ana Tudor (@thebabydino) on CodePen.

如以上demo所示,有些数值不是 90deg 的倍数,我们无法得到相同的结果。只有当我们设置渐变的元素是正方形时结果是相同的。这意味着我们可以给一个更大的正方形元素设置渐变,然后裁剪成实际的形状。然而做这些工作会让 element() 和 mask 来创建渐变倒影的方法更加复杂。

 

HTML标记

两只动物都使用嵌套的HTML部分对身体部位进行分组。分组的概念对于创造逼真的动画效果非常重要——当头部移动时,眼睛和耳朵也应该保持一起移动,因为它们是长在头上的。

<!-- Markup for the fox head -->
<div class="fox-head">
  <div class="fox-face">            
    <div class="fox-ears">
      <div class="fox-ear"></div>
      <div class="fox-ear"></div>
    </div>
    <div class="fox-skull"></div>
    <div class="fox-front"></div>
    <div class="fox-eyes"></div>
    <div class="fox-nose"></div>
  </div>
</div>

<!-- Markup for the husky head -->
<div class="husky-head">
  <div class="husky-ear"></div>
  <div class="husky-ear"></div>
  <div class="husky-face">
    <div class="husky-eye"></div>
    <div class="husky-eye"></div>
    <div class="husky-nose"></div>
    <div class="husky-mouth">
      <div class="husky-lips"></div>
      <div class="husky-tongue"></div>
    </div>
  </div>
</div>

每个部分均可以独立移动,并随着其父元素的移动而移动,这样会产生更逼真的效果。不知道你发现没有,尾巴是深深嵌套到其他尾部组件中的。当每个尾巴部分相对于其母体定位,然后旋转相同的量时,就会产生均匀曲线的视觉感。

图片 9

8.Raphael

Raphaël是一个JavaScript库,方便使用创建网站使用SVG矢量图形。VML创建图形,每个图形生成DOM对象,你可以操纵它们通过JavaScript。

图片 10

在线预览

 #Edge:可以全用SVG吗?

令人遗憾的是,以上提到的两种方法在Edge中都没有用。因此既能在Edge中运行又无需手动复制每个竖条的仅有的方法就是,放下前面的工作重新制作SVG加载器。这中方法具有跨浏览器的优势。

总的来说,我们创建一个带有 viewBox 的SVG元素,以便把 0 0 点放在中间。我们定义一个竖条,它的底边在x轴上,左边在y轴上。然后我们在 #loader 群组中根据需要复制(通过SVG use 元素)多次。我们如之前一样放置这些竖条的位置。

Jade

- var bar_w = 125, bar_h = 5 * bar_w;
- var n = 10;
- var vb_w = n * bar_w;
- var vb_h = 2 * bar_h;
- var vb_x = -.5 * vb_w, vb_y = -.5 * vb_h;

svg(viewBox=[vb_x, vb_y, vb_w, vb_h].join(' '))
  defs
    rect#bar(y=-bar_h width=bar_w height=bar_h)

  g#loader
    - for(var i = 0; i < n; i++) {
      - var x = (i - .5 * n) * bar_w;
      use(xlink:href='#bar' x=x)
    - }

 以上代码的效果如下:

See the Pen bar loader 2.3.1 creating and positioning SVG bars by Zongbin Niu (@nzbin) on CodePen.

现在我们已经创建了所有竖条,我们想把svg元素的位置调整的更准确而且我们使用flexbox属性。同时我们也和之前一样给竖条添加渐变色。我们用Sass做这些事情

SCSS

$n: 10;
$c: #63a6c1 #1e3f57;
$bar-w: 1.25em;
$bar-h: 5 * $bar-w;
$loader-w: $n * $bar-w;
$loader-h: 2 * $bar-h;

body {
  display: flex;
  justify-content: center;
  margin: 0;
  height: 100vh;
}

svg {
  align-self: center;
  width: $loader-w; height: $loader-h;
}

@for $i from 0 to $n {
  $args: append($c, $i * 100%/($n - 1));

  [id='loader'] use:nth-child(#{$i + 1}) {
    fill: mix($args...);
  }
}

 添加以上代码后的效果如下:

See the Pen bar loader 2.3.2 sizing + positioning the SVG & shading the bars by Zongbin Niu (@nzbin) on CodePen.

 

我们复制 #loader 群组(再次使用 use 元素)。我们通过 scale(1 -1) 方法镜像克隆体并且给它添加一个遮罩,和我们之前给伪类元素设置的一样。默认情况下,SVG元素相对于SVG画布的 0 0 点缩放,这个点正好位于加载器的底边上,可以很完美的将加载器镜像过来,我们不用设置 transform-origin 。

Jade/SVG

use(xlink:href='#loader' transform='scale(1 -1)')

我们使用 transform 属性代替CSS变换,因为CSS变换在Edge中不支持。

现在我们有了反射倒影,如下所示:

See the Pen bar loader 2.3.3 getting the reflection by Zongbin Niu (@nzbin) on CodePen.

 

最后一步就是用 mask 给反射添加渐变。它的方法及代码和之前都是一样的,我们不再赘述。所有的代码都在下面的Pen中

See the Pen bar loader 2.3.4 fading the reflection by Zongbin Niu (@nzbin) on CodePen.

 

 

用CSS塑造图形

CSS的border-radius属性大量用来塑造哈士奇的形象。对于许多元素要素,需要对每个边界半径进行逐个控制。例如,下面是如何构造哈士奇后腿的代码:

.husky-hind-leg {
  // ...
  border-top-left-radius: 35% 100%;
  border-top-right-radius: 40% 100%;
}

第一个数字表示曲线从顶部/底部边缘开始的深度,第二个数字表示曲线从左/右边缘开始的深度。

其他形状,如前腿,不能单独用border-radius成形,需要使用transform成形:

.husky-front-legs > .husky-leg:before {
  transform: skewY(-30deg) skewX(10deg);
  transform-origin: top right;
}

一旦图形就位,那么每个元素就能在其父元素中被赋予绝对的基于百分比的位置。这确保每个身体部位的精确放置以及响应性。

9.Snap.SVG

Snap是一个令人印象深刻的+免费的JavaScript库,简化了使用SVG和只注重现代浏览器的支持。这是最受欢迎的SVG库的开发人员创建,拉法ëL,和支持功能如掩蔽,裁剪,图案,全梯度,组,和更多。

图片 11

在线预览

动画

原始案例中的CSS动画很简单,就是用3D方式旋转竖条:

CSS

@keyframes bar {
  0% {
  transform: rotate(-.5turn) rotateX(-1turn);
  }
  75%, 100% { transform: none; }
}

 所有的竖条都是同样的动画:

CSS

animation: bar 3s cubic-bezier(.81, .04, .4, .7) infinite;

 我们只是给循环的竖条添加了不同的延迟时间。

SCSS

animation-delay: $i*50ms;

 因为我们希望旋转的竖条具有3D效果,所有我们给loader元素添加一个 perspective 属性

 但是使用 -webkit-box-reflect 方法后和预期的一样只能在WebKit浏览器中执行。

在Chrome浏览器中使用 -webkit-box-reflect 属性后的最终结果

我们同时添加了一张背景图片来看一下它的表现效果。只能在WebKit浏览器中预览的效果如下:

See the Pen bar loader 3.1 animating the bars by Zongbin Niu (@nzbin) on CodePen.

 

我们也尝试在Firefox中执行动画。但是,如果我们把动画添加到之前在Firefox中运行良好的代码中,好像出现了一些问题。

在Firefox中使用element()和mask方法做的动画雏形

 

这里有一点问题,下面的demo可以在Firefox中实时检测:

See the Pen bar loader 3.2.1 adding animation by Zongbin Niu (@nzbin) on CodePen.

 

第一个问题就是反射在伪类的边界处被切断。我们可以通过增加loader元素的尺寸来修复这一问题(伪类元素不受影响):

SCSS

$loader-w: ($n + 1) * $bar-w + $bar-h;

 但是我们对于其余的两个问题就束手无策了。当竖条进行3D旋转时,反射无法平滑的渲染更新;以及 perspective 属性导致了竖条的消失。

 添加perspective属性的结果                                                 没有添加perspective属性的结果

以下是实时的显示结果:

See the Pen bar loader 3.2.2 tweaks by Zongbin Niu (@nzbin) on CodePen.

全部都用SVG的方案怎么样?很不幸,上面的例子中,我们只用CSS的3D变化制作动画。在Edge中,SVG元素不支持CSS的变换属性,所以我们之前在创建倒影时使用了SVG的 transform 属性。但是 transform 属性是严格的2D模式,我们只能使用JavaScript添加动画。

所以就目前来看,想要制作一个兼容所有浏览器并且不用复制每一个竖条的加载动画是不可能了。我们现在能做的就是创建两个loader元素,每一个都有相同数量的竖条。

Haml

- 2.times do
  .loader
    - 10.times do 
      .bar

 竖条的样式和之前一样,我们使用 scale(-1) 来镜像第二个loader元素。

CSS

.loader:nth-child(2) {
  transform: scaleY(-1);
}

 我们添加竖条动画后得到如下结果:

See the Pen bar loader 3.3.1 reflection via duplication by Zongbin Niu (@nzbin) on CodePen.

现在我们需要给反射添加渐变。遗憾的是,我们不能在第二个loader元素上使用 mask ,因为它只在跨浏览器的SVG元素上有效。Edge目前还不支持HTML元素的遮罩效果,但是你可以给官方提建议。

我们只能在第二个loader元素上添加渐变背景。这样一来我们就不能使用图片背景了。渐变背景只在纯色背景或者有限的情况下才有效。我们在第二个loader元素的 ::after 上添加渐变背景并且设置的大一点,这样就不会挡住旋转的竖条。

SCSS

$bgc: #eee;
$cover-h: $bar-w + $bar-h;
$cover-w: $n * $bar-w + $cover-h;

html { background: $bgc; }

.loader:nth-child(2)::after {
  margin-left: -.5 * $cover-w;
  width: $cover-w; height: $cover-h;
  background: linear-gradient($bgc $bar-w, rgba($bgc, .3));
  content: '';
}

 最终结果如下:

See the Pen bar loader 3.3.2 emulate fading with cover by Zongbin Niu (@nzbin) on CodePen.

用SVG塑造图形

至于狐狸,Sass-SVG被用来为每个身体部位创建复杂的SVG形状。SVG图像可以用作背景图像,更好的是,只要它们是基于64或UTF-8编码的,就可以被内联编写(为了最大限度的浏览器支持)。

不过,SVG代码手写起来非常棘手。我使用Adobe Illustrator来创建初始形状:

图片 12

然后我将每个身体部分保存为SVG图像。SVG代码通过Sass-SVG传输到SCSS样式表。例如,这是狐狸的鼻子:

.fox-nose:before {
  @include svg((viewBox: (0 0 168 168))) {
    // the nose
    @include svg('path', (
      fill: $color-nose,
      d: 'M83.7,86.7c3.3,0,11.6-3.9,11.6-7.1c0-3.2-9.4-3.2-11.6-3.2c-2.2,0-11.6,0-11.6,3.2   C72.1,82.8,80.4,86.7,83.7,86.7z'
    ));

    // the line connecting the nose to the mouth
    @include svg('path', (
      stroke: $color-nose,
      fill: none,
      d: 'M83.7,102.3V86.7'
    ));

    // the mouth
    @include svg('path', (
      stroke: $color-nose,
      fill: none,
      d: 'M94.5,104.9c0,0-5.2-2.7-10.8-2.7c-5.6,0-10.8,2.7-10.8,2.7'
    ));
  }
}

这将在`url()`中生成一个编码的内联SVG字符串,看起来像这样:

.fox-nose:before {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg...");
}

由于SVG是一个背景图像,因此它可以被转换和动画化,就像一个HTML元素一样。使用Sass-SVG,Sass $variables可用于完全控制SVG填充和笔触颜色。

通过内联SVG使狐狸响应起来很简单。viewbox属性值((viewBox:(0 0 168 168)))直接来自SVG文件,但只要保持高/宽比率,那么包含SVG背景图像的元素可以是任意大小。狐狸头部的所有部分都是绝对定位的,具有与.fox-head相同的高度和宽度。

10.D3.js

D3.js是一种处理文件的基础上data.d3 JavaScript库可以帮助您将数据生命使用HTML,SVG和CSS。D3 基于Web标准的重点给你现代浏览器的全部功能,无需自己绑到一个专有的框架,结合功能强大的可视化组件和DOM操作一个数据驱动的方法。

图片 13

在线预览

 

“Squigglevision”和SVG滤镜

Squigglevision是一种通过摆动形状轮廓来模拟手绘动画的动画技术。这使得像狐狸和哈士奇这样的场景看上去更加动态化和手绘化,即使动物在不动的时候也是如此。

SVG有一个称为<feTurbulence>的滤镜,可以给任何应用了此滤镜的地方“噪声”。结合<feDisplacementMap>滤镜以指定像素在每个过滤器中移动的距离。

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <filter id="squiggly-0">
      <feTurbulence id="turbulence" baseFrequency="0.02" numOctaves="3" result="noise" seed="0"/>
      <feDisplacementMap id="displacement" in="SourceGraphic" in2="noise" scale="2" />
    </filter>
    <filter id="squiggly-1">
      <feTurbulence id="turbulence" baseFrequency="0.02" numOctaves="3" result="noise" seed="1"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="3" />
    </filter>

    <filter id="squiggly-2">
      <feTurbulence id="turbulence" baseFrequency="0.02" numOctaves="3" result="noise" seed="2"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="2" />
    </filter>
    <filter id="squiggly-3">
      <feTurbulence id="turbulence" baseFrequency="0.02" numOctaves="3" result="noise" seed="3"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="3" />
    </filter>

    <filter id="squiggly-4">
      <feTurbulence id="turbulence" baseFrequency="0.02" numOctaves="3" result="noise" seed="4"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="1" />
    </filter>
  </defs> 
</svg>

属性的任何元素。要创建“squigglevision”效果,关键帧动画快速地一次设置一个滤镜

@keyframes squigglevision {
  0% {
    -webkit-filter: url('#squiggly-0');
    filter: url('#squiggly-0');
  }
  25% {
    -webkit-filter: url('#squiggly-1');
    filter: url('#squiggly-1');
  }
  50% {
    -webkit-filter: url('#squiggly-2');
    filter: url('#squiggly-2');
  }
  75% {
    -webkit-filter: url('#squiggly-3');
    filter: url('#squiggly-3');
  }
  100% {
    -webkit-filter: url('#squiggly-4');
    filter: url('#squiggly-4');
  }
}

注意:这些SVG滤镜目前在Firefox中似乎不起作用,因此可以将这样的滤镜动画视为一种渐进增强处理。

11.Path.js

Paths.js是一种生成SVG路径,然后可以一起使用一个模板引擎喜欢胡子或把手的形状显示SVG在浏览器的JavaScript库,它提供了三个API,增加抽象。

图片 14

在线预览

 

给动物添加动画特效

CSS关键帧不能为我们提供一种方便的排序和组合动画的方法。解决这个问题的最好方法是将动画计划(故事板)作为时间轴,并使用预处理器,如Sass,生成关键帧。

例如狐狸,在概述每个动画应发生的故事板之后,转换和绝对时间偏移(秒)被用于对每个身体部分进行动画处理。以下是SCSS中对狐狸鼻子进行概述的一个例子:

$animations: (
  // ...

  'nose': (
    // resting position
    (4s, 5s, 7s): rotateY(-4deg),

    // nose down
    4.5s: rotateY(-4deg) rotateX(-3deg),

    // fox looks left
    (7.5s, 9s): rotateX(-3deg) rotateY(-28deg) rotateZ(-11deg),

    // fox looks right
    (9.5s, 12s): rotateY(7deg),

    // fox looks straight ahead
    13s: rotateY(0),
  ),

  // ...
);

在这里,$animations是一类Sass map,其中键是动画的名称(例如“nose”)。每个动画名称的值是另一个map,其中键是以秒为单位的偏移或偏移列表(例如(7.5s,9s)),并且值是每个偏移键的transform属性。

那么,我们怎么把这个map变成@keyframe动画呢?首先,设置全局的$duration: 17s变量——这将是每个动画的总持续时间。然后,使用嵌套的Sass @each ... in ... 循环,我们可以通过对$animations map循环为每个动画生成预期的CSS @keyframe声明:

@each $animation-name, $animation in $animations {
  // keyframe declaration
  @keyframes #{$animation-name} {
    @each $offsets, $transform in $animation {
      @each $offset in $offsets {
        // offset declaration block    
        #{percentage($offset / $duration)} {
          // transform property
          transform: #{$transform};
        }
      }
    }
  }
}

这将生成如下所示的关键帧:

@keyframes nose {
  14.70588% {
    transform: rotateY(-4deg); }
  23.52941% {
    transform: rotateY(-4deg); }
  29.41176% {
    transform: rotateY(-4deg); }
  41.17647% {
    transform: rotateY(-4deg); }
  26.47059% {
    transform: rotateY(-4deg) rotateX(-3deg); }
  44.11765% {
    transform: rotateX(-3deg) rotateY(-28deg) rotateZ(-11deg); }
  52.94118% {
    transform: rotateX(-3deg) rotateY(-28deg) rotateZ(-11deg); }
  55.88235% {
    transform: rotateY(7deg); }
  70.58824% {
    transform: rotateY(7deg); }
  76.47059% {
    transform: rotateY(0); } }

在不使用SCSS的情况下,这些百分比的计算可能非常繁琐。它们代表动画的每个步骤中每个所需时间值相对于总$duration的百分比偏移量。

然后可以将动画应用于它们各自的身体部位,例如animation: nose $duration none infinite;。每个动画的持续时间都得是一样的,这样它们可以无缝循环。

12.SVG.js

SVG.js一种工作的JavaScript库(操作和动画)与SVG没有任何复杂性。图书馆是独立的,大小很轻(5KB gzip压缩)和拥有大量特色。有内置的方法创建的形状(矩形、圆、多边形等)或图像定义。他们都是动画的尺寸,位置、颜色或任何其他性质,可以与标准的JavaScript事件的相互作用。

图片 15

在线预览

最后的思考

 我们需要一个更好的跨浏览器解决方案。我相信制作物体的反射并不需要像我们在这个例子中做的一样复制所有的子元素。为了制作可以放置背景图像的渐变反射,我们不能替换成SVG的方案(其自身也有很多问题)。

哪一种方案更好? -webkit-box-reflect 还是 element() + mask ?我也不知道。我个人喜欢同时使用。

虽然使用 :reflection 伪类元素 看上去很合理,但是我曾经确信我不想使用额外的元素制作反射。但是现在有比不用插入额外元素更让我喜欢的事情。使用 element() 可以在不同方向上自由创建多个反射,以及用不同的方式变换反射,比如3D旋转或者倾斜。这正是我喜欢它的原因。而且用SVG做遮罩意味着我们可以在反射上应用更复杂的遮罩同时获得更酷的效果。

另一方面,能力越强,责任越大。也许你没有时间去接触强大功能背后的复杂细节。有时你只是想要一个简单的方法来获得一个简单的结果。

 

原文地址: 译者:nzbin 友情提示:该文章篇幅较长,内容庞杂,...

逼真的Easing Curves

制作动画的另一个重要组成部分是看上去要逼真,所以要为动画的每个部分仔细选择(或创建)Easing Curves。最为生动的Easing Curves是“正弦曲线”——换句话说,是平滑起伏的Easing Curves。这样一来,自然动作就不会僵硬地起动或停止,animation-timing-function应该能反映出来。

对于狐狸和哈士奇,我使用cubic-bezier(0.645, 0.045, 0.355, 1)(在这里预览)。此曲线(见下文)开始略快,然后平稳地停住。当然,最好试验曲线以找到最适合动画的那种。

图片 16

最后:在Chrome中,你可以直观地检查所有排序的动画,以确保它们在正确的时间发生。你只需打开控制台,单击Style选项卡,然后单击播放按钮即可:

希望本教程可以帮助启发你创建更多的序列CSS动物动画!

13.Jim Knopf

Jim Knopf是一个用于创建SVG功率旋钮的JavaScript库,库doesn不需要任何JS框架和它的各种各样的旋钮,旋钮可以缩放类型,创建完全(由于SVG)和自己的设计可自定义的CSS。同时,他们可以用鼠标滚轮控制,键盘或触摸板和选项设置最小/最大值存在,出发点和角度允许。

图片 17

在线预览

14.Seen.js

Seen.js渲染3D场景为SVG或HTML5 canvas.seen.js包含顶部的SVG和HTML5的canvas元素的图形处理能力的一个简单的抽象,所有本库中的其他组件的上下文类型将呈现在不可知的。

图片 18

在线预览

15.Bonsai

BonsaiJS是一个直观的图形API和SVG渲染轻量级图形库。主要功能包括建筑分流道和渲染,iframe,工人和节点运行环境、形状、路径、资产(视频、图像、字体,subMovies),关键帧和普通动画(宽松的功能),形状/路径变形,和更多…

图片 19

在线预览

本文固定链接: 

上一篇:没有了 下一篇:没有了

更多阅读

付费投稿计划,SVG是最流行的和正在被众

前端 2020-04-11
本文由码农网 –小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!...
查看全文

yacc对一些关键词进行匹配,这个C文件主

前端 2020-04-11
在这之前,我曾经尝试过一个项目,就是将我们的PHP代码自动生成so扩展, 声明:原创作品,...
查看全文

每个公司都有自己的面试标准,付费投稿

前端 2020-04-11
本文由码农网 –小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!...
查看全文

友情链接: 网站地图

Copyright © 2015-2019 http://www.koi-bumi.com. 韦德体育有限公司 版权所有