⚪️ Dotted Text
Create stunning dot matrix animations with this interactive React component powered by Framer Motion. Easily render letters and numbers in a retro pixel-style grid, perfect for eye-catching UI designs, loading screens, or creative typography effects. Fully customizable and optimized for smooth performance in modern web applications
Preview
Follow below steps 👇🏻
Install dependencies
1npm i framer-motion
Component
Create a file dotted-text.tsx in your components folder and paste this code
1'use client';23import { motion } from 'framer-motion';45// Define the dot matrix for each character6const charMatrix: Record<string, number[][]> = {7A: [8[0, 1, 1, 0],9[1, 0, 0, 1],10[1, 1, 1, 1],11[1, 0, 0, 1],12[1, 0, 0, 1]13],14B: [15[1, 1, 1, 0],16[1, 0, 0, 1],17[1, 1, 1, 0],18[1, 0, 0, 1],19[1, 1, 1, 0]20],21C: [22[0, 1, 1, 0],23[1, 0, 0, 1],24[1, 0, 0, 0],25[1, 0, 0, 1],26[0, 1, 1, 0]27],28D: [29[1, 1, 1, 0],30[1, 0, 0, 1],31[1, 0, 0, 1],32[1, 0, 0, 1],33[1, 1, 1, 0]34],35E: [36[1, 1, 1, 1],37[1, 0, 0, 0],38[1, 1, 1, 0],39[1, 0, 0, 0],40[1, 1, 1, 1]41],42F: [43[1, 1, 1, 1],44[1, 0, 0, 0],45[1, 1, 1, 0],46[1, 0, 0, 0],47[1, 0, 0, 0]48],49G: [50[0, 1, 1, 0],51[1, 0, 0, 1],52[1, 0, 0, 0],53[1, 0, 1, 1],54[0, 1, 1, 1]55],56H: [57[1, 0, 0, 1],58[1, 0, 0, 1],59[1, 1, 1, 1],60[1, 0, 0, 1],61[1, 0, 0, 1]62],63I: [64[1, 1, 1],65[0, 1, 0],66[0, 1, 0],67[0, 1, 0],68[1, 1, 1]69],70J: [71[0, 0, 1, 1],72[0, 0, 0, 1],73[0, 0, 0, 1],74[1, 0, 0, 1],75[0, 1, 1, 0]76],77K: [78[1, 0, 0, 1],79[1, 0, 1, 0],80[1, 1, 0, 0],81[1, 0, 1, 0],82[1, 0, 0, 1]83],84L: [85[1, 0, 0, 0],86[1, 0, 0, 0],87[1, 0, 0, 0],88[1, 0, 0, 0],89[1, 1, 1, 1]90],91M: [92[1, 0, 0, 0, 1],93[1, 1, 0, 1, 1],94[1, 0, 1, 0, 1],95[1, 0, 0, 0, 1],96[1, 0, 0, 0, 1]97],98N: [99[1, 0, 0, 1],100[1, 1, 0, 1],101[1, 0, 1, 1],102[1, 0, 0, 1],103[1, 0, 0, 1]104],105O: [106[0, 1, 1, 0],107[1, 0, 0, 1],108[1, 0, 0, 1],109[1, 0, 0, 1],110[0, 1, 1, 0]111],112P: [113[1, 1, 1, 0],114[1, 0, 0, 1],115[1, 1, 1, 0],116[1, 0, 0, 0],117[1, 0, 0, 0]118],119Q: [120[0, 1, 1, 0],121[1, 0, 0, 1],122[1, 0, 0, 1],123[1, 0, 1, 1],124[0, 1, 1, 1]125],126R: [127[1, 1, 1, 0],128[1, 0, 0, 1],129[1, 1, 1, 0],130[1, 0, 1, 0],131[1, 0, 0, 1]132],133S: [134[0, 1, 1, 1],135[1, 0, 0, 0],136[0, 1, 1, 0],137[0, 0, 0, 1],138[1, 1, 1, 0]139],140T: [141[1, 1, 1, 1, 1],142[0, 0, 1, 0, 0],143[0, 0, 1, 0, 0],144[0, 0, 1, 0, 0],145[0, 0, 1, 0, 0]146],147U: [148[1, 0, 0, 1],149[1, 0, 0, 1],150[1, 0, 0, 1],151[1, 0, 0, 1],152[0, 1, 1, 0]153],154V: [155[1, 0, 0, 1],156[1, 0, 0, 1],157[1, 0, 0, 1],158[0, 1, 1, 0],159[0, 0, 1, 0]160],161W: [162[1, 0, 0, 0, 1],163[1, 0, 0, 0, 1],164[1, 0, 1, 0, 1],165[1, 1, 0, 1, 1],166[1, 0, 0, 0, 1]167],168X: [169[1, 0, 0, 1],170[0, 1, 1, 0],171[0, 0, 0, 0],172[0, 1, 1, 0],173[1, 0, 0, 1]174],175Y: [176[1, 0, 0, 1],177[0, 1, 1, 0],178[0, 0, 1, 0],179[0, 0, 1, 0],180[0, 0, 1, 0]181],182Z: [183[1, 1, 1, 1],184[0, 0, 0, 1],185[0, 0, 1, 0],186[0, 1, 0, 0],187[1, 1, 1, 1]188],189'0': [190[0, 1, 1, 0],191[1, 0, 0, 1],192[1, 0, 0, 1],193[1, 0, 0, 1],194[0, 1, 1, 0]195],196'1': [197[0, 1, 0],198[1, 1, 0],199[0, 1, 0],200[0, 1, 0],201[1, 1, 1]202],203'2': [204[0, 1, 1, 0],205[1, 0, 0, 1],206[0, 0, 1, 0],207[0, 1, 0, 0],208[1, 1, 1, 1]209],210'3': [211[1, 1, 1, 0],212[0, 0, 0, 1],213[0, 1, 1, 0],214[0, 0, 0, 1],215[1, 1, 1, 0]216],217'4': [218[0, 0, 1, 1],219[0, 1, 0, 1],220[1, 0, 0, 1],221[1, 1, 1, 1],222[0, 0, 0, 1]223],224'5': [225[1, 1, 1, 1],226[1, 0, 0, 0],227[1, 1, 1, 0],228[0, 0, 0, 1],229[1, 1, 1, 0]230],231'6': [232[0, 1, 1, 0],233[1, 0, 0, 0],234[1, 1, 1, 0],235[1, 0, 0, 1],236[0, 1, 1, 0]237],238'7': [239[1, 1, 1, 1],240[0, 0, 0, 1],241[0, 0, 1, 0],242[0, 1, 0, 0],243[0, 1, 0, 0]244],245'8': [246[0, 1, 1, 0],247[1, 0, 0, 1],248[0, 1, 1, 0],249[1, 0, 0, 1],250[0, 1, 1, 0]251],252'9': [253[0, 1, 1, 0],254[1, 0, 0, 1],255[0, 1, 1, 1],256[0, 0, 0, 1],257[0, 1, 1, 0]258],259'.': [[0], [0], [0], [0], [1]],260',': [[0], [0], [0], [1], [1]],261'!': [[1], [1], [1], [0], [1]],262'?': [263[0, 1, 1, 0],264[1, 0, 0, 1],265[0, 0, 1, 0],266[0, 0, 0, 0],267[0, 0, 1, 0]268],269'+': [270[0, 0, 0],271[0, 1, 0],272[1, 1, 1],273[0, 1, 0],274[0, 0, 0]275],276'-': [277[0, 0, 0],278[0, 0, 0],279[1, 1, 1],280[0, 0, 0],281[0, 0, 0]282],283'*': [284[1, 0, 1],285[0, 1, 0],286[1, 0, 1],287[0, 0, 0],288[0, 0, 0]289],290'/': [291[0, 0, 0, 1],292[0, 0, 1, 0],293[0, 1, 0, 0],294[1, 0, 0, 0],295[0, 0, 0, 0]296],297'=': [298[0, 0, 0],299[1, 1, 1],300[0, 0, 0],301[1, 1, 1],302[0, 0, 0]303],304' ': [305[0, 0],306[0, 0],307[0, 0],308[0, 0],309[0, 0]310]311};312313// Default matrix for unknown characters314const defaultMatrix = [315[1, 1],316[1, 1],317[1, 1],318[1, 1],319[1, 1]320];321322interface DottedTextProps {323text: string;324color?: string;325backgroundColor?: string;326size?: number;327spacing?: number;328animationDelay?: number;329animationColors?: string[];330animationDuration?: number;331shadowIntensity?: number;332}333334const DottedText: React.FC<DottedTextProps> = ({335text,336size = 10,337spacing = 2,338animationDelay = 0.3,339animationColors = [340'#1A0B33', // Deeper purple (twilight)341'#5D2E8C', // Purple342'#F25C54', // Coral/orange343'#F7B267', // Golden orange344'#FFD166', // Amber/gold345'#FFEDDF', // Soft light346'#F7B267', // Golden orange347'#F25C54', // Coral/orange348'#5D2E8C', // Purple349'#1A0B33' // Deeper purple (twilight)350],351animationDuration = 4,352shadowIntensity = 15353}) => {354const renderDot = (355filled: boolean,356x: number,357y: number,358animationIndex: number,359repeatDelay: number360) => {361const dotSize = `${size}px`;362363if (!filled) {364return (365<div366key={`${x}-${y}`}367style={{368width: dotSize,369height: dotSize,370margin: `${spacing}px`,371display: 'inline-block'372}}373/>374);375}376377return (378<motion.div379key={`${x}-${y}`}380style={{381width: dotSize,382height: dotSize,383borderRadius: '50%',384border: '1px solid #FFFFFF47',385margin: `${spacing}px`,386display: 'inline-block',387backgroundColor: animationColors[0]388}}389initial={{390backgroundColor: animationColors[0],391boxShadow: 'none'392}}393animate={{394backgroundColor: animationColors,395boxShadow: [396'none',397'none',398`0 0 ${shadowIntensity / 2.1}px 0 ${animationColors[2]}`,399`0 0 ${shadowIntensity / 2}px 0 ${animationColors[3]}`,400`0 0 ${shadowIntensity}px 0 ${animationColors[4]}`,401`0 0 ${shadowIntensity}px 0 ${animationColors[5]}`,402`0 0 ${shadowIntensity / 2}px 0 ${animationColors[6]}`,403`0 0 ${shadowIntensity / 2.1}px 0 ${animationColors[7]}`,404'none',405'none'406]407}}408transition={{409duration: animationDuration,410delay: animationIndex * animationDelay,411repeat: Infinity,412repeatType: 'reverse',413repeatDelay: repeatDelay,414ease: 'easeInOut'415}}416/>417);418};419420const renderCharacter = (char: string, charIndex: number, totalChars: number) => {421const upperChar = char.toUpperCase();422const matrix = charMatrix[upperChar] || defaultMatrix;423424return (425<div426key={`${charIndex}`}427style={{428display: 'inline-block',429marginRight: `${spacing * 3}px`,430verticalAlign: 'top'431}}432>433{matrix.map((row, rowIndex) => (434<div key={`${rowIndex}`} style={{ display: 'flex' }}>435{row.map((dot, dotColIndex) =>436renderDot(437dot === 1,438charIndex * (matrix[0].length + 2) + dotColIndex,439rowIndex,440charIndex * 4 + dotColIndex,441totalChars * 0.8442)443)}444</div>445))}446</div>447);448};449450return (451<div className="flex flex-wrap gap-2 relative">452{text.split('').map((char, index) => renderCharacter(char, index, text.length))}453</div>454);455};456457export default DottedText;
Usage
1<DottedText text="LM10" />
⭐️ Got a question or feedback?
Feel free to reach out!