grediant in a shape
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
export type FillType = "solid" | "gradient";
|
||||
|
||||
export type LinearGradient = {
|
||||
from: string;
|
||||
to: string;
|
||||
angle: number;
|
||||
};
|
||||
|
||||
type Point = { x: number; y: number };
|
||||
|
||||
type GradientPointMode = "rect" | "centered";
|
||||
|
||||
const toRadians = (angle: number) => (angle * Math.PI) / 180;
|
||||
|
||||
const normalizeAngle = (angle: number) => {
|
||||
if (!Number.isFinite(angle)) return 0;
|
||||
return ((angle % 360) + 360) % 360;
|
||||
};
|
||||
|
||||
const getGradientPoints = (
|
||||
width: number,
|
||||
height: number,
|
||||
angle: number,
|
||||
mode: GradientPointMode,
|
||||
): { start: Point; end: Point } => {
|
||||
const safeWidth = Math.max(1, width);
|
||||
const safeHeight = Math.max(1, height);
|
||||
const rad = toRadians(normalizeAngle(angle));
|
||||
const dx = Math.cos(rad);
|
||||
const dy = Math.sin(rad);
|
||||
const half = Math.sqrt(safeWidth * safeWidth + safeHeight * safeHeight) / 2;
|
||||
|
||||
if (mode === "centered") {
|
||||
return {
|
||||
start: { x: -dx * half, y: -dy * half },
|
||||
end: { x: dx * half, y: dy * half },
|
||||
};
|
||||
}
|
||||
|
||||
const cx = safeWidth / 2;
|
||||
const cy = safeHeight / 2;
|
||||
return {
|
||||
start: { x: cx - dx * half, y: cy - dy * half },
|
||||
end: { x: cx + dx * half, y: cy + dy * half },
|
||||
};
|
||||
};
|
||||
|
||||
export const getKonvaGradientProps = (
|
||||
fillType: FillType | undefined,
|
||||
gradient: LinearGradient | undefined,
|
||||
width: number,
|
||||
height: number,
|
||||
mode: GradientPointMode,
|
||||
) => {
|
||||
if (fillType !== "gradient" || !gradient) return {};
|
||||
const points = getGradientPoints(width, height, gradient.angle, mode);
|
||||
return {
|
||||
fillPriority: "linear-gradient" as const,
|
||||
fillLinearGradientStartPoint: points.start,
|
||||
fillLinearGradientEndPoint: points.end,
|
||||
fillLinearGradientColorStops: [0, gradient.from, 1, gradient.to] as [
|
||||
number,
|
||||
string,
|
||||
number,
|
||||
string,
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
export const toCssLinearGradient = (gradient: LinearGradient | undefined) => {
|
||||
if (!gradient) return undefined;
|
||||
return `linear-gradient(${normalizeAngle(gradient.angle)}deg, ${gradient.from} 0%, ${gradient.to} 100%)`;
|
||||
};
|
||||
Reference in New Issue
Block a user