'use client'; import { useMemo, useRef, useState, useEffect, useId } from 'react'; import type { PPTLineElement } from '@openmaic/dsl'; import { getLineElementPath } from '../../utils/element'; import { useElementShadow } from '../shared/useElementShadow'; import { LinePointMarker } from './LinePointMarker'; export interface BaseLineElementProps { elementInfo: PPTLineElement; animate?: boolean; } const DRAW_ANIMATION_MS = 600; export function BaseLineElement({ elementInfo, animate }: BaseLineElementProps) { const { shadowStyle } = useElementShadow(elementInfo.shadow); const pathRef = useRef(null); const [drawComplete, setDrawComplete] = useState(!animate); const markerId = `${elementInfo.id}-${useId().replaceAll(':', '')}`; const svgWidth = useMemo(() => { const width = Math.abs(elementInfo.start[0] - elementInfo.end[0]); return width < 24 ? 24 : width; }, [elementInfo.start, elementInfo.end]); const svgHeight = useMemo(() => { const height = Math.abs(elementInfo.start[1] - elementInfo.end[1]); return height < 24 ? 24 : height; }, [elementInfo.start, elementInfo.end]); const lineDashArray = useMemo(() => { const size = elementInfo.width; if (elementInfo.style === 'dashed') return size <= 8 ? `${size * 5} ${size * 2.5}` : `${size * 5} ${size * 1.5}`; if (elementInfo.style === 'dotted') return size <= 8 ? `${size * 1.8} ${size * 1.6}` : `${size * 1.5} ${size * 1.2}`; return '0 0'; }, [elementInfo.width, elementInfo.style]); const path = useMemo(() => getLineElementPath(elementInfo), [elementInfo]); useEffect(() => { if (!animate) return; const pathEl = pathRef.current; if (!pathEl) return; const length = pathEl.getTotalLength(); if (length === 0) { const t = setTimeout(() => setDrawComplete(true), 0); return () => clearTimeout(t); } pathEl.style.strokeDasharray = `${length}`; pathEl.style.strokeDashoffset = `${length}`; pathEl.style.transition = 'none'; pathEl.getBoundingClientRect(); pathEl.style.transition = `stroke-dashoffset ${DRAW_ANIMATION_MS}ms ease-out`; pathEl.style.strokeDashoffset = '0'; const timer = setTimeout(() => { pathEl.style.transition = 'none'; pathEl.style.strokeDasharray = ''; pathEl.style.strokeDashoffset = ''; setDrawComplete(true); }, DRAW_ANIMATION_MS + 50); return () => clearTimeout(timer); }, [animate]); return (
{elementInfo.points[0] && ( )} {elementInfo.points[1] && ( )}
); }