{"version":3,"file":"Comp5.CxFpZdKR.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/6XSBvIULSwCHu5Y1KCsV/4qNOZxgIaEQ1ABp3VXOy/Comp5.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import{useRef,useEffect}from\"react\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";export default function AsciiKineticText(props){const canvasRef=useRef(null);const isCanvas=RenderTarget.current()===RenderTarget.canvas;// 1. Safely extract the raw font string\nconst rawFont=typeof props.fontFamily===\"object\"&&props.fontFamily!==null?props.fontFamily.fontFamily:props.fontFamily||\"Inter\";// 2. Format specifically for Canvas API (prevent double quoting)\nconst canvasFontFamily=rawFont.includes(\",\")?rawFont:`\"${rawFont.replace(/['\"]/g,\"\")}\"`;useEffect(()=>{const canvas=canvasRef.current;if(!canvas)return;const ctx=canvas.getContext(\"2d\",{willReadFrequently:true});let particles=[];let animationFrameId;let resizeObserver;let mouse={x:-1e3,y:-1e3,radius:props.mouseRadius,isActive:false};class Particle{update(){// 1. Character Shuffle\nif(props.shuffleSpeed>0&&Math.random()<props.shuffleSpeed){const chars=props.characters.split(\"\");this.char=chars[Math.floor(Math.random()*chars.length)];}// 2. Interaction Physics\nlet dx=mouse.x-this.x;let dy=mouse.y-this.y;let distance=Math.sqrt(dx*dx+dy*dy);if(distance<mouse.radius){// Interaction Power: Positive = Repel, Negative = Attract\nlet force=(mouse.radius-distance)/mouse.radius;let acceleration=force*props.interactionPower;this.vx-=dx/distance*acceleration;this.vy-=dy/distance*acceleration;}// 3. Spring Return Physics\nlet ax=(this.baseX-this.x)*this.stiffness;let ay=(this.baseY-this.y)*this.stiffness;this.vx=(this.vx+ax)*this.friction;this.vy=(this.vy+ay)*this.friction;this.x+=this.vx;this.y+=this.vy;}constructor(x,y,char){this.x=x;this.y=y;this.baseX=x;this.baseY=y;this.vx=0;this.vy=0;this.char=char;// Random weight for organic feel\nthis.friction=props.damping+Math.random()*.05;this.stiffness=props.stiffness+Math.random()*.01;}}const initParticles=(width,height)=>{particles=[];const tempCanvas=document.createElement(\"canvas\");const tempCtx=tempCanvas.getContext(\"2d\");tempCanvas.width=width;tempCanvas.height=height;// Apply Text Transform\nlet displayText=props.text;if(props.textTransform===\"uppercase\")displayText=displayText.toUpperCase();if(props.textTransform===\"lowercase\")displayText=displayText.toLowerCase();// --- AUTO-SCALING LOGIC ---\nconst baseFontSize=100;// Use safely formatted canvas font string\ntempCtx.font=`${props.fontStyle} ${props.fontWeight} ${baseFontSize}px ${canvasFontFamily}`;const metrics=tempCtx.measureText(displayText);const textWidth=metrics.width||1// Fallback to prevent division by zero\n;const autoSize=width/textWidth*baseFontSize*.92;tempCtx.fillStyle=\"white\";tempCtx.font=`${props.fontStyle} ${props.fontWeight} ${autoSize}px ${canvasFontFamily}`;tempCtx.textAlign=\"center\";tempCtx.textBaseline=\"middle\";tempCtx.fillText(displayText,width/2,height/2);const textCoordinates=tempCtx.getImageData(0,0,width,height);const chars=props.characters.split(\"\");for(let y=0;y<textCoordinates.height;y+=props.resolution){for(let x=0;x<textCoordinates.width;x+=props.resolution){const alpha=textCoordinates.data[y*4*textCoordinates.width+x*4+3];if(alpha>128){const randomChar=chars[Math.floor(Math.random()*chars.length)];particles.push(new Particle(x,y,randomChar));}}}};const drawFrame=()=>{ctx.clearRect(0,0,canvas.width,canvas.height);// Get computed color to support Framer Theme variables\nconst computedColor=getComputedStyle(canvas).getPropertyValue(\"color\");ctx.fillStyle=computedColor||props.color;ctx.font=`${props.fontStyle} ${props.fontWeight} ${props.fontSize}px ${canvasFontFamily}`;ctx.textAlign=\"center\";ctx.textBaseline=\"middle\";for(let i=0;i<particles.length;i++){const p=particles[i];// Only run physics calculations if we are animating\nif(!isCanvas)p.update();ctx.fillText(p.char,p.x,p.y);}};const animate=()=>{drawFrame();animationFrameId=requestAnimationFrame(animate);};const handleResize=()=>{const rect=canvas.getBoundingClientRect();if(rect.width===0||rect.height===0)return;// High DPI support for crisp rendering\nconst dpr=window.devicePixelRatio||1;canvas.width=rect.width*dpr;canvas.height=rect.height*dpr;ctx.scale(dpr,dpr);initParticles(rect.width,rect.height);// Instantly draw the static preview frame in the editor\nif(isCanvas){drawFrame();}};const handleMouseMove=e=>{if(isCanvas)return;const rect=canvas.getBoundingClientRect();mouse.x=e.clientX-rect.left;mouse.y=e.clientY-rect.top;mouse.radius=props.mouseRadius;};const handleMouseLeave=()=>{if(isCanvas)return;mouse.x=-1e3;mouse.y=-1e3;};// 3. Wrap in a try-catch so invalid font strings don't crash the canvas setup\ntry{document.fonts.load(`${props.fontStyle} ${props.fontWeight} 10px ${canvasFontFamily}`).then(()=>{if(canvasRef.current)handleResize();});}catch(e){console.warn(\"Font parsing issue, falling back to resize\",e);if(canvasRef.current)handleResize();}resizeObserver=new ResizeObserver(handleResize);resizeObserver.observe(canvas);canvas.addEventListener(\"mousemove\",handleMouseMove);canvas.addEventListener(\"mouseleave\",handleMouseLeave);// Loop Gatekeeper\nif(!isCanvas){animate();}return()=>{resizeObserver.disconnect();canvas.removeEventListener(\"mousemove\",handleMouseMove);canvas.removeEventListener(\"mouseleave\",handleMouseLeave);if(!isCanvas)cancelAnimationFrame(animationFrameId);};},[props.text,props.textTransform,props.color,canvasFontFamily,props.fontWeight,props.fontStyle,props.resolution,props.characters,props.mouseRadius,props.stiffness,props.damping,props.interactionPower,props.fontSize,props.shuffleSpeed,isCanvas]);return /*#__PURE__*/_jsxs(\"div\",{style:{width:\"100%\",height:\"100%\",position:\"relative\",backgroundColor:props.backgroundColor},children:[/*#__PURE__*/_jsx(\"span\",{style:{position:\"absolute\",opacity:0,pointerEvents:\"none\",fontFamily:rawFont,fontWeight:props.fontWeight,fontStyle:props.fontStyle},children:props.text}),/*#__PURE__*/_jsx(\"canvas\",{ref:canvasRef,style:{width:\"100%\",height:\"100%\",display:\"block\",color:props.color}})]});}// Framer Property Controls\naddPropertyControls(AsciiKineticText,{text:{type:ControlType.String,title:\"Text\",defaultValue:\"artefakt\",description:\"The main word or phrase to be generated into particles.\"},characters:{type:ControlType.String,title:\"ASCII Chars\",defaultValue:\"01+-*\",description:\"The pool of characters used to build the text shape.\"},// Typography Group\nfontFamily:{type:ControlType.Font,title:\"Font Family\",defaultValue:\"Inter\",placeholder:\"Inter, monospace, serif...\",description:\"The font used to calculate the shape. Sans-serif blocky fonts work best.\"},fontWeight:{type:ControlType.Enum,title:\"Font Weight\",defaultValue:\"bold\",options:[\"100\",\"300\",\"normal\",\"600\",\"bold\",\"800\",\"900\"],optionTitles:[\"Thin\",\"Light\",\"Regular\",\"Semi-Bold\",\"Bold\",\"Extra Bold\",\"Black\"]},fontStyle:{type:ControlType.Enum,title:\"Font Style\",defaultValue:\"normal\",options:[\"normal\",\"italic\"],optionTitles:[\"Normal\",\"Italic\"]},textTransform:{type:ControlType.Enum,title:\"Transform\",defaultValue:\"none\",options:[\"none\",\"uppercase\",\"lowercase\"],optionTitles:[\"None\",\"UPPERCASE\",\"lowercase\"]},// Styling\ncolor:{type:ControlType.Color,title:\"Text Color\",defaultValue:\"#FFFFFF\"},backgroundColor:{type:ControlType.Color,title:\"Background\",defaultValue:\"#000000\"},// Layout & Rendering\nresolution:{type:ControlType.Number,title:\"Density\",defaultValue:8,min:4,max:20,description:\"Lower number = more particles (heavier performance). Higher number = less particles.\"},fontSize:{type:ControlType.Number,title:\"Char Size\",defaultValue:10,min:2,max:24,description:\"The actual visual size of the ASCII characters.\"},shuffleSpeed:{type:ControlType.Number,title:\"Shuffle\",defaultValue:.05,min:0,max:.5,step:.01,description:\"How fast the characters flicker and swap. Set to 0 for static characters.\"},// Physics Controls\nmouseRadius:{type:ControlType.Number,title:\"Cursor Radius\",defaultValue:120,min:50,max:400,description:\"The size of the interaction area around the mouse.\"},interactionPower:{type:ControlType.Number,title:\"Force\",defaultValue:5,min:-20,max:20,description:\"Positive values push particles away. Negative values pull them in.\"},stiffness:{type:ControlType.Number,title:\"Stiffness\",defaultValue:.05,min:.01,max:.2,step:.01,description:\"How strongly the particles snap back to their original position.\"},damping:{type:ControlType.Number,title:\"Damping\",defaultValue:.9,min:.5,max:.99,step:.01,description:\"Friction. Lower values act like thick liquid; higher values make it bouncy.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"AsciiKineticText\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Comp5.map"],"mappings":"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"}