Vladyslav Babenko
Vladyslav Babenko

Reputation: 1369

D3: Draw merged lines as a single

Is it possible to merge two lines into one and animate it as single? Here is an example what I have:

const line1 = 'M0,100V100H0V0';
const line2 = 'M-200,200V200H0V100';

const path = d3.select('#line')
    .attr('d', line1 + line2);
const pathLength = path.node().getTotalLength();

function _interpolateDashOffset () {;
  const interpolate = d3.interpolateNumber(pathLength, pathLength * 2);
  return () => time => interpolate(time);
}

d3.select('#line')
  .attr('fill', 'none')
  .attr('stroke', 'black')
  .attr('stroke-width', 8)
  .attr('stroke-dasharray', `${pathLength} ${pathLength}`)
  .transition()
  .ease(d3.easeLinear)
  .duration(2000)
  .attrTween('stroke-dashoffset', _interpolateDashOffset())
  .on('end', () => {
    console.log('path animation ended');
});

Demo: jsfiddle

(it uses es6, only FF and chrome can open w/o errors)

As you see the lines were combined into one and than animated. But animation draws a line in the bottom and then at the top. Is it possible somehow combine these lines into one and animate as a single line?

Desired behavior: jsfiddle

(it's just one line and I want two see such behavior with combined lines)

Thanks

Upvotes: 1

Views: 523

Answers (2)

Vladyslav Babenko
Vladyslav Babenko

Reputation: 1369

One of possible solution is to properly merge lines: For example, We have

const line1 = 'M0,100V100H0V0';
const line2 = 'M200,200V200H0V100';
const line3 = 'M200,300V300H200V200'

In my case I am drawing a path from bottom to top. I am taking last path, I need to know final coordinates of line3 and than merging lines without M (moveto): line3 + line2 (without 'M') + line1 (without 'M'). As result I have:

const mergedLine = 'M200,300V300H200V200 V200H0V100 V100H0V0';

Final solution: jsfiddle

Upvotes: 0

Ashitaka
Ashitaka

Reputation: 19203

It is possible. I think what's confusing you is the fact that in SVG the coordinate system origin is at the top-left corner, which means that y increases downwards. This chart should be helpful: https://sarasoueidan.com/blog/svg-coordinate-systems/#initial-coordinate-system

These 2 paths should be animated correctly:

const line1 = 'M0,300V-100';
const line2 = 'M0,-200V-200';

Here's a working jsfiddle.

Also, you are animating your path backwards. That is, you are drawing the path from bottom to top, but then the animation is running from top to bottom. I'm not sure if this is intended or not.

Upvotes: 1

Related Questions