react-native-squircle-skia
Version:
Skia based squircle for React Native. draws with Figma squirce style
69 lines (53 loc) • 1.79 kB
text/typescript
// code from https://github.com/tienphaw/figma-squircle
import { CornerParams, CornerPathParams } from '../types/types';
export const getPathParamsForCorner = memoize(
({
cornerRadius,
cornerSmoothing,
width,
height,
}: CornerParams): CornerPathParams => {
const maxRadius = Math.min(width, height) / 2;
cornerRadius = Math.min(cornerRadius, maxRadius);
const p = Math.min((1 + cornerSmoothing) * cornerRadius, maxRadius);
let angleAlpha: number, angleBeta: number;
if (cornerRadius <= maxRadius / 2) {
angleBeta = 90 * (1 - cornerSmoothing);
angleAlpha = 45 * cornerSmoothing;
} else {
const diffRatio = (cornerRadius - maxRadius / 2) / (maxRadius / 2);
angleBeta = 90 * (1 - cornerSmoothing * (1 - diffRatio));
angleAlpha = 45 * cornerSmoothing * (1 - diffRatio);
}
const angleTheta = (90 - angleBeta) / 2;
const p3ToP4Distance = cornerRadius * Math.tan(toRadians(angleTheta / 2));
const circularSectionLength =
Math.sin(toRadians(angleBeta / 2)) * cornerRadius * Math.sqrt(2);
const c = p3ToP4Distance * Math.cos(toRadians(angleAlpha));
const d = c * Math.tan(toRadians(angleAlpha));
const b = (p - circularSectionLength - c - d) / 3;
const a = 2 * b;
return {
a,
b,
c,
d,
p,
circularSectionLength,
};
}
);
function toRadians(degrees: number) {
return (degrees * Math.PI) / 180;
}
function memoize<R, T extends (args: any) => R>(f: T): T {
const memory = new Map<string, R>();
const g = (args: any) => {
memory.get(JSON.stringify(args));
if (!memory.get(JSON.stringify(args))) {
memory.set(JSON.stringify(args), f(args));
}
return memory.get(JSON.stringify(args));
};
return g as T;
}