Created
May 19, 2026 19:56
-
-
Save vkryukov/029df86d03bfe8f87df1e4d9ed2f6b02 to your computer and use it in GitHub Desktop.
Animated SVG frog rowing through a jungle river
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>Rowing Frog on a Jungle River</title> | |
| <style> | |
| :root { | |
| color-scheme: dark; | |
| --sky-top: #80cfd8; | |
| --sky-bottom: #f1d38b; | |
| --river: #176f83; | |
| --river-dark: #0d5369; | |
| --leaf: #1b8b4d; | |
| --leaf-dark: #07593f; | |
| --leaf-light: #6fbf4a; | |
| --frog: #5fbd42; | |
| --frog-dark: #2f8739; | |
| --frog-light: #a5df6a; | |
| --wood: #8a4f2a; | |
| --wood-dark: #4b2a1b; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| } | |
| html, | |
| body { | |
| margin: 0; | |
| min-height: 100%; | |
| overflow: hidden; | |
| background: #082b2e; | |
| font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; | |
| } | |
| main { | |
| width: 100vw; | |
| height: 100vh; | |
| display: grid; | |
| place-items: center; | |
| background: | |
| radial-gradient(circle at 50% 38%, rgba(255, 225, 130, 0.36), transparent 23rem), | |
| linear-gradient(180deg, #063534 0%, #061d20 100%); | |
| } | |
| svg { | |
| width: min(100vw, 150vh); | |
| height: auto; | |
| max-height: 100vh; | |
| display: block; | |
| } | |
| .mist { | |
| animation: mist-drift 18s linear infinite; | |
| } | |
| .mist, | |
| .back-leaves, | |
| .front-leaves, | |
| .current-a, | |
| .current-b, | |
| .boat-rig, | |
| .boat-shadow, | |
| .frog-body, | |
| .frog-head, | |
| .left-oar, | |
| .right-oar, | |
| .left-arm, | |
| .right-arm, | |
| .left-blade-splash, | |
| .right-blade-splash, | |
| .blink, | |
| .breath, | |
| .river-glint { | |
| transform-box: view-box; | |
| will-change: transform, opacity; | |
| } | |
| .back-leaves { | |
| animation: jungle-sway 7s ease-in-out infinite alternate; | |
| transform-origin: 50% 65%; | |
| } | |
| .front-leaves { | |
| animation: jungle-sway 5.4s ease-in-out infinite alternate-reverse; | |
| transform-origin: 50% 78%; | |
| } | |
| .current-a { | |
| animation: river-flow-a 4.8s linear infinite; | |
| } | |
| .current-b { | |
| animation: river-flow-b 6.2s linear infinite; | |
| } | |
| .boat-rig { | |
| animation: boat-bob 2.8s ease-in-out infinite; | |
| transform-origin: 600px 520px; | |
| } | |
| .boat-shadow { | |
| animation: shadow-breathe 2.8s ease-in-out infinite; | |
| transform-origin: 600px 575px; | |
| } | |
| .frog-body { | |
| animation: frog-lean 1.45s ease-in-out infinite; | |
| transform-origin: 600px 430px; | |
| } | |
| .frog-head { | |
| animation: frog-head 1.45s ease-in-out infinite; | |
| transform-origin: 600px 386px; | |
| } | |
| .left-oar { | |
| animation: left-oar-stroke 1.45s ease-in-out infinite; | |
| transform-origin: 520px 500px; | |
| } | |
| .right-oar { | |
| animation: right-oar-stroke 1.45s ease-in-out infinite; | |
| transform-origin: 680px 500px; | |
| } | |
| .left-arm { | |
| animation: left-arm-stroke 1.45s ease-in-out infinite; | |
| transform-origin: 565px 455px; | |
| } | |
| .right-arm { | |
| animation: right-arm-stroke 1.45s ease-in-out infinite; | |
| transform-origin: 635px 455px; | |
| } | |
| .left-blade-splash { | |
| animation: left-splash 1.45s ease-in-out infinite; | |
| transform-origin: 354px 554px; | |
| } | |
| .right-blade-splash { | |
| animation: right-splash 1.45s ease-in-out infinite; | |
| transform-origin: 846px 554px; | |
| } | |
| .blink { | |
| animation: blink 5.8s ease-in-out infinite; | |
| transform-origin: center; | |
| } | |
| .breath { | |
| animation: breath 2.3s ease-in-out infinite; | |
| transform-origin: center; | |
| } | |
| .river-glint { | |
| animation: glint 2.4s ease-in-out infinite alternate; | |
| } | |
| @keyframes mist-drift { | |
| from { transform: translateX(-72px); opacity: 0.42; } | |
| 50% { opacity: 0.68; } | |
| to { transform: translateX(72px); opacity: 0.42; } | |
| } | |
| @keyframes jungle-sway { | |
| from { transform: rotate(-0.6deg) translateX(-4px); } | |
| to { transform: rotate(0.8deg) translateX(5px); } | |
| } | |
| @keyframes river-flow-a { | |
| from { transform: translateX(-120px); } | |
| to { transform: translateX(120px); } | |
| } | |
| @keyframes river-flow-b { | |
| from { transform: translateX(135px); } | |
| to { transform: translateX(-135px); } | |
| } | |
| @keyframes boat-bob { | |
| 0%, 100% { transform: translateY(0) rotate(-0.6deg); } | |
| 35% { transform: translateY(-8px) rotate(0.8deg); } | |
| 70% { transform: translateY(4px) rotate(-1deg); } | |
| } | |
| @keyframes shadow-breathe { | |
| 0%, 100% { transform: scaleX(1); opacity: 0.34; } | |
| 50% { transform: scaleX(0.91); opacity: 0.22; } | |
| } | |
| @keyframes frog-lean { | |
| 0%, 100% { transform: translateX(0) rotate(-2deg); } | |
| 45% { transform: translateX(7px) translateY(2px) rotate(3deg); } | |
| 70% { transform: translateX(-3px) translateY(-2px) rotate(-4deg); } | |
| } | |
| @keyframes frog-head { | |
| 0%, 100% { transform: rotate(1deg) translateY(0); } | |
| 45% { transform: rotate(-2deg) translateY(2px); } | |
| 70% { transform: rotate(3deg) translateY(-1px); } | |
| } | |
| @keyframes left-oar-stroke { | |
| 0%, 100% { transform: rotate(18deg); } | |
| 34% { transform: rotate(-20deg); } | |
| 58% { transform: rotate(-33deg); } | |
| 74% { transform: rotate(9deg); } | |
| } | |
| @keyframes right-oar-stroke { | |
| 0%, 100% { transform: rotate(-18deg); } | |
| 34% { transform: rotate(20deg); } | |
| 58% { transform: rotate(33deg); } | |
| 74% { transform: rotate(-9deg); } | |
| } | |
| @keyframes left-arm-stroke { | |
| 0%, 100% { transform: rotate(-15deg) translateX(0); } | |
| 34% { transform: rotate(12deg) translateX(-10px); } | |
| 58% { transform: rotate(22deg) translateX(-14px); } | |
| 74% { transform: rotate(-5deg) translateX(5px); } | |
| } | |
| @keyframes right-arm-stroke { | |
| 0%, 100% { transform: rotate(15deg) translateX(0); } | |
| 34% { transform: rotate(-12deg) translateX(10px); } | |
| 58% { transform: rotate(-22deg) translateX(14px); } | |
| 74% { transform: rotate(5deg) translateX(-5px); } | |
| } | |
| @keyframes left-splash { | |
| 0%, 28%, 100% { opacity: 0; transform: scale(0.6) translateY(4px); } | |
| 39% { opacity: 1; transform: scale(1.12) translateY(-4px); } | |
| 58% { opacity: 0.34; transform: scale(1.5) translateY(-9px); } | |
| } | |
| @keyframes right-splash { | |
| 0%, 28%, 100% { opacity: 0; transform: scale(0.6) translateY(4px); } | |
| 39% { opacity: 1; transform: scale(1.12) translateY(-4px); } | |
| 58% { opacity: 0.34; transform: scale(1.5) translateY(-9px); } | |
| } | |
| @keyframes blink { | |
| 0%, 92%, 100% { transform: scaleY(1); } | |
| 95% { transform: scaleY(0.08); } | |
| } | |
| @keyframes breath { | |
| 0%, 100% { transform: scale(1); } | |
| 50% { transform: scale(1.025); } | |
| } | |
| @keyframes glint { | |
| from { opacity: 0.2; } | |
| to { opacity: 0.7; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <main aria-label="Animated SVG of a frog rowing a boat through a jungle river"> | |
| <svg viewBox="0 0 1200 800" role="img" aria-labelledby="title desc" xmlns="http://www.w3.org/2000/svg"> | |
| <title id="title">Animated frog rowing a boat through a jungle river</title> | |
| <desc id="desc">A green frog rows a wooden canoe on a tropical river, with moving oars, splashes, drifting water, and swaying jungle leaves.</desc> | |
| <defs> | |
| <linearGradient id="sky" x1="0" x2="0" y1="0" y2="1"> | |
| <stop offset="0" stop-color="var(--sky-top)"/> | |
| <stop offset="0.58" stop-color="#bbdfad"/> | |
| <stop offset="1" stop-color="var(--sky-bottom)"/> | |
| </linearGradient> | |
| <linearGradient id="riverGradient" x1="0" x2="0" y1="0" y2="1"> | |
| <stop offset="0" stop-color="#21909a"/> | |
| <stop offset="0.5" stop-color="var(--river)"/> | |
| <stop offset="1" stop-color="var(--river-dark)"/> | |
| </linearGradient> | |
| <linearGradient id="boatWood" x1="0" x2="1" y1="0" y2="1"> | |
| <stop offset="0" stop-color="#b97434"/> | |
| <stop offset="0.45" stop-color="var(--wood)"/> | |
| <stop offset="1" stop-color="var(--wood-dark)"/> | |
| </linearGradient> | |
| <radialGradient id="frogSkin" cx="45%" cy="32%" r="72%"> | |
| <stop offset="0" stop-color="#b9f279"/> | |
| <stop offset="0.45" stop-color="var(--frog)"/> | |
| <stop offset="1" stop-color="var(--frog-dark)"/> | |
| </radialGradient> | |
| <radialGradient id="sunGlow" cx="50%" cy="50%" r="50%"> | |
| <stop offset="0" stop-color="#fff7af" stop-opacity="0.95"/> | |
| <stop offset="0.58" stop-color="#ffd26c" stop-opacity="0.6"/> | |
| <stop offset="1" stop-color="#ffbf58" stop-opacity="0"/> | |
| </radialGradient> | |
| <filter id="softShadow" x="-30%" y="-30%" width="160%" height="160%"> | |
| <feGaussianBlur stdDeviation="6"/> | |
| </filter> | |
| <filter id="leafShadow" x="-20%" y="-20%" width="140%" height="140%"> | |
| <feDropShadow dx="0" dy="5" stdDeviation="4" flood-color="#062f29" flood-opacity="0.35"/> | |
| </filter> | |
| <pattern id="woodGrain" width="80" height="22" patternUnits="userSpaceOnUse"> | |
| <path d="M0 6 C18 0 38 14 58 7 S86 5 98 10" fill="none" stroke="#c98948" stroke-opacity="0.38" stroke-width="2"/> | |
| <path d="M-8 17 C18 21 29 10 50 17 S78 22 91 15" fill="none" stroke="#3d2115" stroke-opacity="0.32" stroke-width="1.8"/> | |
| </pattern> | |
| </defs> | |
| <rect width="1200" height="800" fill="url(#sky)"/> | |
| <circle cx="600" cy="210" r="178" fill="url(#sunGlow)"/> | |
| <circle cx="600" cy="210" r="64" fill="#ffe08b" opacity="0.78"/> | |
| <g class="mist" opacity="0.46"> | |
| <path d="M44 274 C178 238 314 266 456 241 C600 215 755 246 900 222 C1012 203 1116 215 1220 194" fill="none" stroke="#eaffef" stroke-width="18" stroke-linecap="round" opacity="0.34"/> | |
| <path d="M-40 336 C148 302 260 327 402 302 C556 275 693 297 836 279 C980 261 1068 278 1240 246" fill="none" stroke="#f5fff9" stroke-width="12" stroke-linecap="round" opacity="0.28"/> | |
| </g> | |
| <g class="back-leaves" filter="url(#leafShadow)"> | |
| <path d="M0 345 C82 252 145 242 238 328 C140 318 74 356 0 428Z" fill="#127347"/> | |
| <path d="M80 312 C135 194 226 142 358 180 C256 222 206 282 190 390Z" fill="#2c9652"/> | |
| <path d="M1000 335 C1087 244 1138 244 1200 299 L1200 448 C1118 364 1072 346 1000 335Z" fill="#0e6b43"/> | |
| <path d="M908 202 C1040 145 1137 176 1210 252 C1110 234 1016 263 945 354Z" fill="#3b9d51"/> | |
| <path d="M306 232 C378 130 486 98 602 150 C501 190 440 249 401 363Z" fill="#117447"/> | |
| <path d="M638 159 C755 92 866 99 984 178 C868 178 779 228 707 343Z" fill="#1c8752"/> | |
| </g> | |
| <g opacity="0.78"> | |
| <path d="M0 379 C122 336 206 347 316 395 C442 449 517 430 600 391 C707 342 798 335 927 389 C1023 429 1101 425 1200 388 L1200 800 L0 800Z" fill="#0c694b"/> | |
| <path d="M0 418 C115 375 229 389 328 430 C456 483 534 458 623 416 C724 368 808 371 923 425 C1036 478 1117 464 1200 431 L1200 800 L0 800Z" fill="#07513d"/> | |
| </g> | |
| <path d="M0 438 C142 414 260 448 374 479 C503 514 686 514 826 480 C963 447 1080 419 1200 444 L1200 800 L0 800Z" fill="url(#riverGradient)"/> | |
| <path d="M0 536 C167 482 318 501 493 537 C643 568 775 570 929 526 C1042 493 1135 493 1200 510 L1200 800 L0 800Z" fill="#0d5b72" opacity="0.34"/> | |
| <g class="current-a" fill="none" stroke="#93d9cf" stroke-linecap="round" opacity="0.48"> | |
| <path d="M-130 504 C-88 494 -46 494 0 506 S86 519 133 503" stroke-width="5"/> | |
| <path d="M80 602 C132 589 190 592 242 606 S340 623 397 601" stroke-width="3"/> | |
| <path d="M430 555 C486 540 540 544 590 559 S682 575 731 555" stroke-width="4"/> | |
| <path d="M822 629 C884 611 936 617 988 633 S1080 651 1135 630" stroke-width="4"/> | |
| <path d="M1060 494 C1120 477 1175 484 1234 501 S1332 520 1390 498" stroke-width="5"/> | |
| </g> | |
| <g class="current-b" fill="none" stroke="#d6f3df" stroke-linecap="round" opacity="0.32"> | |
| <path d="M-70 669 C-10 648 44 651 110 672 S220 697 286 666" stroke-width="4"/> | |
| <path d="M250 466 C306 454 357 458 418 473 S522 488 576 469" stroke-width="3"/> | |
| <path d="M622 702 C681 684 739 687 800 707 S913 733 976 700" stroke-width="4"/> | |
| <path d="M940 565 C1000 544 1055 548 1117 569 S1232 596 1293 563" stroke-width="3"/> | |
| </g> | |
| <g class="river-glint" fill="none" stroke="#fcf2bc" stroke-linecap="round" opacity="0.36"> | |
| <path d="M482 459 C522 452 554 454 587 462" stroke-width="3"/> | |
| <path d="M630 452 C674 442 719 446 759 459" stroke-width="3"/> | |
| <path d="M524 678 C590 661 663 664 730 682" stroke-width="2"/> | |
| </g> | |
| <ellipse class="boat-shadow" cx="600" cy="594" rx="265" ry="34" fill="#062d34" opacity="0.32" filter="url(#softShadow)"/> | |
| <g class="boat-rig"> | |
| <g class="left-oar"> | |
| <line x1="520" y1="500" x2="344" y2="548" stroke="#6f3d22" stroke-width="16" stroke-linecap="round"/> | |
| <line x1="520" y1="500" x2="344" y2="548" stroke="#c98b50" stroke-width="5" stroke-linecap="round" opacity="0.65"/> | |
| <path d="M323 532 C294 541 279 570 297 589 C326 585 351 563 353 538 C345 533 335 530 323 532Z" fill="#c17734" stroke="#4b2a1b" stroke-width="4"/> | |
| </g> | |
| <g class="right-oar"> | |
| <line x1="680" y1="500" x2="856" y2="548" stroke="#6f3d22" stroke-width="16" stroke-linecap="round"/> | |
| <line x1="680" y1="500" x2="856" y2="548" stroke="#c98b50" stroke-width="5" stroke-linecap="round" opacity="0.65"/> | |
| <path d="M877 532 C906 541 921 570 903 589 C874 585 849 563 847 538 C855 533 865 530 877 532Z" fill="#c17734" stroke="#4b2a1b" stroke-width="4"/> | |
| </g> | |
| <path d="M382 490 C424 574 503 618 600 618 C697 618 776 574 818 490 C752 511 664 520 600 520 C536 520 448 511 382 490Z" fill="url(#boatWood)" stroke="#321b12" stroke-width="8" stroke-linejoin="round"/> | |
| <path d="M408 496 C468 534 536 550 600 550 C664 550 732 534 792 496 C744 555 676 589 600 589 C524 589 456 555 408 496Z" fill="#5b321e" opacity="0.52"/> | |
| <path d="M397 492 C457 510 526 519 600 519 C674 519 743 510 803 492" fill="none" stroke="#d79655" stroke-width="10" stroke-linecap="round"/> | |
| <path d="M397 492 C457 510 526 519 600 519 C674 519 743 510 803 492" fill="none" stroke="url(#woodGrain)" stroke-width="16" stroke-linecap="round" opacity="0.8"/> | |
| <path d="M475 536 L725 536" stroke="#2b170f" stroke-width="8" stroke-linecap="round" opacity="0.55"/> | |
| <path d="M486 526 C525 540 675 540 714 526" stroke="#c3834b" stroke-width="5" stroke-linecap="round" opacity="0.5"/> | |
| <g class="frog-body"> | |
| <ellipse class="breath" cx="600" cy="458" rx="68" ry="72" fill="url(#frogSkin)" stroke="#23672f" stroke-width="5"/> | |
| <ellipse cx="600" cy="476" rx="43" ry="45" fill="#b9e77b" opacity="0.82"/> | |
| <ellipse cx="552" cy="509" rx="31" ry="20" fill="#3d963f" stroke="#23672f" stroke-width="4"/> | |
| <ellipse cx="648" cy="509" rx="31" ry="20" fill="#3d963f" stroke="#23672f" stroke-width="4"/> | |
| <g class="left-arm"> | |
| <path d="M558 454 C531 461 512 478 500 505" fill="none" stroke="#4ba940" stroke-width="18" stroke-linecap="round"/> | |
| <circle cx="500" cy="505" r="14" fill="#73c84b" stroke="#23672f" stroke-width="4"/> | |
| <path d="M492 505 L477 492 M493 510 L474 511 M498 517 L484 530" stroke="#23672f" stroke-width="4" stroke-linecap="round"/> | |
| </g> | |
| <g class="right-arm"> | |
| <path d="M642 454 C669 461 688 478 700 505" fill="none" stroke="#4ba940" stroke-width="18" stroke-linecap="round"/> | |
| <circle cx="700" cy="505" r="14" fill="#73c84b" stroke="#23672f" stroke-width="4"/> | |
| <path d="M708 505 L723 492 M707 510 L726 511 M702 517 L716 530" stroke="#23672f" stroke-width="4" stroke-linecap="round"/> | |
| </g> | |
| <g class="frog-head"> | |
| <circle cx="600" cy="382" r="64" fill="url(#frogSkin)" stroke="#23672f" stroke-width="5"/> | |
| <circle cx="560" cy="336" r="31" fill="#82cf52" stroke="#23672f" stroke-width="5"/> | |
| <circle cx="640" cy="336" r="31" fill="#82cf52" stroke="#23672f" stroke-width="5"/> | |
| <g class="blink"> | |
| <circle cx="560" cy="336" r="16" fill="#f7ffe5"/> | |
| <circle cx="640" cy="336" r="16" fill="#f7ffe5"/> | |
| <circle cx="564" cy="340" r="7" fill="#102421"/> | |
| <circle cx="636" cy="340" r="7" fill="#102421"/> | |
| <circle cx="567" cy="337" r="2.5" fill="#fff"/> | |
| <circle cx="639" cy="337" r="2.5" fill="#fff"/> | |
| </g> | |
| <circle cx="575" cy="383" r="5" fill="#23672f"/> | |
| <circle cx="625" cy="383" r="5" fill="#23672f"/> | |
| <path d="M554 403 C575 424 625 424 646 403" fill="none" stroke="#1f5d2c" stroke-width="6" stroke-linecap="round"/> | |
| <circle cx="546" cy="396" r="12" fill="#e77971" opacity="0.35"/> | |
| <circle cx="654" cy="396" r="12" fill="#e77971" opacity="0.35"/> | |
| </g> | |
| </g> | |
| <circle cx="520" cy="500" r="10" fill="#22130d"/> | |
| <circle cx="680" cy="500" r="10" fill="#22130d"/> | |
| </g> | |
| <g class="left-blade-splash" fill="none" stroke="#d3fbff" stroke-linecap="round" opacity="0"> | |
| <path d="M314 560 C300 548 294 536 295 522" stroke-width="4"/> | |
| <path d="M332 572 C324 588 309 601 291 606" stroke-width="4"/> | |
| <path d="M347 551 C364 546 380 548 392 557" stroke-width="3"/> | |
| </g> | |
| <g class="right-blade-splash" fill="none" stroke="#d3fbff" stroke-linecap="round" opacity="0"> | |
| <path d="M886 560 C900 548 906 536 905 522" stroke-width="4"/> | |
| <path d="M868 572 C876 588 891 601 909 606" stroke-width="4"/> | |
| <path d="M853 551 C836 546 820 548 808 557" stroke-width="3"/> | |
| </g> | |
| <g class="front-leaves" filter="url(#leafShadow)"> | |
| <path d="M0 668 C78 590 143 578 226 623 C132 645 64 704 0 800Z" fill="#064c38"/> | |
| <path d="M0 564 C65 522 126 517 198 549 C115 586 55 644 0 738Z" fill="#0d7c45"/> | |
| <path d="M91 696 C137 619 219 602 300 650 C219 670 161 715 116 800 L76 800Z" fill="#2b9950"/> | |
| <path d="M1200 642 C1126 584 1057 582 982 630 C1066 648 1138 707 1200 798Z" fill="#064f3a"/> | |
| <path d="M1200 548 C1134 511 1076 513 1006 552 C1090 584 1148 641 1200 731Z" fill="#11844a"/> | |
| <path d="M1095 704 C1049 618 960 601 878 653 C960 671 1016 718 1060 800 L1124 800Z" fill="#43a84f"/> | |
| <path d="M20 620 C54 592 97 593 134 622 C94 633 59 660 35 704Z" fill="#7dbd39"/> | |
| <path d="M1167 618 C1131 592 1088 596 1054 627 C1094 635 1130 661 1156 704Z" fill="#86c64b"/> | |
| </g> | |
| </svg> | |
| </main> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment