"use client"; import { Cpu, Zap } from "lucide-react"; import { motion } from "motion/react"; import type { RefObject } from "react"; import React, { useRef } from "react"; import { useEffect, useId, useState } from "react"; import { cn } from "@/lib/utils"; interface Feature250Props { className?: string; } const Feature250 = ({ className }: Feature250Props) => { return (

با سگمنت‌بندی دقیق، پیام مناسب را به مخاطب مناسب برسانید. داده رفتاری نشان می‌دهد کدام محتوا بیشترین تأثیر را روی تبدیل دارد.

کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند

); }; export { Feature250 }; const REVERSE = false; const DURATION = 4; function AnimatedBeamIllustration() { const containerRef = useRef(null); const div1Ref = useRef(null); const div2Ref = useRef(null); const div3Ref = useRef(null); const div4Ref = useRef(null); const div5Ref = useRef(null); const div6Ref = useRef(null); const div7Ref = useRef(null); return (
{/* Reserve width on lg so absolute nodes/beams stay inside the frame (avoid lg:w-0 bleed). */}
تحلیل عملکرد کمپین
); } /* animated-beam.tsx with direction support. The original code is from https://magicui.design/docs/components/animated-beam which doesn't support vertical animations. This is a modified version of the original code to support that. */ export interface AnimatedBeamProps { className?: string; containerRef: RefObject; // Container ref fromRef: RefObject; toRef: RefObject; curvature?: number; reverse?: boolean; direction?: "horizontal" | "vertical"; pathColor?: string; pathWidth?: number; pathOpacity?: number; gradientStartColor?: string; gradientStopColor?: string; delay?: number; duration?: number; startXOffset?: number; startYOffset?: number; endXOffset?: number; endYOffset?: number; } const AnimatedBeam: React.FC = ({ className, containerRef, fromRef, toRef, curvature = 0, reverse = false, // Include the reverse prop direction = "horizontal", duration = Math.random() * 3 + 4, delay = 0, pathColor = "gray", pathWidth = 2, pathOpacity = 0.2, gradientStartColor = "#ffaa40", gradientStopColor = "#9c40ff", startXOffset = 0, startYOffset = 0, endXOffset = 0, endYOffset = 0, }) => { const id = useId(); const [pathD, setPathD] = useState(""); const [svgDimensions, setSvgDimensions] = useState({ width: 0, height: 0 }); // Calculate the gradient coordinates based on the direction and reverse prop const gradientCoordinates = direction === "vertical" ? reverse ? { x1: ["0%", "0%"], x2: ["0%", "0%"], y1: ["90%", "-10%"], y2: ["100%", "0%"], } : { x1: ["0%", "0%"], x2: ["0%", "0%"], y1: ["10%", "110%"], y2: ["0%", "100%"], } : reverse ? { x1: ["90%", "-10%"], x2: ["100%", "0%"], y1: ["0%", "0%"], y2: ["0%", "0%"], } : { x1: ["10%", "110%"], x2: ["0%", "100%"], y1: ["0%", "0%"], y2: ["0%", "0%"], }; useEffect(() => { const updatePath = () => { if (containerRef.current && fromRef.current && toRef.current) { const containerRect = containerRef.current.getBoundingClientRect(); const rectA = fromRef.current.getBoundingClientRect(); const rectB = toRef.current.getBoundingClientRect(); const svgWidth = containerRect.width; const svgHeight = containerRect.height; setSvgDimensions({ width: svgWidth, height: svgHeight }); const startX = rectA.left - containerRect.left + rectA.width / 2 + startXOffset; const startY = rectA.top - containerRect.top + rectA.height / 2 + startYOffset; const endX = rectB.left - containerRect.left + rectB.width / 2 + endXOffset; const endY = rectB.top - containerRect.top + rectB.height / 2 + endYOffset; let d: string; if (direction === "vertical") { const controlX = startX - curvature; d = `M ${startX},${startY} Q ${controlX},${ (startY + endY) / 2 } ${endX},${endY}`; } else { const controlY = startY - curvature; d = `M ${startX},${startY} Q ${ (startX + endX) / 2 },${controlY} ${endX},${endY}`; } setPathD(d); } }; // Initialize ResizeObserver const resizeObserver = new ResizeObserver((entries) => { // For all entries, recalculate the path for (const _ of entries) { updatePath(); } }); // Observe the container element if (containerRef.current) { resizeObserver.observe(containerRef.current); } // Call the updatePath initially to set the initial path updatePath(); // Clean up the observer on component unmount return () => { resizeObserver.disconnect(); }; }, [ containerRef, fromRef, toRef, curvature, startXOffset, startYOffset, endXOffset, endYOffset, direction, ]); return ( ); };