如何制作SVG虚线动画?

时间:2019-06-21 14:00:58

标签: javascript html css animation svg

我尝试用HTML(SVG)/ CSS / JS制作虚线动画。

这是我的第一个svg动画...很明显...我什么都不懂。

首先,这是我的虚线:

<svg id="bf7de8ba-cf75-48ab-a36c-06f8d86635d5" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 690.814 824.302">
  <defs>
    <style>
      .a00cb6af-c716-4d00-9962-797e598003da,
      .a6fde9f6-9a2f-4715-ac34-678948a4d015,
      .b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
        fill:none;
        stroke-miterlimit:10;
        stroke-width:6px;
      }
      .a6fde9f6-9a2f-4715-ac34-678948a4d015 {
        stroke:url(#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0);
      }
      .b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
        stroke-dasharray:30.322 50.536;
        stroke:url(#a958eb71-8928-4250-a898-e2a9df336375);
      }
      .a00cb6af-c716-4d00-9962-797e598003da {
        stroke:url(#a8cb66bd-35fa-45ad-b9b6-1af210f764d2);
      }
    </style>
    <linearGradient id="bef7cd12-3404-46dc-ac0f-c9d91ddd83d0" x1="60.835" y1="123.864" x2="751.668" y2="123.864" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#ec6608"/>
      <stop offset="0.494" stop-color="#c33089"/>
      <stop offset="1" stop-color="#662483"/>
    </linearGradient>
    <linearGradient id="a958eb71-8928-4250-a898-e2a9df336375" x1="60.835" y1="541.828" x2="751.668" y2="541.828" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
    <linearGradient id="a8cb66bd-35fa-45ad-b9b6-1af210f764d2" x1="60.835" y1="932.54" x2="751.668" y2="932.54" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
  </defs>
  <path class="a6fde9f6-9a2f-4715-ac34-678948a4d015" d="M748.213,116.426c.215,4.461.381,9.478.436,14.992" transform="translate(-60.835 -116.281)"/>
  <path id="pathRecrut" class="b963f74d-80cb-4571-80bd-9cf5cd28cce2" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916" transform="translate(-60.835 -116.281)"/>
  <path class="a00cb6af-c716-4d00-9962-797e598003da" d="M81.983,925.674a117,117,0,0,0,6.74,13.39" transform="translate(-60.835 -116.281)"/>
</svg>

在codepen上查看:https://codepen.io/Unrillaz/pen/gNmgjW

我已经用Illustrator(adobe)实现了。

因此,我尝试为这一行设置动画,并且遵循CSS-TRICKS教程:https://css-tricks.com/scroll-drawing/

AND .... TADA!我有什么:

             // Get a reference to the <path>
var path = document.querySelector('#pathRecrut');

// Get length of path... ~577px in this case
var pathLength = path.getTotalLength();

// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;

// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;

// Jake Archibald says so
// https://jakearchibald.com/2013/animated-line-drawing-svg/
path.getBoundingClientRect();

// When the page scrolls...
window.addEventListener("scroll", function(e) {
 
  // What % down is it? 
  // https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript/2387222#2387222
  // Had to try three or four differnet methods here. Kind of a cross-browser nightmare.
  var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
    
  // Length to offset the dashes
  var drawLength = pathLength * scrollPercentage;
  
  // Draw in reverse
  path.style.strokeDashoffset = pathLength - drawLength;
    
  // When complete, remove the dash array, otherwise shape isn't quite sharp
 // Accounts for fuzzy math
  if (scrollPercentage >= 0.99) {
    path.style.strokeDasharray = "none";
    
  } else {
    path.style.strokeDasharray = pathLength + ' ' + pathLength;
  }
  
});
<svg id="bf7de8ba-cf75-48ab-a36c-06f8d86635d5" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 690.814 824.302">
  <defs>
    <style>
      .a00cb6af-c716-4d00-9962-797e598003da,
      .a6fde9f6-9a2f-4715-ac34-678948a4d015,
      .b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
        fill:none;
        stroke-miterlimit:10;
        stroke-width:6px;
      }
      .a6fde9f6-9a2f-4715-ac34-678948a4d015 {
        stroke:url(#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0);
      }
      .b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
        stroke-dasharray:30.322 50.536;
        stroke:url(#a958eb71-8928-4250-a898-e2a9df336375);
      }
      .a00cb6af-c716-4d00-9962-797e598003da {
        stroke:url(#a8cb66bd-35fa-45ad-b9b6-1af210f764d2);
      }
    </style>
    <linearGradient id="bef7cd12-3404-46dc-ac0f-c9d91ddd83d0" x1="60.835" y1="123.864" x2="751.668" y2="123.864" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#ec6608"/>
      <stop offset="0.494" stop-color="#c33089"/>
      <stop offset="1" stop-color="#662483"/>
    </linearGradient>
    <linearGradient id="a958eb71-8928-4250-a898-e2a9df336375" x1="60.835" y1="541.828" x2="751.668" y2="541.828" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
    <linearGradient id="a8cb66bd-35fa-45ad-b9b6-1af210f764d2" x1="60.835" y1="932.54" x2="751.668" y2="932.54" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
  </defs>
  <path class="a6fde9f6-9a2f-4715-ac34-678948a4d015" d="M748.213,116.426c.215,4.461.381,9.478.436,14.992" transform="translate(-60.835 -116.281)"/>
  <path id="pathRecrut" class="b963f74d-80cb-4571-80bd-9cf5cd28cce2" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916" transform="translate(-60.835 -116.281)"/>
  <path class="a00cb6af-c716-4d00-9962-797e598003da" d="M81.983,925.674a117,117,0,0,0,6.74,13.39" transform="translate(-60.835 -116.281)"/>
</svg>

在codepen上查看:https://codepen.io/Unrillaz/pen/ZdeezN

我不明白为什么在制作动画时这条线是牢固的。

我想要相同的动画。向下滚动时会填满一行,但我想使其保持虚线。您认为有可能吗?

1 个答案:

答案 0 :(得分:3)

标准的“线条绘制”技术使用变化的划线长度来模拟绘制效果。因此很明显,如果您的行已经有破折号图案,则该技术将无效。至少不是直接。

对此的最佳解决方案是将<mask>应用于虚线。面罩由一条覆盖原始线(虚线)的线组成。然后,我们使用标准的线条绘图破折号技术对蒙版中线条的版本进行动画处理。因此,可以缓慢地遮盖/显示原始虚线。

// Get a reference to the <path>
var path = document.querySelector('#pathRecrut');

// Get length of path... ~577px in this case
var pathLength = path.getTotalLength();

// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;

// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;

// When the page scrolls...
window.addEventListener("scroll", function(e) {
 
  // What % down is it? 
  // https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript/2387222#2387222
  // Had to try three or four differnet methods here. Kind of a cross-browser nightmare.
  var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
    
  // Length to offset the dashes
  var drawLength = pathLength * scrollPercentage;
  
  // Draw in reverse
  path.style.strokeDashoffset = pathLength - drawLength;
  
});
<svg id="bf7de8ba-cf75-48ab-a36c-06f8d86635d5" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 690.814 824.302">
  <defs>
    <style>
      .a00cb6af-c716-4d00-9962-797e598003da,
      .a6fde9f6-9a2f-4715-ac34-678948a4d015,
      .b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
        fill:none;
        stroke-miterlimit:10;
        stroke-width:6px;
      }
      .a6fde9f6-9a2f-4715-ac34-678948a4d015 {
        stroke:url(#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0);
      }
      .b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
        stroke-dasharray:30.322 50.536;
        stroke:url(#a958eb71-8928-4250-a898-e2a9df336375);
      }
      .a00cb6af-c716-4d00-9962-797e598003da {
        stroke:url(#a8cb66bd-35fa-45ad-b9b6-1af210f764d2);
      }
    </style>
    <linearGradient id="bef7cd12-3404-46dc-ac0f-c9d91ddd83d0" x1="60.835" y1="123.864" x2="751.668" y2="123.864" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#ec6608"/>
      <stop offset="0.494" stop-color="#c33089"/>
      <stop offset="1" stop-color="#662483"/>
    </linearGradient>
    <linearGradient id="a958eb71-8928-4250-a898-e2a9df336375" x1="60.835" y1="541.828" x2="751.668" y2="541.828" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
    <linearGradient id="a8cb66bd-35fa-45ad-b9b6-1af210f764d2" x1="60.835" y1="932.54" x2="751.668" y2="932.54" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
    
    <mask id="linemask">
      <path id="pathRecrut" fill="none" stroke="white" stroke-width="10" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916"/>
    </mask>
  </defs>
  <path class="a6fde9f6-9a2f-4715-ac34-678948a4d015" d="M748.213,116.426c.215,4.461.381,9.478.436,14.992" transform="translate(-60.835 -116.281)"/>
  <path class="b963f74d-80cb-4571-80bd-9cf5cd28cce2" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916" transform="translate(-60.835 -116.281)" mask="url(#linemask)"/>
  <path class="a00cb6af-c716-4d00-9962-797e598003da" d="M81.983,925.674a117,117,0,0,0,6.74,13.39" transform="translate(-60.835 -116.281)"/>
</svg>