UNPKG

@remotion/shapes

Version:

Generate SVG shapes

129 lines (128 loc) 4.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.joinPoints = void 0; const shortenVector = (vector, radius) => { const [x, y] = vector; const currentLength = Math.sqrt(x * x + y * y); const scalingFactor = (currentLength - radius) / currentLength; return [x * scalingFactor, y * scalingFactor]; }; const scaleVectorToLength = (vector, length) => { const [x, y] = vector; const currentLength = Math.sqrt(x * x + y * y); const scalingFactor = length / currentLength; return [x * scalingFactor, y * scalingFactor]; }; const joinPoints = (points, { edgeRoundness, cornerRadius, roundCornerStrategy, }) => { return points .map(([x, y], i) => { const prevPointIndex = i === 0 ? points.length - 2 : i - 1; const prevPoint = points[prevPointIndex]; const nextPointIndex = i === points.length - 1 ? 1 : i + 1; const nextPoint = points[nextPointIndex]; const middleOfLine = [(x + nextPoint[0]) / 2, (y + nextPoint[1]) / 2]; const prevPointMiddleOfLine = [ (x + prevPoint[0]) / 2, (y + prevPoint[1]) / 2, ]; const prevVector = [x - prevPoint[0], y - prevPoint[1]]; const nextVector = [nextPoint[0] - x, nextPoint[1] - y]; if (i === 0) { if (edgeRoundness !== null) { return [ { type: 'M', x: middleOfLine[0], y: middleOfLine[1], }, ]; } if (cornerRadius !== 0) { const computeRadius = shortenVector(nextVector, cornerRadius); return [ { type: 'M', x: computeRadius[0] + x, y: computeRadius[1] + y, }, ]; } return [ { type: 'M', x, y, }, ]; } if (cornerRadius && edgeRoundness !== null) { throw new Error(`"cornerRadius" and "edgeRoundness" cannot be specified at the same time.`); } if (edgeRoundness === null) { if (cornerRadius === 0) { return [ { type: 'L', x, y, }, ]; } const prevVectorMinusRadius = shortenVector(prevVector, cornerRadius); const prevVectorLength = scaleVectorToLength(prevVector, cornerRadius); const nextVectorMinusRadius = scaleVectorToLength(nextVector, cornerRadius); const firstDraw = [ prevPoint[0] + prevVectorMinusRadius[0], prevPoint[1] + prevVectorMinusRadius[1], ]; return [ { type: 'L', x: firstDraw[0], y: firstDraw[1], }, roundCornerStrategy === 'arc' ? { type: 'a', rx: cornerRadius, ry: cornerRadius, xAxisRotation: 0, dx: prevVectorLength[0] + nextVectorMinusRadius[0], dy: prevVectorLength[1] + nextVectorMinusRadius[1], largeArcFlag: false, sweepFlag: true, } : { type: 'C', x: firstDraw[0] + prevVectorLength[0] + nextVectorMinusRadius[0], y: firstDraw[1] + prevVectorLength[1] + nextVectorMinusRadius[1], cp1x: x, cp1y: y, cp2x: x, cp2y: y, }, ]; } const controlPoint1 = [ prevPointMiddleOfLine[0] + prevVector[0] * edgeRoundness * 0.5, prevPointMiddleOfLine[1] + prevVector[1] * edgeRoundness * 0.5, ]; const controlPoint2 = [ middleOfLine[0] - nextVector[0] * edgeRoundness * 0.5, middleOfLine[1] - nextVector[1] * edgeRoundness * 0.5, ]; return [ { type: 'C', cp1x: controlPoint1[0], cp1y: controlPoint1[1], cp2x: controlPoint2[0], cp2y: controlPoint2[1], x: middleOfLine[0], y: middleOfLine[1], }, ]; }) .flat(1); }; exports.joinPoints = joinPoints;