enzostvs's picture
enzostvs HF Staff
Upload 172 files
9cd6ddb verified
import { Fragment, useRef, useState } from "react";
import { useMount, useUpdateEffect } from "react-use";
import { motion } from "framer-motion";
import saveAsPng from "save-svg-as-png";
import { EditorType, IconItem } from "types/editor";
import Shapes from "@/components/svg/shapes";
import { Icons } from "components/svg/icons";
import { Null } from "components/svg/shapes/null";
export const Icon = ({
editor,
size = 200,
id,
onChange,
onChangeTab,
}: {
editor: EditorType;
id?: string;
size?: number;
onChange?: (e: EditorType) => void;
onChangeTab?: (e: number) => void;
}) => {
const shapeRef = useRef<any>(null);
const ComponentShape =
Shapes[editor.shape?.component as keyof typeof Shapes] ?? Null;
return (
<ComponentShape
ref={shapeRef}
width={size}
height={size}
shape={editor.shape}
id={id}
>
{editor?.icons?.map((icon, k) => {
const findIcon = Icons?.find(
(i: IconItem) => icon.component === i.name
);
const customText = icon?.custom_text?.enabled;
const customImage = icon?.image;
const GradientType =
icon?.gradient?.type === "radialGradient"
? "radialGradient"
: "linearGradient";
if (!findIcon && !customText && !customImage) return null;
return (
<Fragment key={k}>
<defs>
<GradientType
id={`icon-gradient-${k}`}
gradientTransform={`rotate(${icon?.gradient?.angle ?? "90"})`}
>
{icon?.gradient?.enabled ? (
<>
{icon?.gradient?.colours?.map((color, c) => (
<stop
key={c}
offset={`${color.left}%`}
stopColor={
editor?.shape?.transparency ? "#000" : color.value
}
/>
))}
</>
) : (
<stop
offset="0%"
stopColor={
editor?.shape?.transparency ? "#000" : icon.colour
}
/>
)}
</GradientType>
</defs>
<_IconComponent
component={findIcon?.component}
shapeRef={shapeRef}
shape={editor?.shape?.component}
key={k}
index={k}
icon={icon}
onChange={(e: any) =>
onChange &&
onChange({
...editor,
icons: editor.icons.map((i: any, index: number) =>
index === k ? e : i
),
})
}
onClick={onChangeTab ? () => onChangeTab(2) : undefined}
/>
</Fragment>
);
})}
</ComponentShape>
);
};
const _IconComponent = ({
shapeRef,
component,
icon,
shape,
index,
onChange,
...props
}: any) => {
const iconRef = useRef<any>(null);
const [position, setPosition] = useState<any>(null);
useUpdateEffect(() => {
const position = setIconPosition(iconRef, shapeRef);
setPosition(position);
const svg = document.getElementById("discotools-selected-svg");
saveAsPng.svgAsPngUri(svg).then(() => {});
}, [shapeRef.current, icon.component, icon?.image]);
useMount(() => {
const position = setIconPosition(iconRef, shapeRef);
setPosition(position);
});
useUpdateEffect(() => {
onChange({
...icon,
position,
});
}, [position]);
const IconComponent = component as any;
return (
<motion.g
animate={{
x: icon?.position?.x ?? position?.x ?? 0,
y: icon?.position?.y ?? position?.y ?? 0,
scale: icon?.position?.scale ?? 1,
rotate: icon?.position?.angle ?? 0,
originX: 0.5,
filter:
icon?.shadow?.enabled &&
`drop-shadow(${icon?.shadow?.position?.x}px ${icon?.shadow?.position?.y}px ${icon?.shadow?.position?.blur}px ${icon?.shadow?.colour})`,
}}
fill={`url(#${`icon-gradient-${index}`})`}
stroke={icon?.border?.colour}
strokeLinejoin="round"
strokeWidth={icon?.border?.width}
style={{
transformOrigin: "center",
// filter: `drop-shadow(${icon?.shadow?.position?.x}px ${icon?.shadow?.position?.y}px ${icon?.shadow?.position?.blur}px ${icon?.shadow?.colour})`,
}}
>
{icon?.custom_text?.enabled ? (
<text
ref={iconRef as any}
style={{
fontSize: icon?.custom_text?.size
? `${icon?.custom_text?.size}px`
: "100px",
fontWeight: 900,
}}
className="font-title"
viewBox="0 0 200 -100"
>
{icon?.custom_text?.text}
</text>
) : icon?.image ? (
<image
ref={iconRef as any}
href={icon?.image}
width={190}
height={190}
viewBox="0 0 190 190"
preserveAspectRatio="xMidYMid slice"
/>
) : (
<IconComponent ref={iconRef} {...props} />
)}
</motion.g>
);
};
const setIconPosition = (iconRef: any, shapeRef: any) => {
if (iconRef?.current) {
const shapeBoxW = shapeRef?.current?.getAttribute("viewBox")?.split(" ")[2];
const shapeBoxH = shapeRef?.current?.getAttribute("viewBox")?.split(" ")[3];
const iconBoxW = iconRef?.current?.getAttribute("viewBox")?.split(" ")[2];
const iconBoxH = iconRef?.current?.getAttribute("viewBox")?.split(" ")[3];
const position = {
x: shapeBoxW / 2 - iconBoxW / 2,
y: shapeBoxH / 2 - iconBoxH / 2,
xPath: Number(shapeBoxW - iconBoxW),
yPath: Number(shapeBoxH - iconBoxH),
};
return position;
}
};