72 lines
2.1 KiB
JavaScript
Raw Normal View History

import tinygradient from 'tinygradient';
// An internal function to help with easily creating SVG elements with an object of attributes
export const svgElem = (type, attrs) => {
const elem = document.createElementNS('http://www.w3.org/2000/svg', type),
attributes = Object.keys(attrs);
for (let i = 0; i < attributes.length; i++) {
const attr = attributes[i];
elem.setAttribute(attr, attrs[attr]);
}
return elem;
};
// An internal function to help with the repetition of adding fill, stroke, and stroke-width attributes
export const styleAttrs = (fill, stroke, strokeWidth, progress) => {
const determineColor = (type, progress) =>
typeof type === 'string' ? type : tinygradient(type).rgbAt(progress);
const attrs = {};
if (stroke) {
attrs['stroke'] = determineColor(stroke, progress);
attrs['stroke-width'] = strokeWidth;
}
if (fill) {
attrs['fill'] = determineColor(fill, progress);
}
return attrs;
};
// An internal function to convert any array of samples into a "d" attribute to be passed to an SVG path
export const segmentToD = samples => {
let d = '';
for (let i = 0; i < samples.length; i++) {
const { x, y } = samples[i],
prevSample = i === 0 ? null : samples[i - 1];
if (i === 0 && i !== samples.length - 1) {
d += `M${x},${y}`;
} else if (x !== prevSample.x && y !== prevSample.y) {
d += `L${x},${y}`;
} else if (x !== prevSample.x) {
d += `H${x}`;
} else if (y !== prevSample.y) {
d += `V${y}`;
}
if (i === samples.length - 1) {
d += 'Z';
}
}
return d;
};
// An internal function for getting the colors of a segment, we need to get middle most sample (sorted by progress along the path)
export const getMiddleSample = samples => {
const sortedSamples = [...samples].sort((a, b) => a.progress - b.progress);
return sortedSamples[(sortedSamples.length / 2) | 0];
};
// An internal function for converting any D3 selection or DOM-like element into a DOM node
export const convertPathToNode = path =>
path instanceof Element || path instanceof HTMLDocument ? path : path.node();