-
Notifications
You must be signed in to change notification settings - Fork 7
Feat/home page visual #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
2026-website-preview | 46ffd2d | Commit Preview URL Branch Preview URL |
Dec 31 2025, 08:10 AM |
…oto section (RWD)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a comprehensive visual redesign of the SITCON 2026 home page with interactive components and animations. The changes introduce a landing section with animated background, speaker showcase, photo gallery, and demo exhibition sections to create an engaging user experience for the conference website.
- New visual components with GSAP animations including a landing hero section with draggable CTA button, dialogue/about section, and photo wall carousel
- Interactive speaker list with auto-rotating images and demo show gallery with image transitions
- Canvas-based animated wave background with mouse interaction effects
Reviewed changes
Copilot reviewed 9 out of 24 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/index.astro | Replaced simple h1 with new component structure; removed unused main element but left orphaned styles |
| src/components/index/Visual.astro | Main container with canvas-based animated wave background using mouse interaction |
| src/components/index/Visual/Landing.astro | Hero section with decorative elements and interactive draggable registration button |
| src/components/index/Visual/Dialogue.astro | Theme description and about SITCON section with scroll-triggered fade animations |
| src/components/index/Visual/PhotoWall.astro | Photo gallery with responsive design - horizontal scroll on mobile, staggered reveal on desktop |
| src/components/index/Speaker.astro | Speaker showcase with hover interactions and auto-rotation, includes marquee on mobile |
| src/components/index/DemoShow.astro | Demo exhibition section with interactive parallax image slices and auto-rotation |
| public/img/Visual/*.svg | SVG assets for logo, icons, and decorative elements used throughout the visual components |
| package.json | Package manager version update from pnpm 10.25.0 to 10.26.2 |
| pnpm-workspace.yaml | Removed workspace configuration (onlyBuiltDependencies for esbuild and sharp) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <style> | ||
| main { | ||
| min-height: 100vh; | ||
| /* min-height: 100vh; */ | ||
| padding: 5rem 2rem 2rem; | ||
| } | ||
| h1 { | ||
| margin-top: 5rem; | ||
| /* height: 500vh; */ | ||
| } |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main and h1 style rules are no longer used since the corresponding HTML elements have been removed. These style blocks should be deleted to avoid maintaining dead code.
| { | ||
| speakers.map((person, index) => ( | ||
| <div class:list={["speaker-item", { active: index === 0 }]} data-img={person.img}> | ||
| <a>{person.name}</a> |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The anchor tag is missing an href attribute or should be a button element. Interactive elements that don't navigate should use <button> instead of <a> for proper semantics and accessibility. If these are meant to be clickable items without navigation, convert them to buttons with appropriate ARIA attributes.
| <a>{person.name}</a> | |
| <button type="button" aria-pressed={index === 0}>{person.name}</button> |
| </div> | ||
| </div> | ||
|
|
||
| <a href="#" class="cta-btn">查看議程表</a> |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CTA button link has a placeholder href="#" which will cause navigation to the top of the page. This should either point to the actual agenda URL or be updated to use javascript:void(0) or a button element if the functionality is not yet implemented.
| <a href="#" class="cta-btn">查看議程表</a> | |
| <button type="button" class="cta-btn">查看議程表</button> |
| <h3>2026 全新</h3> | ||
| <h1>Demo 展</h1> | ||
| <div class="cta-btn"> | ||
| <a href="#" class="btn">查看議程表</a> |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CTA button link has a placeholder href="#" which will cause navigation to the top of the page. This should either point to the actual demo show page or be updated appropriately if the functionality is not yet implemented.
| <a href="#" class="btn">查看議程表</a> | |
| <button type="button" class="btn">查看議程表</button> |
| img: "https://placehold.co/367x492/png?text=OsGa" | ||
| }, | ||
| { | ||
| name: "毛哥EM", | ||
| desc: "厲害崴孟讓旅途順暢無阻", | ||
| img: "https://placehold.co/367x492/png?text=EM" | ||
| }, | ||
| { | ||
| name: "凱文 Kevin", | ||
| desc: "崴孟合作 什麼難關都不怕", | ||
| img: "https://placehold.co/367x492/png?text=Kevin" | ||
| }, | ||
| { | ||
| name: "紐爾森 Nelson", | ||
| desc: "孟寶總是心暖暖 因為崴崴寶", | ||
| img: "https://placehold.co/367x492/png?text=Nelson" | ||
| }, | ||
| { | ||
| name: "yc油成", | ||
| desc: "擁有豐富的數學背景", | ||
| img: "https://placehold.co/367x492/png?text=YC" |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using placeholder image URLs from placehold.co in production code is a maintainability issue. These should be replaced with actual speaker images or a proper placeholder image hosted within the project assets before deployment.
| img: "https://placehold.co/367x492/png?text=OsGa" | |
| }, | |
| { | |
| name: "毛哥EM", | |
| desc: "厲害崴孟讓旅途順暢無阻", | |
| img: "https://placehold.co/367x492/png?text=EM" | |
| }, | |
| { | |
| name: "凱文 Kevin", | |
| desc: "崴孟合作 什麼難關都不怕", | |
| img: "https://placehold.co/367x492/png?text=Kevin" | |
| }, | |
| { | |
| name: "紐爾森 Nelson", | |
| desc: "孟寶總是心暖暖 因為崴崴寶", | |
| img: "https://placehold.co/367x492/png?text=Nelson" | |
| }, | |
| { | |
| name: "yc油成", | |
| desc: "擁有豐富的數學背景", | |
| img: "https://placehold.co/367x492/png?text=YC" | |
| img: "/assets/speakers/osga.png" | |
| }, | |
| { | |
| name: "毛哥EM", | |
| desc: "厲害崴孟讓旅途順暢無阻", | |
| img: "/assets/speakers/em.png" | |
| }, | |
| { | |
| name: "凱文 Kevin", | |
| desc: "崴孟合作 什麼難關都不怕", | |
| img: "/assets/speakers/kevin.png" | |
| }, | |
| { | |
| name: "紐爾森 Nelson", | |
| desc: "孟寶總是心暖暖 因為崴崴寶", | |
| img: "/assets/speakers/nelson.png" | |
| }, | |
| { | |
| name: "yc油成", | |
| desc: "擁有豐富的數學背景", | |
| img: "/assets/speakers/yc.png" |
| <img src="/2026/img/DemoShow/a.jpg" class="clip-shape shape-a active" data-index="0" alt="" /> | ||
| <img src="/2026/img/DemoShow/b.jpg" class="clip-shape shape-b" data-index="1" alt="" /> | ||
| <img src="/2026/img/DemoShow/c.jpg" class="clip-shape shape-c" data-index="2" alt="" /> | ||
| <img src="/2026/img/DemoShow/d.jpg" class="clip-shape shape-d" data-index="3" alt="" /> |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty alt attributes on decorative images prevent screen readers from announcing them, which is good for accessibility. However, it's a best practice to add a comment indicating these are intentionally decorative (e.g., alt="" with a comment <!-- Decorative image -->), or use role="presentation" to make the intent explicit.
| <img src="/2026/img/DemoShow/a.jpg" class="clip-shape shape-a active" data-index="0" alt="" /> | |
| <img src="/2026/img/DemoShow/b.jpg" class="clip-shape shape-b" data-index="1" alt="" /> | |
| <img src="/2026/img/DemoShow/c.jpg" class="clip-shape shape-c" data-index="2" alt="" /> | |
| <img src="/2026/img/DemoShow/d.jpg" class="clip-shape shape-d" data-index="3" alt="" /> | |
| <!-- Decorative background images --> | |
| <img src="/2026/img/DemoShow/a.jpg" class="clip-shape shape-a active" data-index="0" alt="" role="presentation" /> | |
| <img src="/2026/img/DemoShow/b.jpg" class="clip-shape shape-b" data-index="1" alt="" role="presentation" /> | |
| <img src="/2026/img/DemoShow/c.jpg" class="clip-shape shape-c" data-index="2" alt="" role="presentation" /> | |
| <img src="/2026/img/DemoShow/d.jpg" class="clip-shape shape-d" data-index="3" alt="" role="presentation" /> |
| const currentItems = container.querySelectorAll(".photo-item"); | ||
| currentItems.forEach((item, index) => { | ||
| if (index >= items.length) { | ||
| item.remove(); | ||
| } else { | ||
| gsap.set(item, { clearProps: "all" }); | ||
| } | ||
| }); |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition if (index >= items.length) will always evaluate to true for all cloned items since they're appended after the original items. However, the else branch attempts to clear props on original items, which could cause visual glitches. Consider storing a reference to only the cloned nodes or using a more explicit cleanup strategy.
| const config = { | ||
| lineCount: 8, | ||
| waveAmplitude: 40, | ||
| waveLength: 0.002, | ||
| speed: 0.003, | ||
| mouseRadius: 200, |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magic numbers are used throughout for animation configuration (lineCount: 8, waveAmplitude: 40, waveLength: 0.002, speed: 0.003, etc.). Consider adding comments explaining what these values represent or extracting them to named constants with descriptive names to improve code maintainability.
| const config = { | |
| lineCount: 8, | |
| waveAmplitude: 40, | |
| waveLength: 0.002, | |
| speed: 0.003, | |
| mouseRadius: 200, | |
| const config = { | |
| // Number of animated wave lines rendered across the canvas | |
| lineCount: 8, | |
| // Maximum vertical displacement (in pixels) of each wave from its base path | |
| waveAmplitude: 40, | |
| // Horizontal wave frequency (smaller values = longer, smoother waves) | |
| waveLength: 0.002, | |
| // Base animation speed factor applied per frame | |
| speed: 0.003, | |
| // Radius (in pixels) around the pointer within which lines are affected | |
| mouseRadius: 200, | |
| // Strength of the mouse repulsion effect applied to nearby points |
| document.addEventListener("DOMContentLoaded", () => { | ||
| const allImages = document.querySelectorAll(".clip-shape"); | ||
| if (allImages.length === 0) return; | ||
|
|
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable intervalId is initialized as null but TypeScript will infer the type as null rather than number | null. This should be explicitly typed as let intervalId: NodeJS.Timeout | null = null; or let intervalId: number | null = null; for better type safety with the setInterval return value.
| /** @type {number | null} */ |
| <!-- 左下角報名按鈕預留 --> | ||
| <div class="cta-wrapper"> | ||
| <div class="cta-container" id="cta-container"> | ||
| <a href="https://tickets.sitcon.org/zh-Hant/sitcon2026" target="_blank"> |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The target="_blank" link to https://tickets.sitcon.org/zh-Hant/sitcon2026 is missing rel="noopener" (and ideally noreferrer), which can enable reverse tabnabbing: the opened page can use window.opener to navigate the original site to a phishing or malicious URL. Because this points to an external domain, a compromise of that site would directly allow attacks against users of your page. Add a rel attribute to this anchor so the new tab cannot control the opener window.
| <a href="https://tickets.sitcon.org/zh-Hant/sitcon2026" target="_blank"> | |
| <a href="https://tickets.sitcon.org/zh-Hant/sitcon2026" target="_blank" rel="noopener noreferrer"> |
elvisdragonmao
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
先這樣吧,底下應該是 OsGa 會再開一個 PR 對吧。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .dialogue-section { | ||
| position: relative; | ||
| width: 100%; | ||
| max-width: 1000px; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
這裡可以寬點,用 max-width 變數
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
請參考 Figma 給的參考的 Animate on Scroll 的動畫
| ]; | ||
| --- | ||
|
|
||
| <section class="speaker-section"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
記得背景的動畫,就一些線性節點上下移動做出波浪效果即可。
| </div> | ||
|
|
||
| <div class="content-wrapper"> | ||
| <div class="speaker-list"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
記得圖片要跟著滑鼠上下左右偏移。畫面中間為滑鼠中心。圖片預設的中心現在這裡 ok。
| { | ||
| speakers.map((person, index) => ( | ||
| <div class:list={["speaker-item", { active: index === 0 }]} data-img={person.img}> | ||
| <a>{person.name}</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hover 不需要在文字上,橫向整排都可以,直接 display block。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hover 記得只放大裡面的圖片,外面的容器不會跟著縮放。不然會像現在這樣破圖。
| width: 35%; | ||
| max-width: 450px; | ||
| } | ||
| .main-title { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
你這也太邪門了吧(
svg 大小切好啦,而且這裡應該要用字體,這個字體 Google Font 有。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
然後 hero 文字字體建議用 clamp 處理,不然大螢幕會很小。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.


[Desktop]


[Mobile]


