Skip to content

Conversation

@HarshMN2345
Copy link
Member

@HarshMN2345 HarshMN2345 commented Dec 9, 2025

What does this PR do?

image

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)

Related PRs and Issues

(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)

Have you read the Contributing Guidelines on issues?

(Write your answer here.)

Summary by CodeRabbit

  • New Features

    • Added an interactive teaser banner to the main layout with animated halftone/particle visuals and CTA.
    • Introduced a reusable canvas component powering GPU-rendered shader effects (interactive trails, mouse-driven animation).
  • Chores

    • Added 3D rendering runtime and type packages to support the new visuals.
    • Adjusted build tooling dependency version.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • static/images/logos/Imagine.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request adds Threlte and Three.js packages and a GLSL module declaration, updates the Main layout to render a new TeaserBanner, and introduces three new Svelte components under src/routes/(marketing)/(components)/teaser: a Canvas wrapper (canvas.svelte), an Imagination component with a custom GLSL fragment shader, mouse-trail logic, and a capped FPS loop (imagination.svelte), and a TeaserBanner component composing the canvas and visual with a public props interface (teaser-banner.svelte).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • src/routes/(marketing)/(components)/teaser/imagination.svelte — high complexity: GLSL shader edits, uniform and trail management, event handling, and custom render loop
  • src/routes/(marketing)/(components)/teaser/teaser-banner.svelte — component API, layout, styling and composition with Canvas/Imagination
  • src/routes/(marketing)/(components)/teaser/canvas.svelte — runtime integration with @threlte/core and prop typing
  • src/global.d.ts — GLSL module declaration to verify typings and build behavior
  • package.json — dependency additions (three, @threlte/*, @types/three) and vite version change; verify compatibility and build implications

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: animated banner for imagine' directly summarizes the main change—adding an animated banner component for the imagine section, which is confirmed by all the file changes implementing TeaserBanner and related canvas/shader components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (6)
src/lib/layouts/Main.svelte (1)

25-26: Remove unused HackathonBanner import.

The HackathonBanner import on line 25 is no longer used since it was replaced by TeaserBanner.

-    import HackathonBanner from '$routes/(marketing)/(components)/(hackathon)/hackathon-banner.svelte';
     import TeaserBanner from '$routes/(marketing)/(components)/teaser/teaser-banner.svelte';
src/routes/(marketing)/(components)/teaser/teaser-banner.svelte (2)

72-80: Avoid fixed pixel dimensions in inline styles.

The container uses hardcoded pixel values (width: 143.384px; height: 35.785px) which may not scale well across viewports. Consider using responsive units or Tailwind classes.

-<div 
-    style="display: flex; width: 143.384px; height: 35.785px; padding: 1.348px 0.634px 1.348px 0; justify-content: center; align-items: flex-end; gap: 10.75px; flex-shrink: 0;"
->
+<div class="flex shrink-0 items-end justify-center">
     <img 
         src="/images/logos/Imagine.png" 
         alt="Imagine"
-        class="h-auto w-auto"
+        class="h-9 w-auto"
     />
 </div>

50-54: Consider adding accessibility attributes to the external link.

The banner link opens an external site. Adding aria-label would improve screen reader experience.

 <a
     href="https://imagine.dev"
     target="_blank"
     rel="noopener noreferrer"
+    aria-label="Learn more about Imagine - opens in new tab"
     class="group relative mx-auto flex w-full items-center py-4 md:h-[76px] bg-black cursor-pointer"
 >
src/routes/(marketing)/(components)/teaser/imagination.svelte (3)

290-290: Avoid as any type cast.

Casting material to any bypasses TypeScript's type checking. Consider using a more specific type or addressing the underlying type mismatch.

-<T.Mesh scale={[$viewport.width, $viewport.height, 1]} material={material as any}>
+<T.Mesh scale={[$viewport.width, $viewport.height, 1]} material={material}>

If there's a type incompatibility with Threlte, you may need to type the material state more specifically or use a type assertion to Material.


15-15: Unused interactivity() call.

The interactivity() function is called but its return value is not used, and there are no interactive Threlte elements (like on:click handlers on meshes) in this component. If interactivity isn't needed, this can be removed.


26-31: Consider consolidating mouse state variables.

Six separate state variables for mouse tracking could be consolidated into objects for cleaner code.

let mouse = $state({ x: 0, y: 0 });
let targetMouse = $state({ x: 0, y: 0 });
let prevMouse = $state({ x: 0, y: 0 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffd2d9a and b862f15.

⛔ Files ignored due to path filters (3)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/routes/(marketing)/(components)/teaser/shaders/noise.glsl is excluded by !**/*.glsl
  • static/images/logos/Imagine.png is excluded by !**/*.png
📒 Files selected for processing (6)
  • package.json (3 hunks)
  • src/global.d.ts (1 hunks)
  • src/lib/layouts/Main.svelte (2 hunks)
  • src/routes/(marketing)/(components)/teaser/canvas.svelte (1 hunks)
  • src/routes/(marketing)/(components)/teaser/imagination.svelte (1 hunks)
  • src/routes/(marketing)/(components)/teaser/teaser-banner.svelte (1 hunks)
🔇 Additional comments (4)
package.json (1)

112-112: Verify the Vite version downgrade.

The Vite version appears to have been downgraded from ^7.2.10 to ^7.2.7. Was this intentional? If so, please document the reason (e.g., compatibility issue with Threlte).

src/global.d.ts (1)

3-6: LGTM!

The module declaration correctly types GLSL shader imports using Vite's ?raw query parameter, enabling TypeScript support for the shader files used in the imagination component.

src/routes/(marketing)/(components)/teaser/canvas.svelte (1)

13-20: LGTM!

The canvas wrapper is well-structured with appropriate performance optimizations (contain, transform: translate3d, backface-visibility). The fixed dpr={1} is a reasonable tradeoff for banner performance over sharpness on high-DPI displays.

src/routes/(marketing)/(components)/teaser/imagination.svelte (1)

283-285: Verify the lerp smoothing factor calculation.

The formula 1 - Math.pow(0.0003, actualDelta) produces values very close to 1 for typical frame deltas (~0.033s at 30fps), resulting in near-instant snapping rather than smooth interpolation. Was this intentional, or should the base/exponent be adjusted for smoother mouse following?

A typical frame-rate-independent lerp uses something like:

const lerpFactor = 1 - Math.pow(smoothing, actualDelta * 60); // where smoothing is 0.8-0.95

"svgtofont": "^4.2.3",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.17",
"three": "^0.176.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

three should be in dependencies, not devDependencies.

The three library is a runtime dependency used in the browser for the 3D canvas rendering. It should be moved to the dependencies section to ensure it's included in production builds.

     "dependencies": {
         "@sentry/sveltekit": "^10.28.0",
         "h3": "^1.15.4",
-        "sharp": "^0.34.5"
+        "sharp": "^0.34.5",
+        "three": "^0.176.0"
     },

And remove it from devDependencies.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In package.json around line 107, the "three" package is currently listed under
devDependencies but is a runtime/browser dependency; move the "three":
"^0.176.0" entry into the top-level "dependencies" object and remove it from
"devDependencies", then run your package manager (npm/yarn/pnpm) to update
node_modules and the lockfile so production builds include the library.

Comment on lines 168 to 173
<TeaserBanner
showLabel={true}
leftText="Introducing"
logoText="Imagine"
rightText="Build something real"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

showLabel={true} appears to be a debug setting.

The showLabel prop renders a "Teaser Banner" label and code icon positioned above the banner (visible at lines 28-46 in teaser-banner.svelte). This looks like development/debug UI that should likely be disabled for production.

 <TeaserBanner 
-    showLabel={true}
+    showLabel={false}
     leftText="Introducing"
     logoText="Imagine"
     rightText="Build something real"
 />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<TeaserBanner
showLabel={true}
leftText="Introducing"
logoText="Imagine"
rightText="Build something real"
/>
<TeaserBanner
showLabel={false}
leftText="Introducing"
logoText="Imagine"
rightText="Build something real"
/>
🤖 Prompt for AI Agents
In src/lib/layouts/Main.svelte around lines 168 to 173, the TeaserBanner is
passing showLabel={true} which enables a development/debug label and icon;
change this to showLabel={false} (or remove the prop if the default is false) so
the debug UI is disabled in production, then verify the teaser-banner no longer
renders the label above the banner.

});
</script>

<T.OrthographicCamera position={[0, 0, 10]} fov={10} near={0.1} far={1000} makeDefault />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

fov is not a valid prop for OrthographicCamera.

OrthographicCamera uses left, right, top, bottom (or relies on viewport sizing), not fov which is specific to PerspectiveCamera. This prop will be silently ignored.

-<T.OrthographicCamera position={[0, 0, 10]} fov={10} near={0.1} far={1000} makeDefault />
+<T.OrthographicCamera position={[0, 0, 10]} near={0.1} far={1000} makeDefault />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<T.OrthographicCamera position={[0, 0, 10]} fov={10} near={0.1} far={1000} makeDefault />
<T.OrthographicCamera position={[0, 0, 10]} near={0.1} far={1000} makeDefault />
🤖 Prompt for AI Agents
In src/routes/(marketing)/(components)/teaser/imagination.svelte around line
289, the OrthographicCamera is being passed a non‑existent fov prop (fov is for
PerspectiveCamera); remove the fov prop and either supply appropriate
orthographic parameters (left, right, top, bottom, near, far) or replace
OrthographicCamera with PerspectiveCamera if a field‑of‑view is required; update
the JSX/props accordingly so the camera receives only valid props and the
intended projection is achieved.

Comment on lines 86 to 94
<svg
class="h-5 w-5 transition group-hover:-translate-x-0.5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Arrow hover animation moves in wrong direction.

The arrow points right (→) but the hover effect translates it left (-translate-x-0.5). For a "go forward" affordance, the arrow should move right on hover.

 <svg
-    class="h-5 w-5 transition group-hover:-translate-x-0.5"
+    class="h-5 w-5 transition group-hover:translate-x-0.5"
     fill="none"
     viewBox="0 0 24 24"
     stroke="currentColor"
     stroke-width="2"
 >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<svg
class="h-5 w-5 transition group-hover:-translate-x-0.5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
<svg
class="h-5 w-5 transition group-hover:translate-x-0.5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
🤖 Prompt for AI Agents
In src/routes/(marketing)/(components)/teaser/teaser-banner.svelte around lines
86 to 94, the SVG arrow uses group-hover:-translate-x-0.5 which moves it left on
hover; change the hover utility to move right (e.g., replace
group-hover:-translate-x-0.5 with group-hover:translate-x-0.5) so the arrow
animates in the forward/right direction on hover, keeping the other classes (h-5
w-5 transition) intact.

@adityaoberai adityaoberai merged commit 24d3950 into main Dec 16, 2025
6 checks passed
@adityaoberai adityaoberai deleted the feat-PRO-2150-Animated-Imagine-Banner branch December 16, 2025 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants