@kirz/react-native-toolkit
Version:
Toolkit to speed up React Native development
109 lines (105 loc) • 5.12 kB
JavaScript
import { Extrapolation, interpolate } from 'react-native-reanimated';
export const SvgUtils = {
sinusoidFunction(offsetX, offsetY, amplitude, frequency) {
'worklet';
return x => {
return amplitude * Math.sin(x / (1 / frequency) + offsetX) + offsetY;
};
},
createGraphPath(length, functions, parameters) {
'worklet';
let x = 0;
let path = `M${x} ${functions.reduce((acc, item) => {
if (typeof item === 'function') {
return acc + item(x);
} else if (item.operator === '+') {
return acc + item.function(x);
} else if (item.operator === '-') {
return acc - item.function(x);
} else if (item.operator === '*') {
return acc * item.function(x);
} else if (item.operator === '/') {
return acc / item.function(x);
}
throw new Error('Not implemented');
}, (parameters === null || parameters === void 0 ? void 0 : parameters.offsetY) ?? 0)}`;
do {
const clamped = x > length ? length : x;
path += `L${clamped} ${functions.reduce((acc, item) => {
if (typeof item === 'function') {
return acc + item(clamped);
} else if (item.operator === '+') {
return acc + item.function(clamped);
} else if (item.operator === '-') {
return acc - item.function(clamped);
} else if (item.operator === '*') {
return acc * item.function(clamped);
} else if (item.operator === '/') {
return acc / item.function(clamped);
}
throw new Error('Not implemented');
}, (parameters === null || parameters === void 0 ? void 0 : parameters.offsetY) ?? 0)}`;
x += (parameters === null || parameters === void 0 ? void 0 : parameters.quantization) ?? 2;
} while (x <= length);
return path;
},
polarToCartesian(centerX, centerY, radius, angleInDegrees) {
'worklet';
const angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
return {
x: centerX + radius * Math.cos(angleInRadians),
y: centerY + radius * Math.sin(angleInRadians)
};
},
createRectangularPath(k, rect, border, start, clockwise) {
'worklet';
const borderWidth = border.width;
const innerBorderRadius = border.radius;
const [innerButtonWidth, innerButtonHeigth] = [rect.width, rect.height];
const [svgButtonWidth, svgButtonHeigth] = start === 'bottom' || start === 'top' ? [rect.width, rect.height] : [rect.height, rect.width];
const outerButtonWidth = innerButtonWidth + borderWidth * 2;
const outerButtonHeigth = innerButtonHeigth + borderWidth * 2;
const outerSvgButtonWidth = svgButtonWidth + borderWidth * 2;
const outerSvgButtonHeigth = svgButtonHeigth + borderWidth * 2;
const r = innerBorderRadius;
const R = r + borderWidth / 2;
const drawCorner = (angle, x1, y1) => {
const x = R * Math.sin(angle);
const y = R * Math.cos(angle);
return `a${R} ${R}, 0 0, 1, ${x + x1} ${y + y1}`;
};
const L0 = 0;
const L1 = svgButtonWidth / 2 - r;
const L2 = L1 + r * 2;
const L3 = L2 + svgButtonHeigth - r * 2;
const L4 = L3 + r * 2;
const L5 = L4 + svgButtonWidth - r * 2;
const L6 = L5 + r * 2;
const L7 = L6 + svgButtonHeigth - r * 2;
const L8 = L7 + r * 2;
const L9 = L8 + svgButtonWidth / 2 - r;
const l = L9 * k;
const path = [`M${outerSvgButtonWidth / 2} ${outerSvgButtonHeigth - borderWidth / 2}`, `h${-(svgButtonWidth / 2 - r) * interpolate(l, [L0, L1], [0, 1], Extrapolation.CLAMP)}`, drawCorner(interpolate(l, [L1, L2], [4 * Math.PI / 2, 3 * Math.PI / 2], Extrapolation.CLAMP), 0, -R), `v${-(svgButtonHeigth - r * 2) * interpolate(l, [L2, L3], [0, 1], Extrapolation.CLAMP)}`, drawCorner(interpolate(l, [L3, L4], [3 * Math.PI / 2, 2 * Math.PI / 2], Extrapolation.CLAMP), R, 0), `h${(svgButtonWidth - r * 2) * interpolate(l, [L4, L5], [0, 1], Extrapolation.CLAMP)}`, drawCorner(interpolate(l, [L5, L6], [2 * Math.PI / 2, Math.PI / 2], Extrapolation.CLAMP), 0, R), `v${(svgButtonHeigth - r * 2) * interpolate(l, [L6, L7], [0, 1], Extrapolation.CLAMP)}`, drawCorner(interpolate(l, [L7, L8], [1 * Math.PI / 2, 0 * Math.PI / 2], Extrapolation.CLAMP), -R, 0), `h${-(svgButtonWidth / 2 - r) * interpolate(l, [L8, L9], [0, 1], Extrapolation.CLAMP)}`].join(' ');
return {
pathProps: {
d: path,
strokeWidth: borderWidth,
strokeDashoffset: L9 * (clockwise ?? true ? 1 : -1) * (start === 'left' ? -1 : 1),
...(start === 'left' ? {
transform: `rotate(-90, ${outerButtonHeigth}, ${0}) scale(1, -1) translate(0, ${-outerButtonWidth + outerButtonHeigth})`
} : start === 'right' ? {
transform: `rotate(-90, ${outerButtonHeigth}, ${0}) translate(0, ${-outerButtonHeigth})`
} : start === 'top' ? {
transform: `rotate(180, ${outerButtonWidth / 2}, ${outerButtonHeigth / 2})`
} : {})
},
path,
pathLength: L9,
svgProps: {
viewBox: `0 0 ${outerButtonWidth} ${outerButtonHeigth}`,
preserveAspectRatio: 'none'
}
};
}
};
//# sourceMappingURL=svg.js.map