n4ks
n4ks

Reputation: 148

How to draw a dashed svg path using anime.js?

I know about ways using the second path that overlaps the first, but this method does not work for me, since gradient is used for the background.

When I try to draw a dashed line using this example https://animejs.com/documentation/#lineDrawing then nothing works for me, are there any ways to solve this problem?

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <div>
    <svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='0 0 900 228' preserveAspectRatio='none'><path d='M20 0 L 880 0 a 20, 20, 0, 0, 1, 20, 20 L 900 208 a 20, 20, 0, 0, 1, -20, 20 L 20 228 a 20, 20, 0, 0, 1, -20, -20 L 0 15' fill='none' stroke='black' stroke-width='1.6' stroke-dasharray='5' /></svg>"
  </div>
</body>
</html>

CSS:

body {
  background-color: white;
}
div {
  width: 900px;
  height: 228px;
}

JS:

anime({
  targets: 'path',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutSine',
  duration: 3000,
  direction: 'alternate',
  loop: true
});

example with anime.js: https://codepen.io/n4ks/pen/vYXxboa

In both cases, the behavior is not what is expected. I need to draw a dashed line from point A to point B (from beginning to end)

Solution

If anyone has encountered the same problem I will leave this demo here, many thanks to Paul LeBeau for the help: https://codepen.io/n4ks/pen/ExmVxzY

Upvotes: 1

Views: 1878

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101956

To animate a dashed line, there's a cheat way, which is to animate a line that's on top of it, as you say.

The better way, though slightly more complicated, is to use a mask. You mask the dasked line with a matching line, and then animate the path that's in the mask.

Demo

anime({
  targets: '#mask-path',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutSine',
  duration: 3000,
  direction: 'alternate',
  loop: true
});
body {
  min-height: 500px;
  background: linear-gradient(135deg, linen, aqua);
}

div {
  width: 900px;
  height: 228px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<div>
  <svg width='100%' height='100%' viewBox='0 0 900 228' preserveAspectRatio='none'>
    <defs>
      <mask id="anim-mask">
        <path id="mask-path"
              d="M20 0 L 880 0 a 20, 20, 0, 0, 1, 20, 20 L 900 208 a 20, 20, 0, 0, 1, -20, 20 L 20 228 a 20, 20, 0, 0, 1, -20, -20 L 0 15"
              fill="none" stroke="white" stroke-width="3" />
      </mask>
    </defs>
    <path d="M20 0 L 880 0 a 20, 20, 0, 0, 1, 20, 20 L 900 208 a 20, 20, 0, 0, 1, -20, 20 L 20 228 a 20, 20, 0, 0, 1, -20, -20 L 0 15"
          fill="none" stroke="black" stroke-width="1.6" stroke-dasharray="5" mask="url(#anim-mask)"/>
  </svg>
</div>

Upvotes: 3

Related Questions