Libraries for SVG Drawing Animations
Strategy

Libraries for SVG Drawing Animations


In 2013, Jake Archibald introduced this cool trick of animating an SVG path to look like it’s drawing itself. It’s 2020 now, and the trick is still popular. I’ve seen it on a lot of websites I’ve visited recently. I, too, feature an animated SVG loader on my website using one of the libraries I’ll introduce below.

In a previous article, Chris Coyier wrote about how SVG path animations work under the hood, using the CSS stroke-dasharray and stroke-dashoffset properties. In this article, I want to introduce you to four JavaScript libraries that can be used to create SVG path drawing animations with fewer lines of code, like this cool example. Why a library? Because they’re ideal for complex animations involving two or more SVGs with multiple paths.

To get started, l’ll first secure an SVG to demo. Let’s use this castle from svgrepo. The castle SVG downloads as an SVG image. But, since we’re dealing with path animation, what we need is the code format of the SVG. To get this, I’ll import the file into Figma and use the “Copy as SVG” feature (Right Click → Copy/Paste → Copy as SVG) to grab the SVG code.

To successfully animate an SVG path, the SVG shape should have a fill of none and each individual SVG path must have a stroke (we’ll set it to #B2441D) and a stroke-width (set to 2px).

The animation effect we want to create is to first draw the outline (or stroke) of the SVG and then fill in the different colors. In total, there are six different fill colors used throughout the SVG, so we’ll remove the fill color from each path and give paths of the same color the same class name.

  • #695A69: color-1
  • #B2441D: color-2
  • #DFDOC6: color-3
  • #C8B2A8: color-4
  • #DE582A: color-5
  • #AO8A8A: color-6

After all the modifications, here’s what the SVG code looks like:


<svg id="svg-castle" width="480" height="480" viewBox="0 0 480 480" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M231.111 183.761V150.371C231.111 149.553 231.774 148.889 232.592 148.889H24  7.407C248.225 148.889 248.889 149.552 248.889 150.371V183.761L258.342 206.667H271.111  V135.556H240H208.889V206.667H221.658L231.111 183.761Z" stroke="#B2441D" stroke-width="2px" class="color-6" />
  <path d="M311.111 420H288.889V455.556V468.889H311.111V455.556V420Z" stroke="#B2441D"   stroke-width="2px" class="color-1" />
  <path d="M191.111 420H168.889V455.556V468.889H191.111V455.556V420Z" stroke="#B2441D" stroke-width="2px" class="color-1" />
  <path d="M168.889 220V228.889V237.778H222.222V228.889H212.487L221.658 206.667H208.88   9H169.524L177.778 220H168.889Z" stroke="#B2441D" stroke-width="2px" class="color-2"/ >
  <!-- etc. -->
</svg>

That’s all the SVG preparation we need. Let’s look at how to achieve the desired animation with the different libraries.

Library 1: Vivus

Vivus is a lightweight JavaScript class (with no dependencies) that allows you to animate SVGs like they’re being drawn. The library is available using any of these options. To keep things simple, we’ll use a CDN link:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js" integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ==" crossorigin="anonymous"></script>

Next, let’s create a new Vivus instance. It takes three arguments:

  1. The ID of the target element (the SVG)
  2. An options object with a dozen possible values
  3. A callback function that runs at the end of the animation

Looking back at our SVG code, the SVG ID is svg-castle.

new Vivus('svg-castle', { 
  duration: 200, type:'oneByOne'
});

Now, let’s write a callback function that fills the paths with the different colors we’ve defined:

function fillPath(classname, color) {
  const paths = document.querySelectorAll(`#svg-castle .${classname}`);
  for (path of paths){
    path.style.fill = `${color}`;
  }
}

The fillPath function selects all paths in the svg-castle element with the supplied classname, loops through and fills each path with the specified color. Remember in a previous step, we removed the fill from each path and gave each path a same fill class (color-1, color-2, etc.).

Next up, we call the fillPath function for the six different classnames and their corresponding colors:

function after() {
  fillPath('color-1', '#695a69');
  fillPath('color-2', '#b2441d');
  fillPath('color-3', '#dfd0c6');
  fillPath('color-4', '#c8b2a8');
  fillPath('color-5', '#de582a');
  fillPath('color-6', '#a08a8a')
}

That’s the callback function passed to the Vivus instance. See Pen for full implementation.

Library 2: Walkway.js

Walkway is a light-weight SVG animation library for path, line and polygon elements. To start using it, we can either add the library using npm, yarn, or with a CDN link like we did with Vivus. We’ll go with the CDN link once again:

<script src="https://cdn.jsdelivr.net/npm/walkway.js/src/walkway.min.js"></script>

With Walkway, we create a new Walkway instance, passing an options object as an argument. Then, we call the draw method on the new instance and pass in an optional callback function which will be run at the end of the draw animation. Again, very much like Vivus.

We’ve already written the after callback function in the previous example, so the rest should be a piece of cake:

const svg = new Walkway({
  selector: '#svg-castle',
  duration: 3000,
});

svg.draw(after);

Library 3: Lazy Line Painter

Lazy Line Painter is a modern JavaScript library for SVG path animation. It requires minimal code to setup. However, if a GUI is more of your thing, you can use the Lazy Line Composer which is a free online editor for SVG path animation from the same makers. The SVG will be exported as an animated SVG file that can be used directly anywhere.

The basic setup for Lazy Line Painter is similar to what we’ve already done in the other examples. First, get the library using either npm or a CDN link. Just like the previous examples, we’ll use a CDN link:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/lazy-line-painter-1.9.4.min.js"></script>

Then, we initialize a new LazyLinePainter instance, which accepts two parameters — a selector (the ID of the target SVG element) and a config object. Let’s call the paint method on the new instance:

// select the svg by id
let svg = document.querySelector('#svg-castle')

// define config options
let options = {
  strokeDash: '2, 2',
}
// initialize new LazyLinePainter instance
let myAnimation = new LazyLinePainter(svg, options)

// call the paint method
myAnimation.paint()

A full list of config options are available in the library docs. Unlike the previous libraries, we don’t pass a callback function to the paint method. Instead, we’ll listen for the complete:all event handler on the animation and then pass in the callback function.

myAnimation.on('complete:all', (event) => {after()});

We can also control when the paint method runs using event listeners like we’ve have done in the following codepen demo. Click on the castle to re-run the animation.

Library 4: Framer Motion

Framer Motion is a bit different from other libraries we’ve covered. It’s a production-ready open-source animation library for React components with tons of possible animation types. And, yes, this is from the same team behind the popular Framer prototyping tool.

First up, we’ll install the library with npm in the terminal:

npm install framer-motion

For SVG path drawing animations, Framer Motion provides a motion.path component that takes four props:

<motion.path
  d={pathDefinition}
  initial={{ pathLength: 1, pathOffset: 0 }}
  animate={{ pathLength: 0, pathOffset: 1 }}
  transition={{ duration: 2 }}
/>

To use it, we’ll simply convert our SVG paths to motion.path, like this:

import React from 'react';
import { motion } from "framer-motion";
const AnimatedCastle = () => {
  return (
    <svg id="svg-castle" width="480" height="480" viewBox="0 0 480 480" fill="non            e" xmlns="http://www.w3.org/2000/svg">
      <motion.path d="M311.111 420H288.889V455.556V468.889H311.111V455.556V420Z"              stroke="#B2441D" stroke-width="2" className="color-1"
       initial={{ pathLength: 1,fill:"none", opacity:0, }}
       animate={{ pathLength: 0,fill:"695A69", opacity:1 }}
       transition={{ duration: 2 }}
      />
      <motion.path d="M191.111 420H168.889V455.556V468.889H191.111V455.556V420Z"                stroke="#B2441D" stroke-width="2" className="color-2"
        initial={{ pathLength: 1, fill:"none", opacity:0, }}
        animate={{ pathLength: 0, fill:"#b2441d", opacity:1}}
        transition={{ duration: 3 }}
      />
         
      <!-- etc. -->
    </svg>
  )
}

This has to be done for each SVG path. See this demo for full implementation:

There’s a caveat though: the castle SVG has over 60 paths, which is a lot. Going through them was quite daunting for me, and I found the process to be repetitive and prone to errors. For that reason, I don’t recommend Framer Motion but I would say that it is well suited for SVGs within React components with no more than five paths. For anything more than that, go with any of the previous libraries we covered.

That’s a look at four JavaScript libraries we can use to get hand-drawn SVG effects.

Why didn’t we cover a CSS-only solution? While it’s possible to do, it involves a lot of code repetition. For example, it means finding the total length of each path using JavaScript or with this cool trick that sets each path length to 1, and then sets the stroke-dasharrray and stroke-dashoffset of each path to its path length.

After that, we still need to define keyframes to animate the stroke-dashoffset to zero. Then, those keyframe animations will be added to each path and with an animation-delay to offset things a bit. We also have to write six different keyframe rules to fill the paths with their respective colors. Considering that the castle has over 60 individual paths, that’s over 100 lines of CSS! Not exactly the most efficient or straightforward approach.



Source link

The Cleanest Trick for Autogrowing Textareas
Strategy

The Cleanest Trick for Autogrowing Textareas


Earlier this year I wrote a bit about autogrowing textareas and inputs. The idea was to make a <textarea> more like a <div> so it expands in height as much as it needs to in order to contain the current value. It’s almost weird there isn’t a simple native solution for this, isn’t it? Looking back at that article, none of my ideas were particularly good. But Stephen Shaw’s idea that I linked to toward the end of it is actually a very good idea for this, so I wanted to shine some light on that and talk through how it works, because it seems like it’s the final answer to how this UX can be done until we get something native and better.

Here’s the demo in case you just want a working example:

The trick is that you exactly replicate the content of the <textarea> in an element that can auto expand height, and match its sizing.

So you’ve got a <textarea>, which cannot auto expand height.

Instead, you exactly replicate the look, content, and position of the element in another element. You hide the replica visually (might as well leave the one that’s technically-functional visible).

Now all three elements are tied to each other. Whichever of the children is tallest is will push the parent to that height, and the other child will follow. This means that the minimum height of the <textarea> will become the “base” height, but if the replicated text element happens to grow taller, everything will grow taller with it.

So clever. I love it so much.

You need to make sure the replicated element is exactly the same

Same font, same padding, same margin, same border… everything. It’s an identical copy, just visually hidden with visibility: hidden;. If it’s not exactly the same, everything won’t grow together exactly right.

We also need white-space: pre-wrap; on the replicated text because that is how textareas behave.

This is the weirdest part

In my demo, I’m using ::after for the replicated text. I’m not sure if that’s the best possible approach or not. It feels clean to me, but I wonder if using a <div aria-hidden="true"> is safer for screen readers? Or maybe the visibility: hidden; is enough for that? Anyway, that’s not the weird part. This is the weird part:

content: attr(data-replicated-value) " ";

Because I am using a pseudo-element, that’s the line that takes the data attribute off the element and renders the content to the page with that extra space (that’s the weird part). If you don’t do that, the end result feels “jumpy.” I can’t say I entirely understand it, but it seems like it respects the line break behavior across the textarea and text elements better.

If you don’t want to use a pseudo-element, hey, fine with me, just watch for the jumpy behavior.


Special high fives to Will Earp and Martin Tillmann who both randomly emailed on the same exact day to remind me how clever Shaw’s technique is. Here’s an example Martin made with Alpine.js and Tailwind that also ends up kinda like a one-liner (but note how it’s got the jumpy thing going on).

I’m sure ya’ll could imagine how to do this with Vue and React and whatnot in a way that can very easily maintain state across a textarea and another element. I’m not going to include examples here, partially because I’m lazy, but mostly because I think you should understand how this works. It will make you smarter and understand your site better.



Source link

Indesign question
Strategy

Indesign question


Indesign question

I have been trying to figure out why Indesign is spacing like this. Does anyone know to fix this? So far the only solution I have found is re typing, but I feel like there is an easier way.

https://preview.redd.it/6tz70vpdpmy51.png?width=976&format=png&auto=webp&s=cfc21ef64d3c583a38247bc399781a2ea31ac577

submitted by /u/Toxic_Avenger94
[comments]



Source link

r/webdev - How does one make a Carousel with text instead of dots ?
Strategy

How does one make a Carousel with text instead of dots ? : w…


I have been trying to make a damned carousel for the past 2 days and for the life of me, I cannot do it on my own.

First, I’ve tried this: https://splidejs.com/ . Had no idea how to customize it or how to actually make it work.

Next, I’ve gave https://gs-shop.github.io/vue-slick-carousel/#/example/simple a try, but after a great start, I ended up with a broken carousel that couldn’t even play the simplest of the examples.

Now I am looking at Bootstrap, but I cannot find a carousel example that suits my need. Every carousel guide/tutorial online looks the same. I’ve also tried the basic example but it does not work… I don’t even know if I installed it correctly because every documentation says something else. This is how I’ve installed it:

npm i bootstrap jquery popper.js
npm install bootstrap-vue

And I am trying to use only the Carousel component, because I don’t need the rest.
So, inside a component I’ve done this:
<div class="portfolio-lower">
<BCarousel
id="carousel-1"
v-model="slide"
:interval="4000"
controls
indicators
background="#ababab"
img-width="1024"
img-height="480"
style="text-shadow: 1px 1px 2px #333"
u/sliding-start="onSlideStart"
u/sliding-end="onSlideEnd"
>
<BCarouselSlide
caption="First slide"
text="Nulla vitae elit libero, a pharetra augue mollis interdum."
img-src="@/assets/images/image1.jpg"
></BCarouselSlide>
<BCarouselSlide
caption="Second slide"
text="Nulla vitae elit libero, a pharetra augue mollis interdum."
img-src="@/assets/images/image2.jpg"
></BCarouselSlide>
</BCarousel>
</div>

import { BCarousel } from "bootstrap-vue";
import { BCarouselSlide } from "bootstrap-vue";

components: { BCarousel, BCarouselSlide },

And this is the result:

r/webdev - How does one make a Carousel with text instead of dots ?

it overflows to the next page

I need 2 carousels:

r/webdev - How does one make a Carousel with text instead of dots ?

this

r/webdev - How does one make a Carousel with text instead of dots ?

that

That’s all I need. And I cannot do it on my own. I have to accept defeat and get some help.

Please help this noob web-dev learn how to create a carousel.

Thank you.



Source link

r/web_design - Can you guys help me with this question on CSS gradients?
Strategy

Can you guys help me with this question on CSS gradients? : …


I’m trying to have the background colors of three stacks of divs melt into each other on both a horizontal and vertical level. I’ve managed to make it work for the horizontal boxes using linear-gradient, but as you can see below there is an obvious separating line between the vertical rows. Is there a way to make the boxes transition into the ones below them as well? I’m using pure css on this, perhaps there is another (better) way?

My CSS:

#canvas {
 width: 100%;
 display: block;
 clear: both;
 margin: 0 0 1em;
}

.row {
 width: 100%;
}

.cell {
 width: 10%;
 height: 5em;
 float: left;
}

.clear {
 clear: both;
}

#box_0x0 {
 background: linear-gradient(to right,rgb(223,207,40),rgb(208,115,69));
}
#box_0x1 {
 background: linear-gradient(to right,rgb(208,115,69),rgb(105,166,166));
}

#box_1x0 {
 background: linear-gradient(to right,rgb(75,204,178),rgb(245,255,71));
}
#box_1x1 {
 background: linear-gradient(to right,rgb(245,255,71),rgb(67,102,113));
}

#box_2x0 {
 background: linear-gradient(to right,rgb(185,28,75),rgb(204,114,21));
}
#box_2x1 {
 background: linear-gradient(to right,rgb(204,114,21),rgb(238,156,125));
}

My html:

<div id="canvas">
  <div class="row">
    <div class="cell box_0x0" id="box_0x0"></div>
    <div class="cell box_0x1" id="box_0x1"></div>
    <div class="clear"></div>
  </div>
  <div class="row">
    <div class="cell box_1x0" id="box_1x0"></div>
    <div class="cell box_1x1" id="box_1x1"></div>
    <div class="clear"></div>
  </div>
  <div class="row">
    <div class="cell box_2x0" id="box_2x0"></div>
    <div class="cell box_2x1" id="box_2x1"></div>
    <div class="clear"></div>
  </div>
</div>
r/web_design - Can you guys help me with this question on CSS gradients?



Source link

X and Y not relative to artboard anymore (see desc)
Strategy

X and Y not relative to artboard anymore (see desc)


X and Y not relative to artboard anymore (see desc)

Why do the X and Y coordinates suddenly not stay relative to the artboard? It should say x:0 and y:0 now. Its inside the artboard because when i nod it the right the amount becomes larger.

https://preview.redd.it/txvztzi6dly51.png?width=827&format=png&auto=webp&s=6134933d120a211458db6e74f7a354fefeda80e5

submitted by /u/Mr-Scrubs
[comments]



Source link

r/webdev - Console cleared?
Strategy

Console cleared? : webdev


I have found for the first time that the webpage is clearing my logs in the console in Safari with an adblocker. I managed to reproduce this behavior in Chrome without uBO. I think that some kind of JavaScript is clearing logs automatically. Can someone shine a light on this? Why would the webpage do this?

I’m still learning and haven’t got to JavaScript yet. I’m still on HTML & CSS. Chrome with uBO blocks that JavaScript so the log is present there.

r/webdev - Console cleared?



Source link

r/graphic_design - What kind of sticker / product label is this?
Strategy

What kind of sticker / product label is this? : graphic_desi…


This is somewhat graphic design adjacent – not sure where else to ask on reddit.

I’m designing a product label that will go on a product we distribute from a supplier. We’re keeping one of the supplier stickers on and replacing one of theirs with ours.

For consistency’s sake, I’d like our sticker to have the same look and feel as the suppliers.

Does anyone know what kind of sticker this is? It feels plasticy and has about the same bend as about 200GSM paper. The thing that makes it interesting is that it appears the black text is printed from the back, then coated with the silver, then the glue. There is no way to scratch the text off from the front of the label. This makes sense as these products are liable to be outside in all sorts of weather and industrial conditions.

So, any ideas? I’ve googled high tack, industrial, vinyl, die cut, kiss cut, metallic, foil, plastic, stickers, product labels, permanent. But it really looks like it’s a specialised process that I don’t know the name of, so my searching is fruitless.

r/graphic_design - What kind of sticker / product label is this?
r/graphic_design - What kind of sticker / product label is this?



Source link

r/graphic_design - how to add Glossy effect to a shampoo bottle in photoshop?
Strategy

how to add Glossy effect to a shampoo bottle in photoshop? :…


i need help to understand how to add the glossy effect to this bottle, i tried but it end very bad

if anyone know short tutorial or post tp explain this, will be really nice.

the way i want it is like this dove bottle but not transparent

i appreciation your help.

here the photos i want like this in my shampoo bottle

im not looking to do the transparent part, i just want the glossy finish in the white area in dove bottles.. see the image for clarity.

r/graphic_design - how to add Glossy effect to a shampoo bottle in photoshop?

i want the glossy effect in this.

r/graphic_design - how to add Glossy effect to a shampoo bottle in photoshop?

i want glossy effects like this one in the up above shampoo bottle

i appreciation your help.



Source link