[{"data":1,"prerenderedAt":1858},["ShallowReactive",2],{"article":3},[4,134,388,593,1317],{"id":5,"title":6,"body":7,"date":111,"description":112,"extension":113,"images":114,"meta":119,"navigation":120,"path":121,"seo":122,"stem":123,"tags":124,"thumbnail":20,"tools":129,"__hash__":133},"articles\u002Farticle\u002F0010_dummy_article.md","Why Every Animator Should Learn to Code",{"type":8,"value":9,"toc":106},"minimark",[10,14,51,54,59,62,89,92,96,99,102],[11,12,13],"p",{},"The entry point is After Effects expressions. You alt-click a stopwatch and type a little JavaScript directly in the timeline. Most animators have already done this without thinking of it as coding.",[15,16,21],"pre",{"className":17,"code":18,"language":19,"meta":20,"style":20},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","wiggle(3, 20)\n","js","",[22,23,24],"code",{"__ignoreMap":20},[25,26,29,33,37,41,45,48],"span",{"class":27,"line":28},"line",1,[25,30,32],{"class":31},"s2Zo4","wiggle",[25,34,36],{"class":35},"sTEyZ","(",[25,38,40],{"class":39},"sbssI","3",[25,42,44],{"class":43},"sMK4o",",",[25,46,47],{"class":39}," 20",[25,49,50],{"class":35},")\n",[11,52,53],{},"That's it. That's code. And you already understand what it does.",[55,56,58],"h2",{"id":57},"you-dont-need-to-go-deep","You don't need to go deep",[11,60,61],{},"Knowing a handful of things gets you 80% of the value:",[63,64,65,73,83],"ul",{},[66,67,68,72],"li",{},[69,70,71],"strong",{},"Variables"," — a value has a name and a type",[66,74,75,78,79,82],{},[69,76,77],{},"Conditionals"," — ",[22,80,81],{},"if\u002Felse"," to make things respond to other things",[66,84,85,88],{},[69,86,87],{},"Loops"," — do this thing N times, or for every file in a folder",[11,90,91],{},"The rest you look up when you need it.",[55,93,95],{"id":94},"the-practical-stuff","The practical stuff",[11,97,98],{},"Once I learned basic Python, the first thing I wrote set up my whole project folder in one command. Then batch renaming frames. Then a script that reads a CSV and spits out title cards in After Effects. None of it was clever — just enough to stop doing the boring parts by hand.",[11,100,101],{},"The mental shift matters too. You start seeing animation as systems rather than one-off solutions. That makes you better at both.",[103,104,105],"style",{},"html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":20,"searchDepth":107,"depth":107,"links":108},2,[109,110],{"id":57,"depth":107,"text":58},{"id":94,"depth":107,"text":95},"12 September, 2025","A look at how picking up even basic programming skills can make you a more versatile artist.","md",[115,117],{"src":20,"alt":116},"A cluttered desk with a monitor showing After Effects alongside a code editor",{"src":20,"alt":118},"A terminal window with a Python script automating file renaming",{},true,"\u002Farticle\u002F0010_dummy_article",{"title":6,"description":112},"article\u002F0010_dummy_article",[125,126,127,128],"animation","coding","workflow","career",[130,131,132],"After Effects","Python","JavaScript","0vWaRTzMEbFq7vOqri_a7PBfGj-c_erzUq5w_GXme7Y",{"id":135,"title":136,"body":137,"date":371,"description":372,"extension":113,"images":373,"meta":378,"navigation":120,"path":379,"seo":380,"stem":381,"tags":382,"thumbnail":20,"tools":386,"__hash__":387},"articles\u002Farticle\u002F0020_dummy_article.md","After Effects Expressions for Noobs",{"type":8,"value":138,"toc":366},[139,142,145,149,154,178,184,228,234,253,259,292,296,299,353,356,360,363],[11,140,141],{},"Alt-click a stopwatch. Type some code. Done — you're writing expressions.",[11,143,144],{},"No setup, no IDE, no terminal. The feedback is instant and visual, which makes this the best possible way to start learning code as an animator.",[55,146,148],{"id":147},"the-four-youll-use-everywhere","The four you'll use everywhere",[11,150,151,153],{},[69,152,32],{}," — shake a layer organically",[15,155,157],{"className":17,"code":156,"language":19,"meta":20,"style":20},"wiggle(3, 20) \u002F\u002F 3x per second, 20px max offset\n",[22,158,159],{"__ignoreMap":20},[25,160,161,163,165,167,169,171,174],{"class":27,"line":28},[25,162,32],{"class":31},[25,164,36],{"class":35},[25,166,40],{"class":39},[25,168,44],{"class":43},[25,170,47],{"class":39},[25,172,173],{"class":35},") ",[25,175,177],{"class":176},"sHwdD","\u002F\u002F 3x per second, 20px max offset\n",[11,179,180,183],{},[69,181,182],{},"loopOut"," — loop your keyframes forever",[15,185,187],{"className":17,"code":186,"language":19,"meta":20,"style":20},"loopOut(\"cycle\")    \u002F\u002F repeats forward\nloopOut(\"pingpong\") \u002F\u002F reverses each loop\n",[22,188,189,210],{"__ignoreMap":20},[25,190,191,193,195,198,202,204,207],{"class":27,"line":28},[25,192,182],{"class":31},[25,194,36],{"class":35},[25,196,197],{"class":43},"\"",[25,199,201],{"class":200},"sfazB","cycle",[25,203,197],{"class":43},[25,205,206],{"class":35},")    ",[25,208,209],{"class":176},"\u002F\u002F repeats forward\n",[25,211,212,214,216,218,221,223,225],{"class":27,"line":107},[25,213,182],{"class":31},[25,215,36],{"class":35},[25,217,197],{"class":43},[25,219,220],{"class":200},"pingpong",[25,222,197],{"class":43},[25,224,173],{"class":35},[25,226,227],{"class":176},"\u002F\u002F reverses each loop\n",[11,229,230,233],{},[69,231,232],{},"time"," — drive anything with the clock",[15,235,237],{"className":17,"code":236,"language":19,"meta":20,"style":20},"time * 90 \u002F\u002F slow spin. crank it up for faster\n",[22,238,239],{"__ignoreMap":20},[25,240,241,244,247,250],{"class":27,"line":28},[25,242,243],{"class":35},"time ",[25,245,246],{"class":43},"*",[25,248,249],{"class":39}," 90",[25,251,252],{"class":176}," \u002F\u002F slow spin. crank it up for faster\n",[11,254,255,258],{},[69,256,257],{},"value"," — offset whatever's already keyframed",[15,260,262],{"className":17,"code":261,"language":19,"meta":20,"style":20},"value + [0, -50] \u002F\u002F push the existing position up by 50px\n",[22,263,264],{"__ignoreMap":20},[25,265,266,269,272,275,278,280,283,286,289],{"class":27,"line":28},[25,267,268],{"class":35},"value ",[25,270,271],{"class":43},"+",[25,273,274],{"class":35}," [",[25,276,277],{"class":39},"0",[25,279,44],{"class":43},[25,281,282],{"class":43}," -",[25,284,285],{"class":39},"50",[25,287,288],{"class":35},"] ",[25,290,291],{"class":176},"\u002F\u002F push the existing position up by 50px\n",[55,293,295],{"id":294},"linking-properties","Linking properties",[11,297,298],{},"Drag the pickWhip from one property to another and AE writes the expression for you. Useful for tying a layer's opacity to a slider, or locking scale to a null.",[15,300,302],{"className":17,"code":301,"language":19,"meta":20,"style":20},"thisComp.layer(\"Control\").effect(\"Opacity\")(\"Slider\")\n",[22,303,304],{"__ignoreMap":20},[25,305,306,309,312,315,317,319,322,324,327,329,332,334,336,339,341,344,346,349,351],{"class":27,"line":28},[25,307,308],{"class":35},"thisComp",[25,310,311],{"class":43},".",[25,313,314],{"class":31},"layer",[25,316,36],{"class":35},[25,318,197],{"class":43},[25,320,321],{"class":200},"Control",[25,323,197],{"class":43},[25,325,326],{"class":35},")",[25,328,311],{"class":43},[25,330,331],{"class":31},"effect",[25,333,36],{"class":35},[25,335,197],{"class":43},[25,337,338],{"class":200},"Opacity",[25,340,197],{"class":43},[25,342,343],{"class":35},")(",[25,345,197],{"class":43},[25,347,348],{"class":200},"Slider",[25,350,197],{"class":43},[25,352,50],{"class":35},[11,354,355],{},"You don't need to write that by hand — just read it after the pickWhip generates it, and it'll start making sense.",[55,357,359],{"id":358},"just-start","Just start",[11,361,362],{},"Take any animation you've already built. Add one expression. Break it. Fix it. That's the whole method.",[103,364,365],{},"html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":20,"searchDepth":107,"depth":107,"links":367},[368,369,370],{"id":147,"depth":107,"text":148},{"id":294,"depth":107,"text":295},{"id":358,"depth":107,"text":359},"28 October, 2025","Expressions are the gateway drug for animators learning to code. Here's how to approach them without feeling lost, and the handful you'll use constantly.",[374,376],{"src":20,"alt":375},"After Effects timeline with an expression applied to a position property",{"src":20,"alt":377},"The expression editor open in After Effects showing a wiggle expression",{},"\u002Farticle\u002F0020_dummy_article",{"title":136,"description":372},"article\u002F0020_dummy_article",[383,384,126,385],"after effects","expressions","tutorial",[130,132],"3WTWxPPjS7H1RFxkS9C9hCmREQvN5Q8nw184RUZnjnw",{"id":389,"title":390,"body":391,"date":576,"description":577,"extension":113,"images":578,"meta":583,"navigation":120,"path":584,"seo":585,"stem":586,"tags":587,"thumbnail":20,"tools":590,"__hash__":592},"articles\u002Farticle\u002F0030_dummy_article.md","Automating Your Pipeline with Python",{"type":8,"value":392,"toc":571},[393,396,400,403,490,508,511,515,522,551,555,562,565,568],[11,394,395],{},"The work that isn't animation — renaming frames, building folder trees, converting formats — quietly eats hours. Python makes it disappear.",[55,397,399],{"id":398},"project-setup","Project setup",[11,401,402],{},"Write this once, run it at the start of every job:",[15,404,408],{"className":405,"code":406,"language":407,"meta":20,"style":20},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import os, sys\n\nname = sys.argv[1]\nbase = f\"\u002FUsers\u002Fyou\u002FProjects\u002F{name}\"\n\nfor folder in [\n    \"01_assets\u002Ffootage\", \"01_assets\u002Faudio\",\n    \"02_project_files\",\n    \"03_renders\u002Fwip\", \"03_renders\u002Ffinal\",\n    \"04_delivery\"\n]:\n    os.makedirs(f\"{base}\u002F{folder}\", exist_ok=True)\n\nprint(f\"Created: {name}\")\n","python",[22,409,410,415,420,426,432,437,443,449,455,461,467,473,479,484],{"__ignoreMap":20},[25,411,412],{"class":27,"line":28},[25,413,414],{},"import os, sys\n",[25,416,417],{"class":27,"line":107},[25,418,419],{"emptyLinePlaceholder":120},"\n",[25,421,423],{"class":27,"line":422},3,[25,424,425],{},"name = sys.argv[1]\n",[25,427,429],{"class":27,"line":428},4,[25,430,431],{},"base = f\"\u002FUsers\u002Fyou\u002FProjects\u002F{name}\"\n",[25,433,435],{"class":27,"line":434},5,[25,436,419],{"emptyLinePlaceholder":120},[25,438,440],{"class":27,"line":439},6,[25,441,442],{},"for folder in [\n",[25,444,446],{"class":27,"line":445},7,[25,447,448],{},"    \"01_assets\u002Ffootage\", \"01_assets\u002Faudio\",\n",[25,450,452],{"class":27,"line":451},8,[25,453,454],{},"    \"02_project_files\",\n",[25,456,458],{"class":27,"line":457},9,[25,459,460],{},"    \"03_renders\u002Fwip\", \"03_renders\u002Ffinal\",\n",[25,462,464],{"class":27,"line":463},10,[25,465,466],{},"    \"04_delivery\"\n",[25,468,470],{"class":27,"line":469},11,[25,471,472],{},"]:\n",[25,474,476],{"class":27,"line":475},12,[25,477,478],{},"    os.makedirs(f\"{base}\u002F{folder}\", exist_ok=True)\n",[25,480,482],{"class":27,"line":481},13,[25,483,419],{"emptyLinePlaceholder":120},[25,485,487],{"class":27,"line":486},14,[25,488,489],{},"print(f\"Created: {name}\")\n",[15,491,495],{"className":492,"code":493,"language":494,"meta":20,"style":20},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","python setup.py client-name\n","bash",[22,496,497],{"__ignoreMap":20},[25,498,499,502,505],{"class":27,"line":28},[25,500,407],{"class":501},"sBMFI",[25,503,504],{"class":200}," setup.py",[25,506,507],{"class":200}," client-name\n",[11,509,510],{},"Whole folder tree, named consistently, in under a second.",[55,512,514],{"id":513},"batch-rename-frames","Batch rename frames",[11,516,517,518,521],{},"AE renders frames like ",[22,519,520],{},"comp_[0000].png",". This cleans them up:",[15,523,525],{"className":405,"code":524,"language":407,"meta":20,"style":20},"from pathlib import Path\n\nrender_dir = Path(\"\u002Fpath\u002Fto\u002Frenders\")\nfor i, f in enumerate(sorted(render_dir.glob(\"*.png\"))):\n    f.rename(render_dir \u002F f\"output_{i:04d}.png\")\n",[22,526,527,532,536,541,546],{"__ignoreMap":20},[25,528,529],{"class":27,"line":28},[25,530,531],{},"from pathlib import Path\n",[25,533,534],{"class":27,"line":107},[25,535,419],{"emptyLinePlaceholder":120},[25,537,538],{"class":27,"line":422},[25,539,540],{},"render_dir = Path(\"\u002Fpath\u002Fto\u002Frenders\")\n",[25,542,543],{"class":27,"line":428},[25,544,545],{},"for i, f in enumerate(sorted(render_dir.glob(\"*.png\"))):\n",[25,547,548],{"class":27,"line":434},[25,549,550],{},"    f.rename(render_dir \u002F f\"output_{i:04d}.png\")\n",[55,552,554],{"id":553},"notify-on-render-complete","Notify on render complete",[11,556,557,558,561],{},"Install ",[22,559,560],{},"watchdog"," and point it at your renders folder. It fires a desktop notification (or a Slack message) the moment new files appear. No more tabbing back to check.",[563,564],"hr",{},[11,566,567],{},"Start with the folder script. Customize it to your actual workflow. Then find the next annoying repetitive thing and automate that. That's it.",[103,569,570],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":20,"searchDepth":107,"depth":107,"links":572},[573,574,575],{"id":398,"depth":107,"text":399},{"id":513,"depth":107,"text":514},{"id":553,"depth":107,"text":554},"14 November, 2025","The repetitive parts of production work — file management, render tracking, asset organization — are exactly what Python is built to eliminate. Here's where to start.",[579,581],{"src":20,"alt":580},"A terminal showing a Python script output listing renamed render files",{"src":20,"alt":582},"A folder structure generated automatically by a project setup script",{},"\u002Farticle\u002F0030_dummy_article",{"title":390,"description":577},"article\u002F0030_dummy_article",[588,407,589,127],"automation","pipeline",[131,130,591],"Terminal","Dx23q0uvfYWR0uPPRHIDBU1RjA4HkKgCDrVwnzmwrHA",{"id":594,"title":595,"body":596,"date":1300,"description":1301,"extension":113,"images":1302,"meta":1307,"navigation":120,"path":1308,"seo":1309,"stem":1310,"tags":1311,"thumbnail":20,"tools":1315,"__hash__":1316},"articles\u002Farticle\u002F0040_dummy_article.md","Generative Art and Animation",{"type":8,"value":597,"toc":1294},[598,609,613,784,787,791,801,933,936,940,943,1284,1288,1291],[11,599,600,601,604,605,608],{},"Generative art is what happens when you write rules and let the output surprise you. For animators it clicks fast — ",[22,602,603],{},"setup()"," runs once, ",[22,606,607],{},"draw()"," runs every frame. You've thought in frames your whole career.",[55,610,612],{"id":611},"start-here","Start here",[15,614,616],{"className":17,"code":615,"language":19,"meta":20,"style":20},"function setup() {\n  createCanvas(800, 800);\n  background(10);\n}\n\nfunction draw() {\n  fill(random(255), 150, 200, 80);\n  noStroke();\n  ellipse(random(width), random(height), random(5, 30));\n}\n",[22,617,618,633,654,668,673,677,688,724,733,780],{"__ignoreMap":20},[25,619,620,624,627,630],{"class":27,"line":28},[25,621,623],{"class":622},"spNyl","function",[25,625,626],{"class":31}," setup",[25,628,629],{"class":43},"()",[25,631,632],{"class":43}," {\n",[25,634,635,638,641,644,646,649,651],{"class":27,"line":107},[25,636,637],{"class":31},"  createCanvas",[25,639,36],{"class":640},"swJcz",[25,642,643],{"class":39},"800",[25,645,44],{"class":43},[25,647,648],{"class":39}," 800",[25,650,326],{"class":640},[25,652,653],{"class":43},";\n",[25,655,656,659,661,664,666],{"class":27,"line":422},[25,657,658],{"class":31},"  background",[25,660,36],{"class":640},[25,662,663],{"class":39},"10",[25,665,326],{"class":640},[25,667,653],{"class":43},[25,669,670],{"class":27,"line":428},[25,671,672],{"class":43},"}\n",[25,674,675],{"class":27,"line":434},[25,676,419],{"emptyLinePlaceholder":120},[25,678,679,681,684,686],{"class":27,"line":439},[25,680,623],{"class":622},[25,682,683],{"class":31}," draw",[25,685,629],{"class":43},[25,687,632],{"class":43},[25,689,690,693,695,698,700,703,705,707,710,712,715,717,720,722],{"class":27,"line":445},[25,691,692],{"class":31},"  fill",[25,694,36],{"class":640},[25,696,697],{"class":31},"random",[25,699,36],{"class":640},[25,701,702],{"class":39},"255",[25,704,326],{"class":640},[25,706,44],{"class":43},[25,708,709],{"class":39}," 150",[25,711,44],{"class":43},[25,713,714],{"class":39}," 200",[25,716,44],{"class":43},[25,718,719],{"class":39}," 80",[25,721,326],{"class":640},[25,723,653],{"class":43},[25,725,726,729,731],{"class":27,"line":451},[25,727,728],{"class":31},"  noStroke",[25,730,629],{"class":640},[25,732,653],{"class":43},[25,734,735,738,740,742,744,747,749,751,754,756,759,761,763,765,767,770,772,775,778],{"class":27,"line":457},[25,736,737],{"class":31},"  ellipse",[25,739,36],{"class":640},[25,741,697],{"class":31},[25,743,36],{"class":640},[25,745,746],{"class":35},"width",[25,748,326],{"class":640},[25,750,44],{"class":43},[25,752,753],{"class":31}," random",[25,755,36],{"class":640},[25,757,758],{"class":35},"height",[25,760,326],{"class":640},[25,762,44],{"class":43},[25,764,753],{"class":31},[25,766,36],{"class":640},[25,768,769],{"class":39},"5",[25,771,44],{"class":43},[25,773,774],{"class":39}," 30",[25,776,777],{"class":640},"))",[25,779,653],{"class":43},[25,781,782],{"class":27,"line":463},[25,783,672],{"class":43},[11,785,786],{},"Random semi-transparent circles, every frame. Not much — but it's a live, running visual system in ten lines.",[55,788,790],{"id":789},"random-vs-noise","random() vs noise()",[11,792,793,796,797,800],{},[22,794,795],{},"random()"," jumps around chaotically. ",[22,798,799],{},"noise()"," flows smoothly — more organic, more interesting:",[15,802,804],{"className":17,"code":803,"language":19,"meta":20,"style":20},"let t = 0;\n\nfunction draw() {\n  let x = noise(t) * width;\n  let y = noise(t + 100) * height;\n  ellipse(x, y, 8);\n  t += 0.005;\n}\n",[22,805,806,822,826,836,864,894,916,929],{"__ignoreMap":20},[25,807,808,811,814,817,820],{"class":27,"line":28},[25,809,810],{"class":622},"let",[25,812,813],{"class":35}," t ",[25,815,816],{"class":43},"=",[25,818,819],{"class":39}," 0",[25,821,653],{"class":43},[25,823,824],{"class":27,"line":107},[25,825,419],{"emptyLinePlaceholder":120},[25,827,828,830,832,834],{"class":27,"line":422},[25,829,623],{"class":622},[25,831,683],{"class":31},[25,833,629],{"class":43},[25,835,632],{"class":43},[25,837,838,841,844,847,850,852,855,857,859,862],{"class":27,"line":428},[25,839,840],{"class":622},"  let",[25,842,843],{"class":35}," x",[25,845,846],{"class":43}," =",[25,848,849],{"class":31}," noise",[25,851,36],{"class":640},[25,853,854],{"class":35},"t",[25,856,173],{"class":640},[25,858,246],{"class":43},[25,860,861],{"class":35}," width",[25,863,653],{"class":43},[25,865,866,868,871,873,875,877,879,882,885,887,889,892],{"class":27,"line":434},[25,867,840],{"class":622},[25,869,870],{"class":35}," y",[25,872,846],{"class":43},[25,874,849],{"class":31},[25,876,36],{"class":640},[25,878,854],{"class":35},[25,880,881],{"class":43}," +",[25,883,884],{"class":39}," 100",[25,886,173],{"class":640},[25,888,246],{"class":43},[25,890,891],{"class":35}," height",[25,893,653],{"class":43},[25,895,896,898,900,903,905,907,909,912,914],{"class":27,"line":439},[25,897,737],{"class":31},[25,899,36],{"class":640},[25,901,902],{"class":35},"x",[25,904,44],{"class":43},[25,906,870],{"class":35},[25,908,44],{"class":43},[25,910,911],{"class":39}," 8",[25,913,326],{"class":640},[25,915,653],{"class":43},[25,917,918,921,924,927],{"class":27,"line":445},[25,919,920],{"class":35},"  t",[25,922,923],{"class":43}," +=",[25,925,926],{"class":39}," 0.005",[25,928,653],{"class":43},[25,930,931],{"class":27,"line":451},[25,932,672],{"class":43},[11,934,935],{},"Pass different offsets for X and Y and you get wandering motion with no keyframes. This is Perlin noise — the function behind most natural-looking generative movement.",[55,937,939],{"id":938},"particle-systems","Particle systems",[11,941,942],{},"A classic: a bunch of points that each move independently.",[15,944,946],{"className":17,"code":945,"language":19,"meta":20,"style":20},"let particles = [];\n\nfunction setup() {\n  createCanvas(800, 800);\n  for (let i = 0; i \u003C 200; i++) {\n    particles.push({ x: random(width), y: random(height), t: random(1000) });\n  }\n}\n\nfunction draw() {\n  background(10, 20); \u002F\u002F low alpha = trails\n  for (let p of particles) {\n    p.x += noise(p.t) * 4 - 2;\n    p.y += noise(p.t + 500) * 4 - 2;\n    point(p.x, p.y);\n    p.t += 0.005;\n  }\n}\n",[22,947,948,962,966,976,992,1032,1097,1102,1106,1110,1120,1139,1160,1195,1233,1259,1274,1279],{"__ignoreMap":20},[25,949,950,952,955,957,960],{"class":27,"line":28},[25,951,810],{"class":622},[25,953,954],{"class":35}," particles ",[25,956,816],{"class":43},[25,958,959],{"class":35}," []",[25,961,653],{"class":43},[25,963,964],{"class":27,"line":107},[25,965,419],{"emptyLinePlaceholder":120},[25,967,968,970,972,974],{"class":27,"line":422},[25,969,623],{"class":622},[25,971,626],{"class":31},[25,973,629],{"class":43},[25,975,632],{"class":43},[25,977,978,980,982,984,986,988,990],{"class":27,"line":428},[25,979,637],{"class":31},[25,981,36],{"class":640},[25,983,643],{"class":39},[25,985,44],{"class":43},[25,987,648],{"class":39},[25,989,326],{"class":640},[25,991,653],{"class":43},[25,993,994,998,1001,1003,1006,1008,1010,1013,1015,1018,1020,1022,1024,1027,1029],{"class":27,"line":434},[25,995,997],{"class":996},"s7zQu","  for",[25,999,1000],{"class":640}," (",[25,1002,810],{"class":622},[25,1004,1005],{"class":35}," i",[25,1007,846],{"class":43},[25,1009,819],{"class":39},[25,1011,1012],{"class":43},";",[25,1014,1005],{"class":35},[25,1016,1017],{"class":43}," \u003C",[25,1019,714],{"class":39},[25,1021,1012],{"class":43},[25,1023,1005],{"class":35},[25,1025,1026],{"class":43},"++",[25,1028,173],{"class":640},[25,1030,1031],{"class":43},"{\n",[25,1033,1034,1037,1039,1042,1044,1047,1049,1052,1054,1056,1058,1060,1062,1064,1066,1068,1070,1072,1074,1076,1079,1081,1083,1085,1088,1090,1093,1095],{"class":27,"line":439},[25,1035,1036],{"class":35},"    particles",[25,1038,311],{"class":43},[25,1040,1041],{"class":31},"push",[25,1043,36],{"class":640},[25,1045,1046],{"class":43},"{",[25,1048,843],{"class":640},[25,1050,1051],{"class":43},":",[25,1053,753],{"class":31},[25,1055,36],{"class":640},[25,1057,746],{"class":35},[25,1059,326],{"class":640},[25,1061,44],{"class":43},[25,1063,870],{"class":640},[25,1065,1051],{"class":43},[25,1067,753],{"class":31},[25,1069,36],{"class":640},[25,1071,758],{"class":35},[25,1073,326],{"class":640},[25,1075,44],{"class":43},[25,1077,1078],{"class":640}," t",[25,1080,1051],{"class":43},[25,1082,753],{"class":31},[25,1084,36],{"class":640},[25,1086,1087],{"class":39},"1000",[25,1089,173],{"class":640},[25,1091,1092],{"class":43},"}",[25,1094,326],{"class":640},[25,1096,653],{"class":43},[25,1098,1099],{"class":27,"line":445},[25,1100,1101],{"class":43},"  }\n",[25,1103,1104],{"class":27,"line":451},[25,1105,672],{"class":43},[25,1107,1108],{"class":27,"line":457},[25,1109,419],{"emptyLinePlaceholder":120},[25,1111,1112,1114,1116,1118],{"class":27,"line":463},[25,1113,623],{"class":622},[25,1115,683],{"class":31},[25,1117,629],{"class":43},[25,1119,632],{"class":43},[25,1121,1122,1124,1126,1128,1130,1132,1134,1136],{"class":27,"line":469},[25,1123,658],{"class":31},[25,1125,36],{"class":640},[25,1127,663],{"class":39},[25,1129,44],{"class":43},[25,1131,47],{"class":39},[25,1133,326],{"class":640},[25,1135,1012],{"class":43},[25,1137,1138],{"class":176}," \u002F\u002F low alpha = trails\n",[25,1140,1141,1143,1145,1147,1150,1153,1156,1158],{"class":27,"line":475},[25,1142,997],{"class":996},[25,1144,1000],{"class":640},[25,1146,810],{"class":622},[25,1148,1149],{"class":35}," p",[25,1151,1152],{"class":43}," of",[25,1154,1155],{"class":35}," particles",[25,1157,173],{"class":640},[25,1159,1031],{"class":43},[25,1161,1162,1165,1167,1169,1171,1173,1175,1177,1179,1181,1183,1185,1188,1190,1193],{"class":27,"line":481},[25,1163,1164],{"class":35},"    p",[25,1166,311],{"class":43},[25,1168,902],{"class":35},[25,1170,923],{"class":43},[25,1172,849],{"class":31},[25,1174,36],{"class":640},[25,1176,11],{"class":35},[25,1178,311],{"class":43},[25,1180,854],{"class":35},[25,1182,173],{"class":640},[25,1184,246],{"class":43},[25,1186,1187],{"class":39}," 4",[25,1189,282],{"class":43},[25,1191,1192],{"class":39}," 2",[25,1194,653],{"class":43},[25,1196,1197,1199,1201,1204,1206,1208,1210,1212,1214,1216,1218,1221,1223,1225,1227,1229,1231],{"class":27,"line":486},[25,1198,1164],{"class":35},[25,1200,311],{"class":43},[25,1202,1203],{"class":35},"y",[25,1205,923],{"class":43},[25,1207,849],{"class":31},[25,1209,36],{"class":640},[25,1211,11],{"class":35},[25,1213,311],{"class":43},[25,1215,854],{"class":35},[25,1217,881],{"class":43},[25,1219,1220],{"class":39}," 500",[25,1222,173],{"class":640},[25,1224,246],{"class":43},[25,1226,1187],{"class":39},[25,1228,282],{"class":43},[25,1230,1192],{"class":39},[25,1232,653],{"class":43},[25,1234,1236,1239,1241,1243,1245,1247,1249,1251,1253,1255,1257],{"class":27,"line":1235},15,[25,1237,1238],{"class":31},"    point",[25,1240,36],{"class":640},[25,1242,11],{"class":35},[25,1244,311],{"class":43},[25,1246,902],{"class":35},[25,1248,44],{"class":43},[25,1250,1149],{"class":35},[25,1252,311],{"class":43},[25,1254,1203],{"class":35},[25,1256,326],{"class":640},[25,1258,653],{"class":43},[25,1260,1262,1264,1266,1268,1270,1272],{"class":27,"line":1261},16,[25,1263,1164],{"class":35},[25,1265,311],{"class":43},[25,1267,854],{"class":35},[25,1269,923],{"class":43},[25,1271,926],{"class":39},[25,1273,653],{"class":43},[25,1275,1277],{"class":27,"line":1276},17,[25,1278,1101],{"class":43},[25,1280,1282],{"class":27,"line":1281},18,[25,1283,672],{"class":43},[55,1285,1287],{"id":1286},"bringing-it-back-to-video","Bringing it back to video",[11,1289,1290],{},"p5.js sketches can be recorded frame-by-frame and imported into After Effects as image sequences. Complex organic backgrounds, particle passes, texture layers — all faster to generate in code than to animate by hand.",[103,1292,1293],{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":20,"searchDepth":107,"depth":107,"links":1295},[1296,1297,1298,1299],{"id":611,"depth":107,"text":612},{"id":789,"depth":107,"text":790},{"id":938,"depth":107,"text":939},{"id":1286,"depth":107,"text":1287},"3 December, 2025","What happens when you apply an animator's instincts — timing, rhythm, visual weight — to systems built from code? A look at creative coding through the lens of motion work.",[1303,1305],{"src":20,"alt":1304},"A generative sketch showing flowing particle trails built in p5.js",{"src":20,"alt":1306},"A grid of color-shifting rectangles animated with noise functions",{},"\u002Farticle\u002F0040_dummy_article",{"title":595,"description":1301},"article\u002F0040_dummy_article",[1312,1313,1314,125],"generative art","creative coding","p5.js",[1314,132,130],"RKmBbN3dF1C5dHmVYBY47LCiDnX54JqHY9wjzsWVmG4",{"id":1318,"title":1319,"body":1320,"date":1839,"description":1840,"extension":113,"images":1841,"meta":1846,"navigation":120,"path":1847,"seo":1848,"stem":1849,"tags":1850,"thumbnail":20,"tools":1854,"__hash__":1857},"articles\u002Farticle\u002F0050_dummy_article.md","From Motion Graphics to JavaScript",{"type":8,"value":1321,"toc":1834},[1322,1325,1329,1336,1396,1399,1601,1604,1608,1614,1717,1723,1821,1824,1828,1831],[11,1323,1324],{},"A lot of the most interesting animation happening right now isn't in video — it's in browsers. Scroll-triggered reveals, type that follows the cursor, interactive data viz. Same goal as motion work, totally different pipeline.",[55,1326,1328],{"id":1327},"what-carries-over","What carries over",[11,1330,1331,1332,1335],{},"Easing vocabulary is identical. ",[22,1333,1334],{},"ease-in-out",", bezier curves — same model as After Effects, different syntax:",[15,1337,1341],{"className":1338,"code":1339,"language":1340,"meta":20,"style":20},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight",".box {\n  transition: transform 0.4s cubic-bezier(0.25, 0.1, 0.25, 1);\n}\n","css",[22,1342,1343,1352,1392],{"__ignoreMap":20},[25,1344,1345,1347,1350],{"class":27,"line":28},[25,1346,311],{"class":43},[25,1348,1349],{"class":501},"box",[25,1351,632],{"class":43},[25,1353,1354,1358,1360,1363,1366,1369,1371,1374,1376,1379,1381,1384,1386,1389],{"class":27,"line":107},[25,1355,1357],{"class":1356},"sqsOY","  transition",[25,1359,1051],{"class":43},[25,1361,1362],{"class":35}," transform ",[25,1364,1365],{"class":39},"0.4s",[25,1367,1368],{"class":31}," cubic-bezier",[25,1370,36],{"class":43},[25,1372,1373],{"class":39},"0.25",[25,1375,44],{"class":43},[25,1377,1378],{"class":39}," 0.1",[25,1380,44],{"class":43},[25,1382,1383],{"class":39}," 0.25",[25,1385,44],{"class":43},[25,1387,1388],{"class":39}," 1",[25,1390,1391],{"class":43},");\n",[25,1393,1394],{"class":27,"line":422},[25,1395,672],{"class":43},[11,1397,1398],{},"And GSAP's timeline API maps almost directly to how you already think:",[15,1400,1402],{"className":17,"code":1401,"language":19,"meta":20,"style":20},"gsap.timeline()\n  .from(\".headline\", { opacity: 0, y: 40, duration: 0.6, ease: \"power2.out\" })\n  .from(\".subhead\",  { opacity: 0, y: 20, duration: 0.4, ease: \"power2.out\" }, \"-=0.2\")\n  .from(\".body\",     { opacity: 0,         duration: 0.3 }, \"-=0.1\");\n",[22,1403,1404,1417,1485,1552],{"__ignoreMap":20},[25,1405,1406,1409,1411,1414],{"class":27,"line":28},[25,1407,1408],{"class":35},"gsap",[25,1410,311],{"class":43},[25,1412,1413],{"class":31},"timeline",[25,1415,1416],{"class":35},"()\n",[25,1418,1419,1422,1425,1427,1429,1432,1434,1436,1439,1442,1444,1446,1448,1450,1452,1455,1457,1460,1462,1465,1467,1470,1472,1475,1478,1480,1483],{"class":27,"line":107},[25,1420,1421],{"class":43},"  .",[25,1423,1424],{"class":31},"from",[25,1426,36],{"class":35},[25,1428,197],{"class":43},[25,1430,1431],{"class":200},".headline",[25,1433,197],{"class":43},[25,1435,44],{"class":43},[25,1437,1438],{"class":43}," {",[25,1440,1441],{"class":640}," opacity",[25,1443,1051],{"class":43},[25,1445,819],{"class":39},[25,1447,44],{"class":43},[25,1449,870],{"class":640},[25,1451,1051],{"class":43},[25,1453,1454],{"class":39}," 40",[25,1456,44],{"class":43},[25,1458,1459],{"class":640}," duration",[25,1461,1051],{"class":43},[25,1463,1464],{"class":39}," 0.6",[25,1466,44],{"class":43},[25,1468,1469],{"class":640}," ease",[25,1471,1051],{"class":43},[25,1473,1474],{"class":43}," \"",[25,1476,1477],{"class":200},"power2.out",[25,1479,197],{"class":43},[25,1481,1482],{"class":43}," }",[25,1484,50],{"class":35},[25,1486,1487,1489,1491,1493,1495,1498,1500,1502,1505,1507,1509,1511,1513,1515,1517,1519,1521,1523,1525,1528,1530,1532,1534,1536,1538,1540,1543,1545,1548,1550],{"class":27,"line":422},[25,1488,1421],{"class":43},[25,1490,1424],{"class":31},[25,1492,36],{"class":35},[25,1494,197],{"class":43},[25,1496,1497],{"class":200},".subhead",[25,1499,197],{"class":43},[25,1501,44],{"class":43},[25,1503,1504],{"class":43},"  {",[25,1506,1441],{"class":640},[25,1508,1051],{"class":43},[25,1510,819],{"class":39},[25,1512,44],{"class":43},[25,1514,870],{"class":640},[25,1516,1051],{"class":43},[25,1518,47],{"class":39},[25,1520,44],{"class":43},[25,1522,1459],{"class":640},[25,1524,1051],{"class":43},[25,1526,1527],{"class":39}," 0.4",[25,1529,44],{"class":43},[25,1531,1469],{"class":640},[25,1533,1051],{"class":43},[25,1535,1474],{"class":43},[25,1537,1477],{"class":200},[25,1539,197],{"class":43},[25,1541,1542],{"class":43}," },",[25,1544,1474],{"class":43},[25,1546,1547],{"class":200},"-=0.2",[25,1549,197],{"class":43},[25,1551,50],{"class":35},[25,1553,1554,1556,1558,1560,1562,1565,1567,1569,1572,1574,1576,1578,1580,1583,1585,1588,1590,1592,1595,1597,1599],{"class":27,"line":428},[25,1555,1421],{"class":43},[25,1557,1424],{"class":31},[25,1559,36],{"class":35},[25,1561,197],{"class":43},[25,1563,1564],{"class":200},".body",[25,1566,197],{"class":43},[25,1568,44],{"class":43},[25,1570,1571],{"class":43},"     {",[25,1573,1441],{"class":640},[25,1575,1051],{"class":43},[25,1577,819],{"class":39},[25,1579,44],{"class":43},[25,1581,1582],{"class":640},"         duration",[25,1584,1051],{"class":43},[25,1586,1587],{"class":39}," 0.3",[25,1589,1542],{"class":43},[25,1591,1474],{"class":43},[25,1593,1594],{"class":200},"-=0.1",[25,1596,197],{"class":43},[25,1598,326],{"class":35},[25,1600,653],{"class":43},[11,1602,1603],{},"Tweens, sequencing, overlap offsets — same mental model.",[55,1605,1607],{"id":1606},"whats-new","What's new",[11,1609,1610,1613],{},[69,1611,1612],{},"Events"," replace the render button. Animation responds to what the user does:",[15,1615,1617],{"className":17,"code":1616,"language":19,"meta":20,"style":20},"document.querySelector(\".btn\").addEventListener(\"mouseenter\", () => {\n  gsap.to(\".btn\", { scale: 1.05, duration: 0.2 });\n});\n",[22,1618,1619,1664,1709],{"__ignoreMap":20},[25,1620,1621,1624,1626,1629,1631,1633,1636,1638,1640,1642,1645,1647,1649,1652,1654,1656,1659,1662],{"class":27,"line":28},[25,1622,1623],{"class":35},"document",[25,1625,311],{"class":43},[25,1627,1628],{"class":31},"querySelector",[25,1630,36],{"class":35},[25,1632,197],{"class":43},[25,1634,1635],{"class":200},".btn",[25,1637,197],{"class":43},[25,1639,326],{"class":35},[25,1641,311],{"class":43},[25,1643,1644],{"class":31},"addEventListener",[25,1646,36],{"class":35},[25,1648,197],{"class":43},[25,1650,1651],{"class":200},"mouseenter",[25,1653,197],{"class":43},[25,1655,44],{"class":43},[25,1657,1658],{"class":43}," ()",[25,1660,1661],{"class":622}," =>",[25,1663,632],{"class":43},[25,1665,1666,1669,1671,1674,1676,1678,1680,1682,1684,1686,1689,1691,1694,1696,1698,1700,1703,1705,1707],{"class":27,"line":107},[25,1667,1668],{"class":35},"  gsap",[25,1670,311],{"class":43},[25,1672,1673],{"class":31},"to",[25,1675,36],{"class":640},[25,1677,197],{"class":43},[25,1679,1635],{"class":200},[25,1681,197],{"class":43},[25,1683,44],{"class":43},[25,1685,1438],{"class":43},[25,1687,1688],{"class":640}," scale",[25,1690,1051],{"class":43},[25,1692,1693],{"class":39}," 1.05",[25,1695,44],{"class":43},[25,1697,1459],{"class":640},[25,1699,1051],{"class":43},[25,1701,1702],{"class":39}," 0.2",[25,1704,1482],{"class":43},[25,1706,326],{"class":640},[25,1708,653],{"class":43},[25,1710,1711,1713,1715],{"class":27,"line":422},[25,1712,1092],{"class":43},[25,1714,326],{"class":35},[25,1716,653],{"class":43},[11,1718,1719,1722],{},[69,1720,1721],{},"ScrollTrigger"," is where things get fun:",[15,1724,1726],{"className":17,"code":1725,"language":19,"meta":20,"style":20},"gsap.from(\".panel\", {\n  scrollTrigger: { trigger: \".panel\", start: \"top 80%\" },\n  opacity: 0, y: 60, duration: 0.8\n});\n",[22,1727,1728,1749,1786,1813],{"__ignoreMap":20},[25,1729,1730,1732,1734,1736,1738,1740,1743,1745,1747],{"class":27,"line":28},[25,1731,1408],{"class":35},[25,1733,311],{"class":43},[25,1735,1424],{"class":31},[25,1737,36],{"class":35},[25,1739,197],{"class":43},[25,1741,1742],{"class":200},".panel",[25,1744,197],{"class":43},[25,1746,44],{"class":43},[25,1748,632],{"class":43},[25,1750,1751,1754,1756,1758,1761,1763,1765,1767,1769,1771,1774,1776,1778,1781,1783],{"class":27,"line":107},[25,1752,1753],{"class":640},"  scrollTrigger",[25,1755,1051],{"class":43},[25,1757,1438],{"class":43},[25,1759,1760],{"class":640}," trigger",[25,1762,1051],{"class":43},[25,1764,1474],{"class":43},[25,1766,1742],{"class":200},[25,1768,197],{"class":43},[25,1770,44],{"class":43},[25,1772,1773],{"class":640}," start",[25,1775,1051],{"class":43},[25,1777,1474],{"class":43},[25,1779,1780],{"class":200},"top 80%",[25,1782,197],{"class":43},[25,1784,1785],{"class":43}," },\n",[25,1787,1788,1791,1793,1795,1797,1799,1801,1804,1806,1808,1810],{"class":27,"line":422},[25,1789,1790],{"class":640},"  opacity",[25,1792,1051],{"class":43},[25,1794,819],{"class":39},[25,1796,44],{"class":43},[25,1798,870],{"class":640},[25,1800,1051],{"class":43},[25,1802,1803],{"class":39}," 60",[25,1805,44],{"class":43},[25,1807,1459],{"class":640},[25,1809,1051],{"class":43},[25,1811,1812],{"class":39}," 0.8\n",[25,1814,1815,1817,1819],{"class":27,"line":428},[25,1816,1092],{"class":43},[25,1818,326],{"class":35},[25,1820,653],{"class":43},[11,1822,1823],{},"No render button. Save, switch to browser, refresh. The feedback loop is tight.",[55,1825,1827],{"id":1826},"where-to-start","Where to start",[11,1829,1830],{},"Install GSAP, open a blank HTML file, and try to recreate something you've already built in After Effects. The translation work teaches you more than any tutorial.",[103,1832,1833],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":20,"searchDepth":107,"depth":107,"links":1835},[1836,1837,1838],{"id":1327,"depth":107,"text":1328},{"id":1606,"depth":107,"text":1607},{"id":1826,"depth":107,"text":1827},"22 January,2026","CSS animations and JavaScript give motion designers a new canvas. Here's what the transition actually looks like, and why your existing skills matter more than you'd think.",[1842,1844],{"src":20,"alt":1843},"A VS Code editor showing a GSAP timeline animation script",{"src":20,"alt":1845},"A browser preview of a smooth text reveal animation built with CSS",{},"\u002Farticle\u002F0050_dummy_article",{"title":1319,"description":1840},"article\u002F0050_dummy_article",[1851,1852,1853,1340,128],"javascript","web animation","GSAP",[132,1855,1853,1856],"CSS","VS Code","lsoXFcI0ptA7ssvcDxiaGQ3jZvAT8V4nK46u5qz208g",1776374633879]