టైప్‌రైటర్ ఎఫెక్ట్ అనేది ఎవరో ఒకరు ఆలోచిస్తున్నట్లుగా చూస్తున్న అనుభూతిని ఇచ్చే డిజిటల్ రూపం. నిజమైన చేత్తో కీలను నొక్కుతున్నట్లుగా, ఒక్కో అక్షరం ఒక్కొక్కటిగా కనిపిస్తుంది. మీరు దీనిని పోర్ట్‌ఫోలియో సైట్‌ల హీరో సెక్షన్‌లలో, బ్రౌజర్ ఆధారిత టెర్మినల్ ఎమ్యులేటర్లలో మరియు AI అసిస్టెంట్ల చాట్ విండోలలో చూడవచ్చు. ఇవి కేవలం ముందే సిద్ధం చేసిన టెక్స్ట్‌ను చూపించడం కాకుండా, తాము నిజంగా "టైప్" చేస్తున్నామని నిరూపించుకోవడానికి దీనిని ఉపయోగిస్తాయి. ఇది సరిగ్గా చేసినప్పుడు, ఒక రకమైన ఉత్కంఠను కలిగిస్తుంది. సరిగ్గా చేయకపోతే, 1987లో జామ్ అయిన ప్రింటర్ లాగా అనిపిస్తుంది.

ఈ ప్యాటర్న్ ఎందుకు కొనసాగుతోంది

కంప్యూటర్లు సమాచారాన్ని తక్షణమే అందిస్తాయి. మనుషులు అలా చేయలేరు. ఈ రెండు వేగాల మధ్య ఉన్న వ్యత్యాసం ఉపయోగకరమైనది. టైప్‌రైటర్ ఎఫెక్ట్ మానవ వేగాన్ని అనుకరిస్తూ ఆ వ్యత్యాసాన్ని పూరిస్తుంది. ఒక ల్యాండింగ్ పేజీలో, ఇది హెడ్‌లైన్‌లోని ప్రతి పదాన్ని ఒక్కొక్కటిగా చూపిస్తూ, సందర్శకులు కేవలం స్కిమ్ చేయకుండా (వేగంగా చదవకుండా) ఆ వాల్యూ ప్రపోజిషన్‌ను పూర్తిగా చదివేలా చేస్తుంది. టెర్మినల్ ఎమ్యులేటర్‌లో, కమాండ్‌లు రియల్ టైమ్‌లో అమలు అవుతున్నాయనే భ్రమను కలిగిస్తుంది. చాట్‌బాట్ ఇంటర్‌ఫేస్‌లో, సమాధానం డేటాబేస్ నుండి తీయడం కాకుండా, అప్పటికప్పుడు జనరేట్ అవుతోందని ఈ రిథమ్ సూచిస్తుంది.

కానీ ఈ ఎఫెక్ట్ మెకానిక్స్ వినియోగదారుని గౌరవిస్తేనే పనిచేస్తుంది. ఒకే రకమైన సమయ వ్యవధితో జరిగే యాంత్రికమైన 'టిక్-టిక్-టిక్' వేగం రోబోటిక్‌గా అనిపిస్తుంది. అంతకంటే దారుణంగా, అసిస్టివ్ టెక్నాలజీని విస్మరించే ఇంప్లిమెంటేషన్, ఒక సరదా విజువల్ అలంకారాన్ని చిరాకు కలిగించే అడ్డంకిగా మార్చవచ్చు. లక్ష్యం వినియోగదారుని నెమ్మదింపజేయడం కాదు; ఇంటర్‌ఫేస్ సజీవంగా అనిపించేలా తగినంత ఫ్రిక్షన్ (చిన్నపాటి ఆలస్యం) జోడించడం మాత్రమే.

Recursive setTimeout తో దీనిని నిర్మించండి

setTimeout తో ప్రారంభించండి, setInterval ని ముట్టుకోవద్దు. దీని మధ్య తేడా మీరు అనుకున్న దానికంటే చాలా ఎక్కువ.

setInterval మొండిది. మీ స్క్రిప్ట్‌లో లేదా బ్రౌజర్ యొక్క మెయిన్ థ్రెడ్‌లో ఏం జరుగుతున్నా సరే, ఇది ప్రతి n మిల్లీసెకన్లకు రన్ అవుతుంది. మీ లాజిక్‌కు సాధారణ కీస్ట్రోక్‌ల మధ్య 50 మిల్లీసెకన్ల విరామం, కానీ విరామ చిహ్నాల (punctuation) తర్వాత 150 మిల్లీసెకన్ల విరామం కావాలంటే, setInterval దానికి అనుగుణంగా మారలేదు. దీనివల్ల మీరు అదనపు కండిషనల్ లాజిక్‌ను ఉపయోగించాల్సి వస్తుంది, రేస్ కండిషన్స్‌తో పోరాడాల్సి వస్తుంది, మరియు చివరికి ఇంటర్వల్‌ను పదేపదే క్లియర్ చేసి రీసెట్ చేయాల్సి వస్తుంది, దీనివల్ల కోడ్ స్టేట్-మేనేజ్‌మెంట్ నైట్‌మేర్‌గా మారుతుంది. వేగంలో మార్పులు కావాల్సి వచ్చినప్పుడు ఫిక్స్‌డ్ ఇంటర్వల్స్ విఫలమవుతాయి.

Recursive setTimeout ప్రతి దశ కూడా తదుపరి దశ కోసం నియమాలను నిర్ణయించుకునేలా చేయడం ద్వారా దీనిని పరిష్కరిస్తుంది. దీనిని ఒక చిన్న స్టేట్ మెషీన్‌గా భావించండి. మీరు కొన్ని వేరియబుల్స్‌ను నిర్వహిస్తారు: ప్రస్తుత స్ట్రింగ్, ప్రస్తుత క్యారెక్టర్ ఇండెక్స్, మీరు టైప్ చేస్తున్నారా లేదా డిలీట్ చేస్తున్నారా అని తెలిపే బూలియన్ ఫ్లాగ్, మరియు మీరు బహుళ స్ట్రింగ్‌ల ద్వారా లూప్ చేయడానికి ఒక textIndex కౌంటర్. ఈ ఫంక్షన్ ఒక క్యారెక్టర్‌ను జోడిస్తుంది, వాక్యంలో అది ఎక్కడ ఉందో తనిఖీ చేస్తుంది, ఆపై సందర్భానికి తగిన ఆలస్యంతో తన తదుపరి కాల్‌ను షెడ్యూల్ చేస్తుంది.

ఉదాహరణకు, మీరు చాలా క్యారెక్టర్లను 50 మిల్లీసెకన్లలో టైప్ చేయవచ్చు, కామా తర్వాత 150 మిల్లీసెకన్లకు తగ్గించవచ్చు మరియు డిలీట్ మోడ్‌కు మారే ముందు పూర్తి వాక్యం చివరలో 800 మిల్లీసెకన్ల పాటు ఆపవచ్చు. setInterval తో మీరు దీనిని స్పష్టంగా చేయలేరు. Recursive setTimeout తో, లాజిక్ చాలా సరళంగా ఉంటుంది:

if typing:
  append next character
  if at end of string:
    switch to pause mode
    schedule next call after 1000ms
if deleting:
  remove last character
  if string empty:
    increment textIndex
    load next string
    switch to typing mode

ఈ నిర్మాణం క్లీనప్‌ను కూడా చాలా సులభతరం చేస్తుంది. timeout IDని స్టోర్ చేయండి. కాంపోనెంట్ అన్‌మౌంట్ అయినప్పుడు లేదా యూజర్ వేరే పేజీకి వెళ్ళినప్పుడు, ఒకసారి clearTimeoutని కాల్ చేయండి. బ్యాక్‌గ్రౌండ్‌లో అనవసరంగా రన్ అయ్యే ఇంటర్వల్స్ ఉండవు.

మెరిసే కర్సర్ అనేది ఒక విజువల్ డీటెయిల్ మాత్రమే, అది డేటాకు సంబంధించినది కాదు. దానిని మీ JavaScript స్టేట్ ఇంజిన్ నుండి దూరంగా ఉంచండి. ::after pseudo-elementకి లేదా మీ టెక్స్ట్ కంటైనర్ చివరన ఉండే ప్రత్యేకమైన <span>కి అనుసంధానించబడిన విడి CSS యానిమేషన్‌ను ఉపయోగించండి.

step-end టైమింగ్‌తో opacity లేదా border-colorను మార్చే సాధారణ @keyframes blink మీకు కంపోజిటర్‌పై నడిచే స్పష్టమైన, హార్డ్‌వేర్-ఫ్రెండ్లీ పల్స్‌ను ఇస్తుంది. కర్సర్ యొక్క విజిబిలిటీని నిర్వహించడం జావాస్క్రిప్ట్ పని కాదు. మీరు setTimeout రికర్షన్ నుండి డిస్‌ప్లే ప్రాపర్టీలను టోగుల్ చేస్తే, ప్రతి క్యారెక్టర్‌కు అనవసరమైన స్టైల్ రీకల్క్యులేషన్స్‌ను ప్రేరేపిస్తారు. సౌందర్యాన్ని CSS కి వదిలేయండి. క్రమాన్ని JavaScript కి వదిలేయండి.

textIndex కౌంటర్ ఉపయోగించి బహుళ స్ట్రింగ్‌ల ద్వారా లూప్ చేయడం చాలా సులభం. మీ స్ట్రింగ్‌లను ఒక అర్రే (array)లో స్టోర్ చేయండి. యానిమేషన్ తన డిలీట్ దశను పూర్తి చేసి, కంటైనర్ ఖాళీ అయినప్పుడు, అర్రే పొడవును బట్టి textIndexని మోడ్యులో (modulo) చేసి పెంచండి, క్యారెక్టర్ పాయింటర్‌ను సున్నాకి రీసెట్ చేయండి మరియు మళ్ళీ టైపింగ్ ప్రారంభించండి. పోర్ట్‌ఫోలియో సైట్లు పేజీని రీలోడ్ చేయకుండానే ["Developer", "Designer", "Writer"] వంటి రోల్స్ ద్వారా సైక్లింగ్ చేసే విధానం ఇదే.

భ్రమను పాడుచేసే తప్పులు

అనాటరు (amateur) ఇంప్లిమెంటేషన్లలో మూడు తప్పులు పదేపదే కనిపిస్తాయి.

setInterval ఉపయోగించడం. మనం ఇప్పటికే వేరియబుల్-స్పీడ్ సమస్య గురించి చర్చించాము, కానీ ఇక్కడ ఒక సూక్ష్మమైన సమస్య ఉంది. ఒకవేళ మీ DOM అప్‌డేట్ ఎప్పుడైనా ఆలస్యమైతే—ఉదాహరణకు, బ్రౌజర్ లేఅవుట్ షిఫ్ట్‌ను పెయింట్ చేయడం వల్ల—setInterval నిరంతరం ఫైర్ అవుతూనే ఉంటుంది. దీనివల్ల ఒకదానిపై ఒకటి రాసుకోవడం (overlapping writes), డూప్లికేట్ అక్షరాలు లేదా బ్రౌజర్ రెండర్ చేయగలిగే దానికంటే వేగంగా రాసేయడం వంటివి జరగవచ్చు. రికర్సివ్ setTimeout తదుపరి దశ గురించి ఆలోచించే ముందు, ప్రస్తుత దశ పూర్తయ్యే వరకు వేచి ఉంటుంది.

HTMLని ఎస్కేప్ చేయడం మర్చిపోవడం. మీ సోర్స్ స్ట్రింగ్స్‌లో యాంగిల్ బ్రాకెట్లు ఉండి, మీరు ఒక్కో అక్షరాన్ని innerHTML ద్వారా ఇంజెక్ట్ చేస్తుంటే, మీరు ట్యాగ్‌లను సగానికి విడగొడుతారు. బ్రౌజర్ మొదట <, తర్వాత <s, ఆపై <st అని చూస్తుంది. ఇది సరైన ట్యాగ్ పార్సింగ్‌ను నిరోధిస్తుంది మరియు విచ్ఛిన్నమైన DOM నోడ్స్ లేదా ఊహించని స్టైలింగ్ క్యాస్కేడ్‌లకు దారితీస్తుంది. మీకు ఆ అక్షరాలు అలాగే కనిపించాలనుకుంటే, మొదట వాటిని ఎస్కేప్ చేయండి లేదా అంతకంటే ఉత్తమంగా, innerHTML బదులుగా textContent ఉపయోగించండి. టైప్‌రైటర్ అవుట్‌పుట్‌లో మీకు స్టైల్ చేసిన <span> ట్యాగ్‌లు నిజంగా అవసరమైతే, అక్షరాల లూప్‌ను ప్రారంభించే ముందు ట్యాగ్‌లు ఎక్కడ మొదలై ఎక్కడ ముగుస్తాయో ఖచ్చితంగా తెలుసుకోవడానికి స్ట్రింగ్‌ను ప్రీ-ప్రాసెస్ చేయండి.

యాక్సెసిబిలిటీని విస్మరించడం. స్క్రీన్ రీడర్లు ఒక్కో అక్షరాన్ని చదవడం ఇష్టపడవు. మీ స్క్రిప్ట్ ప్రతి కొత్త అక్షరాన్ని DOMకి జోడిస్తున్నప్పుడు, కొన్ని అసిస్టివ్ టెక్నాలజీలు మొత్తం నోడ్‌ను మళ్ళీ ప్రకటిస్తాయి, దీనివల్ల విడివిడి పదాల వరుసగా వినిపిస్తుంది. శ్రవణ నావిగేషన్ (auditory navigation) పై ఆధారపడే వారికి ఇది ఒక দুঃస్వప్నం. దీని పరిష్కారం క్లిష్టమైనది కాదు: పూర్తి, తుది వచనాన్ని కలిగి ఉన్న కంటైనర్‌కు aria-label జోడించండి. మీరు aria-hidden="true" ఉపయోగించి యానిమేటెడ్ ఎలిమెంట్‌ను అసిస్టివ్ టెక్నాలజీ నుండి పూర్తిగా దాచవచ్చు మరియు స్క్రీన్ రీడర్ల కోసం విజువల్‌గా కనిపించని స్టాటిక్ కాపీని అందించవచ్చు. ఏది చేసినా, వినియోగదారులను మీ పెర్ఫార్మెన్స్ కోసం వేచి ఉండేలా చేయకుండా, వారికి పూర్తి వాక్యాన్ని ముందే అందించండి.

మీ వెర్షన్‌ను మెరుగుపరచడానికి మార్గాలు

కోర్ లూప్ సరిగ్గా పనిచేస్తున్నప్పుడు, మీరు అదనపు ఫీచర్లను జోడించవచ్చు. కానీ ప్రాథమిక అంశాలు పటిష్టంగా ఉండే వరకు వాటిని జోడించాలనే కోరికను అదుపులో ఉంచుకోండి.

కీస్ట్రోక్ సౌండ్ ఎఫెక్ట్స్. ప్రతి అక్షరంపై ఒక చిన్న క్లిక్ శబ్దం సంతృప్తిని ఇవ్వవచ్చు, కానీ వెబ్‌పేజీలలో ఆడియో అనేది ఒక సవాలుతో కూడుకున్న విషయం. Web Audio API లేదా తక్కువ బఫర్‌తో కూడిన తేలికపాటి Audio ఎలిమెంట్‌ను ఉపయోగించండి. ప్లేబ్యాక్ రేట్‌ను స్వల్పంగా—0.95 మరియు 1.05 మధ్య—మార్చండి, దీనివల్ల ఒకే రకమైన క్లిక్‌లు కృత్రిమంగా అనిపించవు. ఎల్లప్పుడూ బ్రౌజర్ యొక్క ఆటోప్లే పాలసీలను గౌరవించండి మరియు మ్యూట్ టోగుల్‌ను అందించండి. ఉదయం 9 గంటలకు టైపింగ్ శబ్దాలను ఆటోప్లే చేసే మ్యూట్ చేయని పోర్ట్‌ఫోలియో పేజీ వినియోగదారులను త్వరగా విరక్తి చెందిస్తుంది.

మల్టీ-లైన్ టైపింగ్. నిజమైన టెర్మినల్ విండోలు లైన్లను మారుస్తాయి (wrap). మీ వచనం లైన్ బ్రేక్‌ను దాటితే, మీ లేఅవుట్ ఊహించదగినది కాకపోతే, ఒక సాధారణ border-right కర్సర్ వింతగా దూకుతుంది. న్యూలైన్ క్యారెక్టర్ల ద్వారా స్ట్రింగ్స్‌ను విభజించి ప్రతి లైన్‌ను దాని స్వంత <span లో రెండర్ చేయండి, లేదా కంటెంట్ చివరను ట్రాక్ చేసే పొజిషన్డ్ సూడో-ఎలిమెంట్‌ను ఉపయోగించండి. టెక్స్ట్ రాపింగ్‌ విషయంలో జాగ్రత్తగా ఉండండి; కంటైనర్ వెడల్పు మారితే ఇన్‌లైన్ బోర్డర్‌గా అమలు చేయబడిన కర్సర్ టెక్స్ట్ నుండి విడిపోవచ్చు. టెర్మినల్ స్టైల్స్ కోసం white-space: pre-wrap మరియు మోనోస్పేస్డ్ ఫాంట్‌ను ఉపయోగించడం గురించి ఆలోచించండి, ఎందుకంటే ఫిక్స్‌డ్-విడ్త్ అక్షరాలు కర్సర్ గణనను (cursor math) చాలా సులభతరం చేస్తాయి.

రియల్-టైమ్ Markdown రెండరింగ్. ఇక్కడే విషయాలు క్లిష్టంగా మారుతాయి. మీరు **bold** అని టైప్ చేస్తే, మీకు రెండు ఎంపికలు ఉన్నాయి: నక్షత్రాలను (asterisks) అవి ఉన్నట్లుగా రెండర్ చేయడం లేదా వాటిని వెంటనే బోల్డ్ స్టైల్‌లోకి మార్చడం. మీరు రెండవ దానిని ఎంచుకుంటే, మధ్యలో textContent నుండి innerHTML కి మారడం అంటే మీ టెక్స్ట్ నోడ్ సరిహద్దులు మారుతాయని అర్థం. HTML ట్యాగ్‌లు మీ కింద ఉన్న DOM ట్రీని మార్చడం వల్ల కర్సర్ పొజిషన్ ఒక తలనొప్పిగా మారుతుంది. ఒక సురక్షితమైన విధానం ఏమిటంటే, ముడి Markdown స్ట్రింగ్‌ను సాధారణంగా టైప్ చేయడం, ఆపై పూర్తి స్ట్రింగ్ స్క్రీన్‌పై ఉన్నప్పుడు రెండర్ పాస్‌ను ట్రిగ్గర్ చేయడం. మీకు నిజంగా లైవ్ ఫార్మాటింగ్ కావాలంటే, రెండు లేయర్‌లను నిర్వహించండి: ఒక హిడెన్ టైప్డ్ బఫర్ మరియు ఒక పార్స్డ్ విజువల్ ఓవర్‌లే.

రివర్స్ ఎఫెక్ట్స్. టెక్స్ట్‌ను డిలీట్ చేయడం అంటే ఒక్కో అక్షరాన్ని బ్యాక్‌స్పేస్ చేయడం మాత్రమే కాదు. తదుపరి స్ట్రింగ్ టైప్ కావడానికి ముందు ఫీల్డ్‌ను తక్షణమే క్లియర్ చేసే "select all, then delete" రీసెట్‌ను మీరు అనుకరించవచ్చు. అది చాలా యాంత్రికంగా ఉంటుంది. ప్రత్యామ్నాయంగా, అక్షరానికి 30 మిల్లీసెకన్ల వేగంతో నెమ్మదిగా బ్యాక్‌స్పేసింగ్ చేయడం వల్ల ఉత్కంఠ పెరుగుతుంది. ఈ రెండింటినీ కలపండి: ఒక టైపోను త్వరగా బ్యాక్‌స్పేస్ చేయండి, కాసేపు ఆగండి, ఆపై సాధారణ వేగంతో డిలీట్ చేయడం ప్రారంభించండి. ఈ వైవిధ్యం ఆ ఎఫెక్ట్‌కు సహజత్వాన్ని ఇస్తుంది.

అసలైన సారాంశం

టైప్‌రైటర్ ఎఫెక్ట్ అనేది ఉపరితలంపై చాలా సాధారణంగా కనిపించే, కానీ మీరు దానిని నిర్మించిన తర్వాత మాత్రమే దాని సంక్లిష్టతను వెల్లడించే UI అలంకరణలలో ఒకటి. ప్రారంభించండి