A Rendering the Icon
Goal: Get a Lucide bell icon rendering in CodePen, make it bigger, and change its color.
Context you have: You know you want to use Lucide icons in a CodePen project. You’ve never used Lucide before. You need the icon to show up, be resizable, and be a custom color.
Step 1: Get the bell rendering
Prompt Strategy: State your environment
AI models give better answers when you tell them where you’re working. “How do I use Lucide?” gets a different answer than “How do I use Lucide in CodePen?” — the first might give you npm install instructions you can’t use.
Try this prompt (copy it, or write your own version):
I'm working in CodePen (no npm or imports). I want to render a Lucide bell icon. What CDN do I need, what HTML markup, and what JavaScript call?
After you get a response:
- Add the CDN to Settings → JS → External Scripts
- Add the HTML to your HTML panel
- Add the JS to your JS panel
- Right-click the bell and choose “Inspect.” What element is actually in the DOM? The model probably told you, but verify it yourself.
Step 2: Make it bigger and change its color
Now you need two more things. You could ask two separate questions, or combine them. Try combining:
The bell rendered but it's tiny (24px). I want it around 120px and a different color. It's a Lucide SVG icon. What CSS do I need?
Prompt Strategy: Tell the model what you already know
Notice the prompt says “It’s a Lucide SVG icon.” This gives the model context about the element type, which matters because SVG coloring works differently than regular HTML elements. Without this, you might get advice for changing text color.
Evaluate the response:
- Did the model suggest
strokeorcolorfor the color change? Try both — which works, and does the model explain why? - Did the CSS selector target the right element? (Remember what you saw in the inspector.)
Reflection:
Paste the prompt you actually used (whether you modified the suggested one or wrote your own). Did the model’s first response work, or did you need a follow-up? What information in your prompt helped the model give a useful answer?
Auto-saved ✓
B GSAP Ring Animation
Goal: Use GSAP to animate the bell so it rings — swinging back and forth from the top like a real bell.
Context you have: You have a rendered SVG bell icon in CodePen. You want to add GSAP and animate it. You’ve never used GSAP before.
Step 1: Get GSAP set up and the bell ringing
Prompt Strategy: Describe the behavior, not just the tool
Instead of “How do I use GSAP timeline?”, describe what you want to see happen. The model can suggest the right GSAP tools for the job rather than you guessing which API to ask about.
Try this prompt:
I have a Lucide bell SVG icon in CodePen (no npm). I want to animate it with GSAP so it swings back and forth like a ringing bell. It should swing from the top, not the center. What CDN do I need and what JS code?
Before you paste the code into CodePen, read the response and look for:
- Did the model mention
transformOrigin? That’s the property that controls where rotation pivots from. - Does the rotation decay? (A real bell swings less and less, not the same amount forever.)
- Does it use a
timeline? Timelines let you chain multiple animations in sequence.
Now paste the code in and test it. Does the bell ring from the top?
Step 2: If it doesn’t look right
Prompt Strategy: Describe the gap between expected and actual
When debugging with a model, the most effective pattern is: “I expected [X]. Instead I’m seeing [Y]. Here’s my code.” This gives the model everything it needs to diagnose the issue.
If the bell is spinning from the center, rotating weirdly, or not animating at all, try a follow-up like:
The bell is rotating from the center instead of swinging from the top. I'm using transformOrigin but it doesn't seem to work on the SVG. Here's my code: [paste your code]
Reflection:
What did the model get right on the first try? What did you need to fix or follow up on? If you had to debug, paste the follow-up prompt that worked.
Auto-saved ✓
C Two Bells, Stacked
Goal: Add a second bell, give each a different color, and stack them on top of each other.
Context you have: You have one working bell. You need to add a second one and control them independently. You also need them visually overlapping.
Step 1: Ask the model to help restructure
Prompt Strategy: Share your current code
When you want to modify existing work, always paste your current code into the prompt. Without it, the model will write something from scratch that might conflict with what you already have.
Try this prompt:
I have one Lucide bell icon in a .bell-container div. I need to:
1. Add a second bell icon
2. Give each its own class (.bell-1 and .bell-2) so I can target them separately
3. Make them different colors
4. Stack them on top of each other with CSS
Here's my current HTML:
[paste your HTML here]
And my current CSS:
[paste your CSS here]
What changes do I need?
Evaluate the response:
- Did the model restructure your HTML or just add to it?
- Does it still only call
lucide.createIcons()once? (Calling it twice is a common model mistake.) - For the stacking — does it use
position: absolute? That’s the standard approach.
Common model mistake
Some models will put classes directly on the <i> tag. That works, but check: after Lucide runs, does the rendered <svg> keep the class? Inspect the DOM to verify. If not, wrapping each icon in a classed <div> is more reliable.
D Click to Ring
Goal: Make Bell 1 ring only when clicked, not on page load.
Context you have: Your ring animation plays automatically. You want it to wait for a click instead.
Step 1: Ask the model to change the trigger
Prompt Strategy: Ask “how do I change X” not “how do I do X”
When modifying existing behavior, framing it as a change gets you a more targeted response. “How do I make a GSAP timeline play on click?” might get a generic answer. “My timeline auto-plays. How do I make it only play when the user clicks?” tells the model exactly what to change.
Try this prompt:
My GSAP ring animation plays automatically when the page loads. I want it to only play when the user clicks on .bell-1. If they click while it's already ringing, it should restart from the beginning. Here's my current JS:
[paste your JS here]
Look for these in the response:
- Does it add
paused: trueto the timeline config? - Does it use
.restart()or.play()? Ask the model what the difference is if it doesn’t explain. - Does it add an event listener on the right element?
Test it
Click the first bell. It should ring. Click again mid-ring. Does it restart cleanly?
Reflection:
The prompt specifically said “if they click while it’s already ringing, it should restart.” Did the model pick up on that detail? How did specifying the edge case in the prompt affect the response?
Auto-saved ✓
Checkpoint: Prompting Foundations
Parts A–D got you working with an AI model to build interactive animations. Look at the prompting strategies you’ve practiced so far:
- State your environment — “I’m in CodePen, no npm”
- Describe behavior, not just tools — “swings like a real bell”
- Share your current code — always paste what you have
- Describe the gap — “I expected X, got Y”
- Specify edge cases — “if they click mid-ring…”
Parts E–G introduce two GSAP plugins you’ve never used. This is where the prompting gets more interesting — you’re asking the model about tools that are genuinely new to you.
E DrawSVGPlugin — Stroke Animation
Goal: Make Bell 2 look like it’s being drawn by hand, with the strokes animating in one at a time.
Context you have: You know GSAP has a plugin called DrawSVGPlugin that animates SVG strokes. It’s a paid plugin, but free trial versions exist for CodePen. You’ve never used it.
Step 1: Ask the model to set it up
Prompt Strategy: Name the constraints
DrawSVGPlugin is paid, but has a CodePen trial. If you don’t mention this, the model might tell you to install it via npm (which you can’t do) or give you a generic CDN that doesn’t work. Naming the constraint up front saves a round-trip.
Try this prompt:
I want to use GSAP's DrawSVGPlugin to animate a Lucide bell icon so it looks hand-drawn. I'm in CodePen, so I need the free trial CDN URL that GSAP provides for CodePen. I also need to know:
1. How to register the plugin
2. How to start with the strokes hidden and animate them to fully drawn
3. How to stagger the animation so each path draws one at a time
My bell is inside a div with class .bell-2
Evaluate the response:
- Does the CDN URL look like it’s from
assets.codepen.io? That’s the CodePen trial host. - Does it use
gsap.registerPlugin(DrawSVGPlugin)? - Does it target both
pathandlineelements inside the SVG? Lucide bells have both. - Does the code use
drawSVG: "0%"anddrawSVG: "100%"?
Watch for this
If you get a DrawSVGPlugin is not defined error, the CDN didn’t load. Check that the URL is correct and that it’s listed after GSAP core in your external scripts. Ask your model: “I’m getting DrawSVGPlugin is not defined. The CDN URL is [URL]. What could be wrong?”
Reflection:
This was the first time you asked the model about a tool you’d never used. How did you decide whether the model’s response was correct? What did you look for to evaluate the output?
Auto-saved ✓
F ScrollTrigger — Scroll-Driven Animation
Goal: Tie the draw animation to scroll position. Then add an “undraw” phase so the bell draws in, then undraws as you keep scrolling.
Context you have: You have a working draw animation from Part E. You want scroll position to control it instead of it playing automatically. You need the page to be scrollable.
Step 1: Ask the model to add scroll control
Prompt Strategy: Build on what you have
You’re not starting from scratch — you’re modifying working code. Always tell the model what already works so it modifies rather than replaces. Include the code.
Try this prompt:
I have a working DrawSVG animation that plays automatically. I want to change it so:
1. It's driven by scroll position (scrubbed, so scrolling forward draws it, scrolling back undraws it)
2. I need the GSAP ScrollTrigger plugin set up in CodePen (CDN)
3. The page needs to be scrollable — right now it's not tall enough
Here's my current code:
[paste your HTML, CSS, and JS]
What do I need to change?
Evaluate the response:
- Does it add spacer divs (or height) to make the page scrollable?
- Does it use
scrub: truein the ScrollTrigger config? - Does it register ScrollTrigger alongside DrawSVGPlugin?
- Does it suggest
markers: truefor debugging? If not, add it yourself — you’ll want the visual feedback.
If scrolling does nothing
The most common problem is the page isn’t tall enough to scroll, so ScrollTrigger has nothing to work with. Ask the model: “My ScrollTrigger animation isn’t working. I have markers: true but I don’t see any markers. Could the page not be scrollable?”
Step 2: Add the undraw phase
Once the bell is fully drawn, you want it to undraw (strokes disappear) if the user keeps scrolling. This is a good test of follow-up prompting.
Try this prompt:
The scroll-driven draw works. Now I want a second phase: once the bell is fully drawn at 100%, if the user keeps scrolling, it should undraw back to 0%. Both phases should be scrubbed. Here's my current code:
[paste your code]
Prompt Strategy: Describe the full sequence
When you want multi-step behavior, describe the complete sequence in one prompt: “first this, then this.” Splitting it into multiple prompts often results in code that works for step 1 but needs restructuring for step 2.
Reflection:
How did the model handle the idea of “two phases in one scrubbed timeline”? Did it add a second tween to the existing timeline, or try a different approach? If you had asked about both phases in one prompt (instead of splitting it), do you think you’d have gotten a better response?
Auto-saved ✓
G The Combo — Ring at Full Draw
Goal: When the bell reaches 100% drawn (the midpoint of your scroll), trigger the ring animation. The ring should play at normal speed, not be scrubbed.
Context you have: You have a scrubbed draw/undraw timeline. You want a separate ring animation that fires freely at a specific moment in the scrubbed timeline. This is a genuinely tricky problem — two different animation paradigms need to work together.
Step 1: Frame the problem precisely
Prompt Strategy: Name the tension
This is the hardest part of the tutorial because there’s a conflict: the scroll timeline is scrubbed (tied to scroll), but the ring should play freely (tied to time). When you name this tension in your prompt, the model understands the actual problem instead of giving you a generic answer.
Try this prompt:
I have two animation needs that conflict:
1. A scrubbed ScrollTrigger timeline that draws and undraws a bell SVG based on scroll position
2. A ring animation that should play freely at normal speed (NOT scrubbed) when the draw reaches 100%
The ring can't be part of the scrubbed timeline because scrubbing a fast ring animation would look weird. How do I fire a separate, non-scrubbed animation at a specific point in a scrubbed timeline?
Here's my current code:
[paste your code]
The model should suggest one of these approaches:
- Using GSAP’s
onCompletecallback on the draw-in tween - Using ScrollTrigger’s
onEnter/onLeavecallbacks - A custom scroll position check
The cleanest approach is onComplete on the first tween. If the model suggests something else, try asking: “Would an onComplete callback on the draw tween work here?”
Syntax traps
The onComplete callback goes inside the tween’s config object, which means every property needs a comma after it. If you get Unexpected identifier, you’re probably missing a comma. Ask the model: “I’m getting Unexpected identifier on the onComplete line. Here’s my code:”
Test it
- Scroll down slowly through the trigger zone
- Watch the bell draw itself in
- When it reaches 100% drawn, it should ring freely at normal speed
- Continue scrolling — the bell undraws
- Scroll back up — everything reverses
Reflection:
This was the most complex prompt in the tutorial. Compare it to your Part A prompt. How did the specificity change? What did naming the conflict between “scrubbed” and “free-playing” do for the quality of the response?
Auto-saved ✓
You Built It!
Two animated bell icons — one click-triggered, one scroll-driven with a callback combo. And you built it by driving the model, not by following a recipe.
Prompting strategies you practiced:
- State your environment — “I’m in CodePen, no npm”
- Describe behavior, not tools — “swings like a bell from the top”
- Share your current code — paste what you have, every time
- Tell the model what you know — “It’s a Lucide SVG icon”
- Describe expected vs. actual — “I expected X, got Y”
- Specify edge cases — “if they click mid-ring, restart”
- Name constraints — “paid plugin, but CodePen trial exists”
- Build on what works — modify, don’t replace
- Describe the full sequence — “first draw, then undraw”
- Name the tension — “scrubbed vs. free-playing”
These strategies transfer to any project:
The prompting patterns you used here work the same whether you’re building a scrollytelling site, debugging a layout, or asking a model to help you learn a framework you’ve never seen before. The skill isn’t knowing GSAP syntax. The skill is knowing how to describe what you want, what you have, and what’s going wrong.
Final Reflection:
Look back at your prompts from Part A compared to Part G. How did they change? What would you do differently if you started this tutorial over?
Auto-saved ✓
Final Step: Document Your Thinking
- Click the “Copy All My Responses” button below
- Open your CodePen’s JavaScript panel
- Paste your responses at the top as a comment block:
/*
MY REFLECTIONS
==============
[Paste your copied responses here]
*/
Why? Your reflections show your learning process. The prompts you wrote, the problems you hit, and how you resolved them are more valuable than the final code.