Prevent Svg Animation From Starting Again

Animations are a ubiquitous function of the web. Unlike the flashing GIF images that plagued websites in the net's earlier days, today's animations are more than subtle and tasteful. Designers and front-end specialists use them to make websites await more polished, enhance the user experience, phone call attention to important elements, and convey information.

Spider web developers can benefit from combining the power of SVG and CSS to create animations without using external libraries. This SVG animation tutorial shows how to build custom animations for real-world projects.

SVG Blitheness Using CSS: Core Concepts

Before animating SVGs with CSS, developers demand to understand how SVGs work internally. Fortunately, it'due south like to HTML: We define SVG elements with XML syntax and manner them with CSS, simply as if they were HTML.

SVG elements are purposely built for cartoon graphics. Nosotros tin use <rect> for drawing a rectangle, <circumvolve> for cartoon circles, etc.—SVG as well defines <ellipse>, <line>, <polyline>, <polygon>, and <path>.

Note: The full list of SVG elements fifty-fifty includes <animate>, which allows you to create animations using synchronized multimedia integration language (SMIL). However, its future is uncertain and the Chromium team recommends using a CSS- or JavaScript-based approach to animating SVGs whenever possible.

The bachelor attributes depend on the element, so while <rect> has width and height attributes, the <circle> chemical element has the r attribute, which defines its radius.

Three basic SVG elements (a rectangle, circle, and line) and their available attributes. The rectangle is defined past the ten- and y-coordinates of its top-left corner, also as its width and peak, eastward.thousand., <rect x="25" y="25" width="150" height="100"/>. The circle is defined past the x- and y-coordinates of its center (cx, cy) followed by its radius (r), e.chiliad., <circle cx="75" cy="75" r="50"/>. The line is divers using start coordinates (x1 and y1) and end coordinates (x2 and y2), e.k., <line x1="40" y1="140 x2="140" y2="40"/>.
Select basic SVG elements; coordinates are relative to the origin (the tiptop-left corner of the SVG viewport).

While most HTML elements can have children, most SVG elements cannot. One exception is the group element <thou>, which we can use in order to employ CSS styles and transformations to multiple elements at one time.

The <svg> Chemical element and Its Attributes

Some other important deviation betwixt HTML and SVG is how we position elements, notably via the viewBox attribute of a given outer <svg> chemical element. Its value consists of four numbers separated by whitespace or a comma: min-x, min-y, width, and height. Together, these specify how much of our SVG drawing nosotros want the browser to return. That expanse will be scaled to fit the premises of the viewport, as divers past the width and height attributes of the <svg> element.

When information technology comes to letterboxing, the ratio of the width and height attributes of the viewport may indeed differ from the ratio of the width and height parts of the viewBox attribute.

By default, the aspect ratio of the SVG sail will exist preserved at the expense of a larger-than-specified viewBox, thereby causing a smaller, letterboxed rendering within the viewport. But you can specify a different beliefs via the preserveAspectRatio attribute.

This allows united states of america to describe images in isolation and exist confident that all elements will be positioned correctly no affair the context or rendering size.

An image showing how a viewBox is rendered into a viewport with a different aspect ratio while preserving the aspect ratio of the contents. On the left, a rectangular viewBox has an isometric cube centered in it. On the right, a larger square viewport has the same isometric cube, centered and scaled up, while maintaining the aspect ratio of the cube.
Maintaining the attribute ratio of an image via letterboxing.

While you can lawmaking SVG images past hand, more than complex images may crave a vector graphics program (our SVG animation tutorial demonstrates both techniques). My editor of choice is Affinity Designer, but any editor should provide enough functionality for the simple operations covered hither.

CSS Transitions and Animations

CSS transitions let the states to define the rate and duration of property changes. Instead of jumping instantly from the starting value to the finish value, the values transition smoothly as in this case in which the color of an SVG circle changes when you hover over it with a mouse:

Come across the Pen Transition case by Filip Defar (@dabrorius) on CodePen.

We tin can define transitions with the transition property, which accepts the name of the property that nosotros want to transition, the duration of the transition, a transition timing role (besides known every bit easing function), and the length of the filibuster before the effect begins:

          /* property name | duration | easing function | delay */ transition: margin-right 4s ease-in-out 1s;                  

We can ascertain transitions for multiple CSS properties, each of which can have separate transition values. However, there are two obvious limitations to this approach.

The outset limitation is that transitions are triggered automatically when a property value changes. This is inconvenient in some utilize cases. For example, we can't accept an animation that loops infinitely.

The second limitation is that transitions e'er have ii steps: the initial state and the final state. We tin can extend the duration of the animation, but nosotros can't add different keyframes.

This is why a more powerful concept exists: CSS animations. With CSS animations, nosotros tin have multiple keyframes and an space loop:

Encounter the Pen Animation example by Filip Defar (@dabrorius) on CodePen.

To animate CSS properties over multiple keyframes, first nosotros need to define the keyframes using an @keyframes at-rule. The timing of keyframes is defined in relative units (percentages) considering at this point, we haven't yet defined the animation duration. Each keyframe describes the values of one or more than CSS properties at that bespeak in time. CSS animations will ensure shine transitions between keyframes.

We apply the animation with described keyframes to the desired chemical element using the animation property. Similar to the transition property, information technology accepts a elapsing, an easing office, and a filibuster.

The only difference is that the first parameter is our @keyframes name instead of a property name:

          /* @keyframes name | duration | easing-role | delay */ animation: my-sliding-animation 3s linear 1s;                  

At present that we have a basic understanding of how animative SVGs works, nosotros can first building a classic animation—a menu toggle that smoothly transitions between a "hamburger" icon and a close push (an "10"):

See the Pen Hamburger by Filip Defar (@dabrorius) on CodePen.

This is a subtle but valuable blitheness. It attracts the user's attending, informing them that the icon can be used to close the menu.

We start our demonstration by creating an SVG element with three lines:

          <svg class="hamburger">   <line x1="0" y1="50%" x2="100%" y2="l%"     course="hamburger__bar hamburger__bar--top" />   <line x1="0" y1="50%" x2="100%" y2="50%"     form="hamburger__bar hamburger__bar--mid" />   <line x1="0" y1="50%" x2="100%" y2="50%"     grade="hamburger__bar hamburger__bar--bot" /> </svg>                  

Each line has two sets of attributes. The x1 and y1 correspond the coordinates of the showtime of the line, while x2 and y2 represent the coordinates of the end of the line. We've used relative units to set positions. This is a unproblematic way to ensure that image contents get resized to fit the containing SVG chemical element. While this approach works in this case, there is one large drawback: We can't maintain the aspect ratio of elements positioned this way. For that, we would take to utilize the viewBox attribute of the <svg> element.

Note that nosotros applied CSS classes to SVG elements. There are many properties that can be changed via CSS, then let's apply some basic styling to our SVG elements.

Nosotros'll set the size of the <svg> element, likewise as alter the cursor blazon to indicate that it's clickable. But to set the colour and thickness of the lines, we'll use the stroke and stroke-width backdrop. You might accept expected to use color or border, only unlike <svg> itself, SVG sub-elements are not HTML elements, and so they often have different property names:

          .hamburger {   width: 62px;   summit: 62px;   cursor: pointer; } .hamburger__bar {   stroke: white;   stroke-width: ten%; }                  

If nosotros render at this point, nosotros'll see that all three lines have the aforementioned size and position, overlapping each other completely. Unfortunately, we can't change the starting and ending positions independently via CSS, but we tin can move whole elements. Allow'due south move the meridian and bottom bars with the transform CSS holding:

          .hamburger__bar--acme {   transform: translateY(-40%); } .hamburger__bar--bot {   transform: translateY(40%); }                  

Past moving the bars on the Y axis we end upward with a decent-looking hamburger.

At present information technology's time to code our second state: the shut push button. We rely on an .is-opened CSS course applied to the SVG element to toggle between the two states. To make the effect more accessible, allow'south wrap our SVG in a <push> element and handle clicks on that level.

The process of adding and removing the course will be handled by a simple JavaScript snippet:

          const hamburger = document.querySelector("push button"); hamburger.addEventListener("click", () => {   hamburger.classList.toggle("is-opened"); });                  

In gild to create our X, we can apply a different transform property to our hamburger bars. Because the new transform property will override the old one, our starting point will exist the original, shared position of the three bars.

From there, nosotros can rotate the top bar 45 degrees clockwise around its eye, and rotate the bottom bar 45 degrees counterclockwise. We tin shrink the middle bar horizontally until it is narrow plenty to be hidden behind the center of the X:

          .is-opened .hamburger__bar--meridian {   transform: rotate(45deg); } .is-opened .hamburger__bar--mid {   transform: scaleX(0.1); } .is-opened .hamburger__bar--bot {   transform: rotate(-45deg); }                  

By default, the transform-origin belongings for SVG elements is commonly 0,0. This means that our bars will be rotated around the top-left corner of the viewport, only nosotros want them to rotate around the middle. To gear up this, let's set the transform-origin belongings to heart for the .hamburger__bar grade.

Animating CSS Properties With transition

The transition CSS holding tells the browser to smoothly transition between two different states of CSS backdrop. Hither we want to animate our changes to the transform belongings, which dictates the positions, orientation, and scale of the bars.

We can also control the duration of the transition using the transition-elapsing belongings. To make the animation look snappy, we'll set a brusque duration of 0.iii seconds:

          .hamburger__bar {   transition-property: transform;   transition-duration: 0.3s;   ... }                  

The just piece of JavaScript nosotros demand is the bit that makes the icon state toggleable:

          const hamburger = document.querySelector("button"); hamburger.addEventListener("click", () => {   hamburger.classList.toggle("is-opened"); });                  

Here, we select the outer SVG element by its .mute class using querySelector(). We then add together a click event listener. When a click effect is triggered, nosotros toggle the .is-active course merely on the <svg> itself—no deeper in the hierarchy. Because we fabricated the CSS blitheness only apply to elements with the .is-active class, toggling this course will activate and conciliate the animation.

As a final impact, we'll convert the HTML torso to a flex container, which volition help usa center the icon horizontally and vertically. Nosotros'll also update the groundwork colour to a very nighttime gray and the icon colour to white, to attain a sleek "night mode" look and feel:

          body {   brandish: flex;   justify-content: eye;   marshal-items: center;   background-colour: #222;   height: 100vh; }                  

With that, nosotros've built a fully functional animated push button using some bones CSS and a brusk JavaScript snippet. It's easy to alter the transformations we've applied to brand a diversity of animations. Readers can simply fork the CodePen—which includes a scrap of extra CSS for smooth—and get creative.

Working With SVG Data From External Editors

Our hamburger menu is extremely simple. What if we want to make something more than complex? That'south where coding SVG by manus becomes difficult and vector graphics editing software tin help.

Our 2nd SVG animation is a mute push showing a headphones icon. When the music is active, the icon volition drum and trip the light fantastic; when it'due south muted, the icon will be crossed out:

See the Pen Mute button - five - red strikethrough by Filip Defar (@dabrorius) on CodePen.

Drawing icons would be outside of the scope of this tutorial (and probably your job description), and then we are going to start with a pre-drawn SVG icon. We'll also want the same trunk styling as our hamburger menu example.

You might want to clean up the SVG code before working with it. You tin can do this with svgo, an open-source, Node.js-based SVG optimizer tool. This will remove unnecessary elements and brand the lawmaking easier to edit by hand, which you will need to do in gild to add classes and combine different elements.

SVG icons created in image editing software are unlikely to utilise relative units. Additionally, we want to make certain that the icon's aspect ratio is maintained, regardless of the aspect ratio of the SVG element containing it. To brand this level of control possible, we will use the viewBox attribute.

It'due south a adept thought to resize the SVG so that viewBox can be set to some easy-to-employ values. In this case, I've converted it to a viewBox that is 100 x 100 pixels.

Allow's make sure the icon is centered and appropriately sized. We'll apply the mute class to our base SVG element and then add the following CSS styles:

          .mute {   fill: white;   width: 80px;   top: 70px;   cursor: arrow; }                  

Here, the width is slightly greater than the height to avert clipping during the rotations of our animation.

Our SVG Animation Starting Indicate

The now-clean SVG contains a single <chiliad> chemical element that contains 3 <path> elements.

The path element allows the states to draw lines, curves, and arcs. Paths are described with a series of commands that describe how the shape should be drawn. As our icon consists of iii unconnected shapes, we have three paths to depict them.

The one thousand SVG element is a container used to group other SVG elements. We use it to apply the pulsating and dancing transformations on all iii paths simultaneously.

          <svg course="mute" viewBox="0 0 100 100">   <g>     <path d="M92.six,50.075C92.213,26.775 73.25,vii.938 50,7.938C26.75,vii.938 7.775,26.775 7.388,fifty.075C3.112,51.363 -0.013,55.425 -0.013,60.25L-0.013,72.7C-0.013,78.55 4.575,83.3 10.238,83.3L18.363,83.3L18.363,51.6C18.iv,51.338 18.438,51.075 18.438,50.813C18.438,33.275 32.6,19 l,19C67.4,xix 81.563,33.275 81.563,fifty.813C81.563,51.088 81.6,51.338 81.638,51.6L81.638,83.313L89.763,83.313C95.413,83.313 100.013,78.563 100.013,72.713L100.013,sixty.263C100,55.438 96.875,51.362 92.half-dozen,l.075Z" />     <path d="M70.538,54.088L70.538,79.588C70.538,81.625 72.188,83.275 74.225,83.275L74.225,83.325L78.662,83.325L78.662,50.4L74.225,50.4C72.213,fifty.4 lxx.538,52.063 lxx.538,54.088Z" />     <path d="M25.75,50.4L21.313,50.4L21.313,83.325L25.75,83.325L25.75,83.275C27.788,83.275 29.438,81.625 29.438,79.588L29.438,54.088C29.45,52.063 27.775,50.four 25.75,50.4Z" />   </g> </svg>                  

To make the headphones drum and dance, transition won't suffice. This is an example that is complex enough to need keyframes.

In this case, our starting and catastrophe keyframes (at 0% and 100% of the animation, respectively) use a slightly shrunken headphones icon. For the get-go xl% of the animation we abound the image slightly and tilt it 5 degrees. Then, for the adjacent 40% of the animation, nosotros scale it dorsum down to 0.9x and rotate it 5 degrees to the other side. Finally, for the terminal 20% of the animation, the icon transformation returns to the same initial parameters in lodge to loop smoothly.

          @keyframes pulse {   0% {     transform: scale(0.9);   }   twoscore% {     transform: scale(1) rotate(5deg);   }   fourscore% {     transform: calibration(1) rotate(-5deg);   }   100% {     transform: scale(0.9) rotate(0);   } }                  

CSS Animation Optimizations

To show how keyframes work, we left our keyframe CSS more verbose than information technology needs to exist. At that place are 3 means we could shorten it.

Since our 100% keyframe sets the entire transform listing, if we were to omit rotate() entirely, its value would default to 0:

                          100% {     transform: scale(0.9);   }                      

Secondly, we know we want our 0% and 100% keyframes to match because we're looping the blitheness. By defining them with the same CSS rule, we won't take to remember to alter both of them if we want to alter this shared point in the animation loop:

                          0%, 100% {     transform: scale(0.9);   }                      

Lastly, we'll before long use transform: scale(0.9); to the mute__headphones class, and when nosotros practise, we won't need to ascertain the starting and catastrophe keyframes at all! They'll default to the static mode used by mute__headphones.

Now that we've defined the blitheness keyframes, we tin employ the animation. We add the .mute__headphones course to the <g> element so that it affects all 3 parts of the headphones icon. First, nosotros in one case again gear up transform-origin to center as nosotros want the icon to rotate around its center. We also calibration it so that its size matches the initial animation keyframe. Without this footstep, switching from the static "muted" icon to the blithe one will always issue in a sudden jump in size. (Either style, switching dorsum to muted will crusade a jump in calibration—and probable rotation too—if the user clicks while the scale is larger than 0.9x. Nosotros can't do much most that effect with CSS alone.)

Nosotros apply the blitheness using the animation CSS property but just when the .is-agile parent class is present, like to how we animated our hamburger menu.

          .mute__headphones {   transform-origin: center;   transform: calibration(0.9); } .is-active .mute__headphones {   animation: pulse 2s infinite; }                  

The JavaScript we need to permit u.s. switch between states follows the same pattern equally the hamburger carte du jour too:

          const muteButton = certificate.querySelector(".mute"); muteButton.addEventListener("click", () => {   muteButton.classList.toggle("is-active"); });                  

The next slice we'll add together is a strikethrough line that appears when the icon is inactive. Equally this is a uncomplicated design chemical element, nosotros tin can code information technology manually. This is where having simple and reasonable viewBox values is useful. We know that the edges of the canvass are at 0 and 100 so it is piece of cake to summate the get-go and cease positions for our line:

          <line x1="12" y1="12" x2="88" y2="88" class="mute__strikethrough" />                  

Resizing vs. Using Relative Units

A case tin can be made for using relative units instead of resizing the image. This applies in our example considering we are adding but a uncomplicated SVG line over our icon.

In real-globe scenarios you might want to combine more circuitous SVG content from several unlike sources. This is where making them all a uniform size is useful, as nosotros can't manually difficult-code the relative values similar we did in our example.

Considering we applied a class directly to our strikethrough <line> element, we tin style it via CSS. We merely need to make sure that the line is not visible when the icon is active:

          .mute__strikethrough {   stroke: cherry-red;   opacity: 0.8;   stroke-width: 12px; } .is-active .mute__strikethrough {   opacity: 0; }                  

Optionally, nosotros can add the .is-active class directly to the SVG. This will brand the blitheness kickoff as soon as the folio is loaded, and then nosotros finer change the initial state of the icon from non-animated (muted) to blithe (non-muted).

CSS-based SVG Animation Is Here to Stay

We've only scratched the surface of CSS blitheness techniques and how viewports work. It's worth knowing how to write SVG code by hand to keep simple animations uncomplicated, but it's too important to know how and when to make use of graphics created with external editors. While mod browsers enable us to create impressive animations using only built-in functionality, for (very) complex employ cases, developers might want to explore blitheness libraries like GSAP or anime.js.

Animations don't have to be reserved for extravagant projects. Modern CSS blitheness techniques allow us to create a broad array of engaging and polished animations in a simple, cantankerous-browser-uniform way.


Special thanks to Mike Zeballos for this article's technical review!

barringtonsampe1980.blogspot.com

Source: https://www.toptal.com/css/svg-animation-css-tutorial

0 Response to "Prevent Svg Animation From Starting Again"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel