网站SVG/图片动画信息图开发需求:重复图标实现公益人数动态展示
Hey there! Let’s tackle that animated infographic for your "86 people dedicating time to help underprivileged kids" stat. I’ve built similar population-style silhouette animations before, so here’s a practical, embeddable solution using SVG (way more flexible than raster images) with CSS and vanilla JS.
We’ll create a reusable SVG person silhouette, then dynamically generate 86 instances of it with a staggered fade-in animation. To tie it all together, we’ll add a counter that ticks up to 86 in sync with the silhouettes appearing. This mimics that "growing impact" feel you see in population infographics.
First, here’s the complete code you can drop into your website. I’ll break down the key parts afterward:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>86 People Supporting Kids</title> <style> .impact-container { max-width: 800px; margin: 2rem auto; padding: 0 1rem; text-align: center; font-family: 'Arial', sans-serif; } .silhouette-grid { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 2rem 0; min-height: 120px; } .person-silhouette { width: 30px; height: 45px; opacity: 0; transform: translateY(10px); animation: fadeInUp 0.5s ease forwards; /* SVG fill color - customize this! */ fill: #2c3e50; } @keyframes fadeInUp { to { opacity: 1; transform: translateY(0); } } .impact-counter { font-size: 2.5rem; font-weight: bold; color: #27ae60; margin-bottom: 0.5rem; } .impact-label { font-size: 1.1rem; color: #34495e; } </style> </head> <body> <div class="impact-container"> <div class="impact-counter" id="counter">0</div> <div class="impact-label">People dedicating time to help underprivileged children</div> <div class="silhouette-grid" id="silhouetteGrid"></div> </div> <script> const totalPeople = 86; const silhouetteGrid = document.getElementById('silhouetteGrid'); const counterEl = document.getElementById('counter'); // SVG person silhouette (customize this to match your brand!) const personSVG = ` <svg class="person-silhouette" viewBox="0 0 20 30" xmlns="http://www.w3.org/2000/svg"> <circle cx="10" cy="5" r="3"/> <rect x="8" y="8" width="4" height="8"/> <line x1="8" y1="12" x2="5" y2="18"/> <line x1="12" y1="12" x2="15" y2="18"/> <line x1="8" y1="16" x2="5" y2="24"/> <line x1="12" y1="16" x2="15" y2="24"/> </svg> `; // Generate silhouettes with staggered animation function generateSilhouettes() { let currentCount = 0; const interval = setInterval(() => { if (currentCount >= totalPeople) { clearInterval(interval); return; } // Add new silhouette silhouetteGrid.innerHTML += personSVG; // Update counter currentCount++; counterEl.textContent = currentCount; // Set animation delay for the new silhouette (stagger effect) const lastSilhouette = silhouetteGrid.lastElementChild; lastSilhouette.style.animationDelay = `${currentCount * 0.03}s`; }, 30); // Adjust speed here (lower = faster) } // Start animation when the element is in view (optional but user-friendly) const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { generateSilhouettes(); observer.unobserve(entry.target); } }); }); observer.observe(document.querySelector('.impact-container')); </script> </body> </html>
Reusable SVG Silhouette:
- The SVG is lightweight, scalable, and easy to customize (change
fillcolor, adjust the shape to match your theme). No external image files needed! - I kept it simple, but you can swap in a more detailed silhouette (like a child-friendly icon) by editing the SVG code.
- The SVG is lightweight, scalable, and easy to customize (change
Staggered Animation:
- Each silhouette gets a unique
animationDelaybased on its position, so they appear one after another instead of all at once. Adjust the0.03svalue to make the animation faster or slower. - The
fadeInUpkeyframe adds a subtle upward slide with fade-in, which feels more natural than a plain pop-in.
- Each silhouette gets a unique
Counter Sync:
- The JS counter increments at the same rate as silhouettes are added, so the number matches the visual count perfectly. The interval time (
30ms) controls how fast everything progresses.
- The JS counter increments at the same rate as silhouettes are added, so the number matches the visual count perfectly. The interval time (
Intersection Observer:
- The animation only starts when the container is visible on the screen, which saves resources and makes the experience feel more intentional for users scrolling down.
- Change Silhouette Style: Swap the SVG code for a gender-neutral icon, a kid silhouette, or even a hand icon to match your "time dedication" theme.
- Adjust Animation Speed: Modify the
intervalvalue (lower = faster) or theanimationDelaymultiplier to fit your desired pace. - Grouped Animation: Instead of one-by-one, add 5 silhouettes at a time for a chunkier growth effect.
- Color Variations: Randomize the
fillcolor of silhouettes to add visual interest (use JS to set a random color for each one). - Add Hover Effects: Add a CSS
hoverstate to silhouettes (e.g.,fill: #e74c3c; transform: scale(1.1);) to make it interactive.
This code is fully embeddable—just copy the HTML/CSS/JS into your website’s template, and tweak the styles to match your brand. It’s responsive, works on all modern browsers, and doesn’t require any external libraries.
内容的提问来源于stack exchange,提问作者Marcelo Araujo marujobhz

