svg配合css3动画_使用CSS和Snap.svg的SVG动画

svg配合css3动画

Snap.svg

Today I wanted to share with you the ease of animation in SVG with the tools we have available to us today. SVG is still one of those subjects that can scare away a lot of developers, but I'm here to show you hopefully just how easy it can be.

今天,我想与大家分享我们今天可用的工具中SVG中动画的简便性。 SVG仍然是可以吓走很多开发人员的主题之一,但是我在这里是希望向您展示它多么容易。

While doing my usual search on the internet for inspiration, I came across this great post on From Up North. As you can see, there are some beautiful illustrations by Miguel Sousa aka Heymikel, Snack Studio, Martín Feijoó & Sara Enríquez. As soon as I saw the animations, the first thing that came to mind was how these could be made into SVG animations to be used freely on the internet.

当我在互联网上进行常规搜索以寻找灵感时,我在From Up North上看到了这篇很棒的文章 。 如您所见,Miguel Sousa aka Heymikel,Snack Studio,MartínFeijoó和SaraEnríquez提供了一些精美的插图。 当我看到动画时,首先想到的是如何将这些动画制作为SVG动画,以便在互联网上免费使用。

让我们开始吧 (Let's get to it)

There are a few different implementations, some with the focus more on the Snap.svg side of things, then also combining both Snap.svg and CSS animations.

有几种不同的实现,其中一些更着重于Snap.svg方面,然后还结合了Snap.svg和CSS动画。

制备 (Preparation)

The first part of any SVG project should be spent optimising your SVG's, hopefully in your case you have either created them yourself or will have a nice SVG supplied by your design team. Now rather than putting the vast subject of optimisation into this particular article. We recommend you check out this article by Sara Soueidan which has some great tools to help you out.

SVG项目的第一部分应该花在优化SVG上,希望在您的情况下,您可以自己创建它们,也可以由设计团队提供不错的SVG。 现在,而不是将广泛的优化主题放入此特定文章中。 我们建议您查看Sara Soueidan的 这篇文章 ,其中有一些很棒的工具可以帮助您。

The biggest thing that will make working with SVG a breeze is to be very organised with your layering and grouping. Remove all unused layers and group elements that you feel will be linked together in animation.

使SVG轻而易举的最大事情就是将您的分层和分组组织得井井有条。 删除所有您感觉将在动画中链接在一起的未使用的图层和组元素。

设置Snap.svg (Setting up Snap.svg)

The beauty of Snap.svg is that it is simple to get set up and gives us a tremendous amount of functionality out of the box to manipulate our SVG's. First step is to include it in our project; there are many ways to do this, which you can find here

Snap.svg的优点是易于设置,并为我们提供了开箱即用的大量功能来操作SVG。 第一步是将其包含在我们的项目中; 有很多方法可以做到这一点,您可以在这里找到

初始化Snap SVG元素 (Initialise Snap SVG element)

// HTML
<svg class="hill-valley article"></svg>

// JS
var s = new Snap('.hill-valley');

加载我们的外部SVG (Load our external SVG)

Snap.load('img/hill-valley.svg', function (response) {
    var hillValley = response;
    s.append(hillValley);
});

哥谭市动画 (Gotham City Animation)

The best thing to do with all your animations first is take a step back and think about exactly how you are going implement the animation and what needs to happen.

首先,最好对所有动画进行处理,然后退后一步,仔细考虑如何实施动画以及需要进行哪些操作。

So with this particular animation there are two main animations going on, one is the animation of the 'bat light' which if you look carefully also applies a clipping mask on to the text. The other, is the animation of the scene lighting up in relation to the 'bat light' turning on and flickering.

因此,对于这个特殊的动画,有两个主要的动画,一个是“蝙蝠灯”的动画,如果仔细看,还会在文本上应用剪贴蒙版。 另一个是与“蝙蝠灯”打开和闪烁有关的场景动画点亮。

场景照明动画 (Scene lighting animation)

We wanted to show you how easy it is to use CSS animations still to manipulate your SVG elements, so we decided for the lighting of this animation it would be perfect to show that.

我们想向您展示仍然使用CSS动画来操纵SVG元素有多么容易,因此我们决定为该动画的照明效果很好地展示出来。

We only add classes to the paths we wish to manipulate and then we are away by just creating keyframe animations. In the code example below I will only do this for WebKit, but you should make sure you have all the correct vendor prefixes.

我们仅将类添加到希望操纵的路径,然后仅通过创建关键帧动画就可以了。 在下面的代码示例中,我将仅对WebKit执行此操作,但是您应确保拥有所有正确的供应商前缀。

.gotham__background {
  -webkit-animation: background-anim 7s infinite linear;  
}

@-webkit-keyframes background-anim {
  0%, 10%, 
  21%, 23%,
  25%, 27%,
  37%, 55%,
  57%, 61%,
  63%,
  80%   { fill: #333738; }
  11%, 20%, 22%, 24%, 28%, 36%, 38%,
  54%, 56%, 58%, 62%, 64%,
  79% { fill: #6D6C6D; }
}

蝙蝠灯动画 (Bat light animation)

The central component of the background animation is that we take full advantage of SVG's clipping masks. Meaning, we can show the title text as soon as our clip path rolls over it. The animation itself is a pretty simple one; it is just a rotate and scroll concurrently. We do take advantage of the available easing algorithms built into snap.svg. For more information on what these algorithms do take a look at a CodePen I made here.

背景动画的核心部分是我们充分利用了SVG的剪贴蒙版。 意思是,我们可以在剪辑路径滚动到标题文本后立即显示标题文本。 动画本身是一个非常简单的动画。 它只是同时旋转和滚动。 我们确实利用了snap.svg中内置的可用缓动算法。 有关这些算法的更多信息,请查看我在此处制作CodePen

To create a clipping mask in SVG, we need to make sure that our path is defined in the clipping path SVG element, with an id attached to it. Then we apply the 'clip-path' attribute to the element we wish to mask and that sets up the clipping path. Here is what that code looks like:

要在SVG中创建剪贴蒙版,我们需要确保在剪切路径SVG元素中定义了我们的路径,并为其附加了ID。 然后,将“ clip-path”属性应用于要遮罩的元素,从而设置剪切路径。 该代码如下所示:

<clipPath id="b">
    <use xlink:href="#a" overflow="visible"/>
</clipPath>

<g clip-path="url(#b)"></g>

Now, let's get this animation sorted:

现在,让我们对动画进行排序:

// rotateElems is the element we wish to rotate
rotateElems = s.selectAll('.gotham__rotate')

rotateElems.animate({
    transform: 'r0,250,453 s1,1'
}, 1500, mina.elastic);


君临 (Kings Landing)

The Kings Landing animation has a few little tricks to make some of the animations feel more realistic. We will go into these further on, for now let's look at how we created the cloud animation and using snap.svg to dynamically add extra elements.

Kings Landing动画有一些小技巧,可以使某些动画更逼真。 我们将进一步研究这些内容,现在让我们看看如何创建云动画以及如何使用snap.svg动态添加额外的元素。

云动画 (Clouds Animation)

The beauty of SVG is that it allows us to reuse elements quickly. Whether it be a group, path or shape, it can even let you reference external resources (external resources have lower browser support). We can achieve this by using the use element, this simply references other objects on the page using the xlink:href attribute.

SVG的优点在于它使我们能够快速重用元素。 无论是组,路径还是形状,它甚至可以让您引用外部资源(外部资源对浏览器的支持较低)。 我们可以通过使用use元素来实现此目的,该元素仅使用xlink:href属性引用页面上的其他对象。

One thing to note, if you have fill or stroke attributes on the original path, these will also be on every element no matter what you have defined on the use element. Therefore, if you want to reuse parts and have individual attributes on them, then you are better to apply none to your master element and only apply to the individual elements.

需要注意的一件事是,如果您在原始路径上具有填充或笔触属性,则无论您在use元素上定义了什么,这些属性也将出现在每个元素上。 因此,如果要重复使用零件并在零件上具有单独的属性,则最好不将其应用于主元素,而仅将其应用于单个元素。

As we are going to animate clouds in multiple sizes and positions, it's better that we let snap.svg manage that process rather than it be hard coded into the SVG. All we do in the SVG is create our cloud path to be copied using the 'use' element.

当我们要对多种大小和位置的云进行动画处理时,最好让snap.svg管理该过程,而不是将其硬编码到SVG中。 在SVG中,我们要做的就是创建云路径,以使用“ use”元素进行复制。

The following creates a defined amount of clouds in a random layout, with an arbitrary scale:

以下内容以任意比例创建具有随机数量的定义数量的云:

var containerHeight = s.node.offsetHeight / 4,
    numberOfClouds = 10;

  // Gets the width of the container
  cloudWidth = s.select('#a').getBBox().w;

  // Creates a group element
  clouds = s.g();

  // Loop to create clouds
  for (var i = numberOfClouds; i >= 0; i—) {
    /** 
    x is a random number between 0 and the container width
    y is a random number between 0 and our container height
    newCloud creates a use element referencing our cloud path
    randomScale is a random number between 0.2 and 0.9
    **/
    var x = Math.floor(Math.random() * cloudWidth),
        y = -Math.floor(Math.random() * containerHeight),
        newCloud = cloud.use(),
        randomScale = Math.random() * (0.9 - 0.2) + 0.2;

    // Applies our new attributes to the use element
    newCloud.attr({
      x: x,
      y: y,
      transform: 's' + randomScale
    });

    // Adds the use element to our group
    clouds.add(newCloud);
  }

沿路径动画 (Animate along a path)

One thing that snap.svg, doesn't do out of the box is give a method to allow you to animate over a particular path. It's not a massive issue though as we can utilise the Snap.animate method, this allows us to manipulate the animation frame by frame.

snap.svg不能立即使用的一件事是提供一种方法,使您可以对特定路径进行动画处理。 尽管我们可以利用Snap.animate方法,但这并不是一个大问题,这使我们可以逐帧处理动画。

All we now need to do is get the path we wish to animate along. Then with a little bit of code, get its points at each frame of the animation and apply them to the element being animated. Here is the function:

现在我们需要做的就是获得我们希望动画化的道路。 然后用一点点代码,在动画的每个帧处获取其点,并将其应用于正在动画的元素。 这是函数:

/**
  path is the path we wish with to animate along
  element is the element we want to animate
  start is the frame we wish to start the animation on
  dur is the duration in milliseconds
  callback is a function we wish to call once the animation has finished
**/
animateAlongPath = function (path, element, start, dur, callback) {
  // Get the path length, so we know how many frames we will animate over
  var len = Snap.path.getTotalLength(path);

  Snap.animate(start, len, function (value) {
    // movePoint gets the path attributes at a certain frame
    var movePoint = Snap.path.getPointAtLength(path, value);

    // applies the attributes to our element
    element.attr({ cx: movePoint.x, cy: movePoint.y });
  }, dur, mina.easeinout, function () {
    callback(path);
  });
};


希尔山谷 (Hill Valley)

The animation for the Hill Valley SVG has four principal components, with this particular animation we will use the easing algorithms provided by Snap.svg.

Hill Valley SVG的动画具有四个主要组成部分,对于此特定动画,我们将使用Snap.svg提供的缓动算法。

汽车动画 (Car animation)

This animation is just a simple translation combined with a rotation. The only thing that makes it more complex is because of the easing; it can make it appear difficult to achieve.

该动画只是结合了旋转的简单平移。 使它变得更复杂的唯一原因是宽松。 这会使它看起来很难实现。

/**
  car is our SVG car element
  carStartMatrix and carMidMatrix initialises our Snap Matrix
**/

var car = s.select('.car'),
  carStartMatrix = new Snap.Matrix(),
  carMidMatrix = new Snap.Matrix();

// Sets up the matrix transforms
carStartMatrix.rotate(10);
carStartMatrix.translate(0,-50);
carMidMatrix.rotate(-15);
carMidMatrix.translate(300,-20);

car.animate({
  transform: carStartMatrix
}, 1250, mina.easeinout, function () {
  car.animate({
    transform: carMidMatrix
  }, 250);
});

树动画 (Tree animation)

The tree animation is a two part rotate animation to get more of a realistic bend during the animation. If the leaves were the same colour we could have used a path transform for the animation, but in our case the two-part animation was the better option.

树动画是一个分为两部分的旋转动画,可以在动画过程中获得更多逼真的弯曲。 如果叶子是相同的颜色,我们可以对动画使用路径变换,但是在我们的情况下,两部分动画是更好的选择。

It's a pretty simple concept, all we do is animate the whole tree by a small amount, and then at the same time we animate the leaves of the tree further. We can also take full advantage of the excellent easing algorithms that snap.svg has built into it. Here is how to achieve that:

这是一个非常简单的概念,我们要做的只是对整个树进行少量动画处理,然后同时对树的叶子进行动画处理。 我们还可以充分利用snap.svg内置的出色的缓动算法。 这是实现该目标的方法:

/**
  leaves are the leaves element we want to rotate
  leavesDim is the bounding box dimension of leaves
  tree is the tree element we want to rotate
  treeDim is the bounding box dimension of the tree
**/
var leaves = s.select('leaves'),
  leavesDim = leaves.getBBox();

leaves.animate({
  transform: 'r25,' + (leavesDim.x + (leavesDim.width / 2)) + ',' + (leavesDim.y + leavesDim.height)
}, 20, mina.easeinout, function (){

  // This animation triggers once the other has finished
  leaves.animate({
    transform: 'r0,' + (leavesDim.x + (leavesDim.width / 2)) + ',' + (leavesDim.y + leavesDim.height)
  }, 1000, mina.elastic);
});

tree.animate({
  transform: 'r8,' + (treeDim.x + (treeDim.width / 2)) + ',' + (treeDim.y + treeDim.height)
}, 20, function () {

  // This animation triggers once the other has finished
  tree.animate({
    transform: 'r0,' + (treeDim.x + (treeDim.width / 2)) + ',' + (treeDim.y + treeDim.height)
  }, 1000, mina.elastic);
});

时钟动画 (Clock animation)

The clock animation is a relatively straightforward operation. The only thing you have to be careful with rotations is that if it rotates 360 degrees or more, then a further rotate applied; the animation will go the wrong direction.

时钟动画是一个相对简单的操作。 您唯一需要注意的旋转问题是,如果旋转360度或以上,则会进行进一步的旋转。 动画会走错方向。

You can see this in our following animation routine, let us take it that this line of code is being called in a loop. As you can see, we reset the rotated transform, so the animation keeps resetting.

您可以在下面的动画例程中看到这一点,让我们以为这行代码正在循环中被调用。 如您所见,我们重置了旋转的变换,因此动画不断重置。

var s.select('.minute');

// Resets to 0
clockMinute.transform('r0,195.5,105.5');

// Animates 360 degrees around the point 195.5,105.5 over 1250 ms
clockMinute.animate({
    transform: 'r90,195.5,105.5'
},1250)

文字动画 (Text animation)

The structure for the text animation is relatively straightforward; we just create five 'use' elements which reference the main text. Then on queue we trigger an animation which translates all the elements linearly to the top right of the initial text element.

文本动画的结构相对简单。 我们只创建五个引用主要文本的“ use”元素。 然后在队列中,我们触发一个动画,该动画将所有元素线性转换为初始文本元素的右上角。

/**
    textiles selects all of the .text elements, this is stored as an array
    amount is the max translation value divided by text elements on the page
**/
var textElems = s.selectAll('.text'),
        amount = 20/textElems.length;

// Loops through each element
for (var i = 1; i < textElems.length; i++) {

    // Initiates the animation to translate to the correct position
    textElems[i].animate({
        'transform': 't' + (amount * i) + ',-' + (amount * i)
    }, 200, mina.easeinout);
};


Hopefully, that has given you a bit of insight into how easy it is to animate SVG and create striking imagery. If you have any questions, please do not hesitate to get in touch via all the links below. The wonderful thing about SVG animation is it will happily work in all modern browsers and IE9 upwards. As you will see in my animations above where I use keyframe animation of CSS, you can just use snap.svg to do the same.

希望这使您对SVG动画和创建引人注目的图像有多么容易。 如有任何疑问,请随时通过以下所有链接与我们联系。 SVG动画的妙处在于它可以在所有现代浏览器和IE9以上版本中愉快地工作。 正如您在上面的动画中使用CSS的关键帧动画所看到的那样,您可以仅使用snap.svg来执行相同的操作。

翻译自: https://davidwalsh.name/svg-animations-snap

svg配合css3动画

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值