spb/svgarden Public
SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)
HTML 79.2%
Astro 10.3%
JavaScript 6%
CSS 3.7%
Shell 0.8%
1<!--2 ============================================================3 SVGarden — https://www.svgarden.dev4 Author : Simon-Pierre Boucher5 Contact: contact@spboucher.ai6 File : snippets/charts/chart-radar-pulse.html7 Desc : Radar chart whose data area breathes and vertices ping8 ============================================================9-->10<!--svgarden11title: Radar pulse12slug: chart-radar-pulse13category: charts14tags: [chart, radar, pulse, polygon]15difficulty: intermediate16techniques: [transform-box, "polar → cartesian mapping", "animation-delay", scale]17how_it_works: >18 A radar chart is pure polar-to-cartesian mapping: each axis sits at 72°19 intervals (five axes), and a data point at strength v becomes the vertex20 (cx + v·R·cos θ, cy + v·R·sin θ) — every polygon here, rings included, was21 computed with that one formula. The rings are just the same pentagon at four22 radii, so the "grid" costs four polygons instead of trigonometry at runtime.23 The living feel comes from transform-box: fill-box on the data polygon, which24 makes a tiny scale oscillation breathe around the shape's own centroid rather25 than the SVG corner, while the vertex dots reuse one ping animation with26 staggered delays so attention sweeps around the chart.27customizable:28 - { var: "--sg-color", label: "Area color", type: color, default: "#7F77DD" }29 - { var: "--sg-size", label: "Size", type: range, min: 110, max: 300, default: 170, unit: px }30 - { var: "--sg-duration", label: "Speed", type: range, min: 1, max: 6, step: 0.5, default: 2.5, unit: s }31created: 2026-08-1032-->33<div class="sg-chart-radar-pulse" style="--sg-color:#7F77DD; --sg-size:170px; --sg-duration:2.5s;">34 <svg viewBox="0 0 140 140" role="img" aria-label="Radar chart of five skills: speed 90, power 65, defense 80, stamina 55, accuracy 70 out of 100">35 <title>Skill radar chart</title>36 <g class="sg-chart-radar-pulse-rings">37 <polygon points="70,18 119.5,53.9 100.6,112.1 39.4,112.1 20.5,53.9" />38 <polygon points="70,31 107.1,58 92.9,101.6 47.1,101.6 32.9,58" />39 <polygon points="70,44 94.7,62 85.3,91 54.7,91 45.3,62" />40 <polygon points="70,57 82.4,66 77.6,80.5 62.4,80.5 57.6,66" />41 <line x1="70" y1="70" x2="70" y2="18" />42 <line x1="70" y1="70" x2="119.5" y2="53.9" />43 <line x1="70" y1="70" x2="100.6" y2="112.1" />44 <line x1="70" y1="70" x2="39.4" y2="112.1" />45 <line x1="70" y1="70" x2="20.5" y2="53.9" />46 </g>47 <polygon class="sg-chart-radar-pulse-area" points="70,23.2 102.1,59.6 94.5,103.7 53.2,93.1 35.4,58.8" />48 <g class="sg-chart-radar-pulse-dots">49 <circle cx="70" cy="23.2" r="3" />50 <circle cx="102.1" cy="59.6" r="3" />51 <circle cx="94.5" cy="103.7" r="3" />52 <circle cx="53.2" cy="93.1" r="3" />53 <circle cx="35.4" cy="58.8" r="3" />54 </g>55 <g class="sg-chart-radar-pulse-labels">56 <text x="70" y="12">spd</text>57 <text x="128" y="52">pwr</text>58 <text x="105" y="122">def</text>59 <text x="35" y="122">sta</text>60 <text x="12" y="52">acc</text>61 </g>62 </svg>63</div>64<style>65 .sg-chart-radar-pulse {66 width: var(--sg-size);67 }68 .sg-chart-radar-pulse svg {69 display: block;70 width: 100%;71 font-family: inherit;72 }73 .sg-chart-radar-pulse-rings polygon,74 .sg-chart-radar-pulse-rings line {75 fill: none;76 stroke: rgba(128, 128, 128, 0.3);77 stroke-width: 1;78 }79 .sg-chart-radar-pulse-area {80 fill: var(--sg-color);81 fill-opacity: 0.35;82 stroke: var(--sg-color);83 stroke-width: 2;84 stroke-linejoin: round;85 transform-box: fill-box;86 transform-origin: center;87 animation: sg-chart-radar-pulse-breathe var(--sg-duration) ease-in-out infinite;88 }89 .sg-chart-radar-pulse-dots circle {90 fill: var(--sg-color);91 transform-box: fill-box;92 transform-origin: center;93 animation: sg-chart-radar-pulse-ping var(--sg-duration) ease-in-out infinite;94 }95 .sg-chart-radar-pulse-dots circle:nth-of-type(2) { animation-delay: calc(var(--sg-duration) * 0.2); }96 .sg-chart-radar-pulse-dots circle:nth-of-type(3) { animation-delay: calc(var(--sg-duration) * 0.4); }97 .sg-chart-radar-pulse-dots circle:nth-of-type(4) { animation-delay: calc(var(--sg-duration) * 0.6); }98 .sg-chart-radar-pulse-dots circle:nth-of-type(5) { animation-delay: calc(var(--sg-duration) * 0.8); }99 .sg-chart-radar-pulse-labels text {100 font-size: 9px;101 fill: currentColor;102 opacity: 0.65;103 text-anchor: middle;104 }105 @keyframes sg-chart-radar-pulse-breathe {106 0%, 100% { transform: scale(1); fill-opacity: 0.3; }107 50% { transform: scale(1.045); fill-opacity: 0.5; }108 }109 @keyframes sg-chart-radar-pulse-ping {110 0%, 55%, 100% { transform: scale(1); opacity: 1; }111 70% { transform: scale(1.9); opacity: 0.4; }112 85% { transform: scale(1); opacity: 1; }113 }114</style>115