A Pen by Grant Jenkins on CodePen.
Created
November 10, 2025 05:19
-
-
Save rsp2k/9d7f4f5d54208c6a1ffabe37156264d7 to your computer and use it in GitHub Desktop.
3D Bee (Animated)
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
| //- | |
| 3D Bee using HTML/CSS | |
| By Grant Jenkins, June 2022 | |
| Submitted for the positive and negative numbers codepen challenge | |
| #codepenchallenge, #cpc-positive-negative, #cpc-cubes | |
| mixin cube(id) | |
| div(id=id,class='cube') | |
| .container | |
| .left | |
| .right | |
| .top | |
| .bottom | |
| .front | |
| .back | |
| mixin pyramid(id, sides) | |
| div(id=id,class='pyramid') | |
| .container | |
| - for (s = 0; s < sides; s++) | |
| span | |
| mixin flower(id) | |
| div(id=id,class='flower') | |
| +cube(id+'-pot') | |
| +cube(id+'-trunk') | |
| +cube(id+'-top') | |
| +cube(id+'-horizontal') | |
| +cube(id+'-vertical') | |
| +cube(id+'-center') | |
| doctype html | |
| html(lang='en') | |
| .scene | |
| +cube('ground') | |
| .flowers | |
| +flower('flower-1') | |
| +flower('flower-2') | |
| +flower('flower-3') | |
| +flower('flower-4') | |
| .bee | |
| .body | |
| - for (i = 1; i <= 5; i++) | |
| +cube('body-'+i) | |
| +pyramid('stinger', 4) | |
| .eyes | |
| +cube('eye-left') | |
| +cube('eye-right') | |
| .antennas | |
| +cube('antenna-left') | |
| +cube('antenna-left-front') | |
| +cube('antenna-right') | |
| +cube('antenna-right-front') | |
| .feet | |
| - for (i = 1; i <= 6; i++) | |
| +cube('feet-'+i) | |
| .wings | |
| +cube('wing-left') | |
| +cube('wing-right') | |
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
| @use "sass:math"; | |
| $scene-width: 70vmin; | |
| $scene-depth: 70vmin; | |
| $scene-height: 20vmin; | |
| $scale: 1.0; | |
| $wing-speed: 0.075s; | |
| $color-main: #244775; | |
| $color-body: #D1A438; | |
| $color-wing: #8DBCB8; | |
| @mixin flower($color-flower, $color-center) { | |
| div:nth-child(1) { //pot | |
| $width: 8vmin; | |
| $height: 1vmin; | |
| $depth: 8vmin; | |
| $color: #BC7D3D; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(0, 0, 0); | |
| .container .bottom { | |
| box-shadow: 0 0 5vmin #000; | |
| } | |
| } | |
| div:nth-child(2) { //trunk | |
| $width: 2vmin; | |
| $height: 7vmin; | |
| $depth: 2vmin; | |
| $color: #4CB648; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(3vmin, -1vmin, 0); | |
| } | |
| div:nth-child(3) { //top | |
| $width: 8vmin; | |
| $height: 1.5vmin; | |
| $depth: 8vmin; | |
| $color: $color-flower; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(0vmin, -8vmin, 0); | |
| } | |
| div:nth-child(4) { //horizontal | |
| $width: 10vmin; | |
| $height: 1.5vmin; | |
| $depth: 3vmin; | |
| $color: $color-flower; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(-1vmin, -8vmin, 0); | |
| } | |
| div:nth-child(5) { //vertical | |
| $width: 3vmin; | |
| $height: 1.5vmin; | |
| $depth: 10vmin; | |
| $color: $color-flower; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(2.5vmin, -8vmin, 0); | |
| } | |
| div:nth-child(6) { //center | |
| $width: 3vmin; | |
| $height: 1vmin; | |
| $depth: 3vmin; | |
| $color: $color-center; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(2.5vmin, -9vmin, 0); | |
| } | |
| } | |
| @mixin pyramid($width, $height, $sides, $color) { | |
| width: $width; | |
| height: $height; | |
| .container { | |
| position: relative; | |
| width: 100%; | |
| height: 100%; | |
| &::after { | |
| content: ''; | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| background-color: $color; | |
| transform: | |
| rotateX(90deg) | |
| translateZ($height / -2); | |
| } | |
| * { | |
| position: absolute; | |
| bottom: 0; | |
| } | |
| $_angle: 360deg / $sides; | |
| $_len: math.sin($_angle) * $height; | |
| @for $i from 1 through $sides { | |
| span:nth-child(#{$i}) { | |
| width: $width; | |
| height: $height; | |
| clip-path: polygon(50% 0%, 0% 100%, 100% 100%); | |
| background-color: darken($color, min(($i * 5%), 100%)); | |
| background-image: linear-gradient(90deg, $color, darken($color, 10%)); | |
| transform-origin: bottom; | |
| transform: | |
| rotateX(90deg) | |
| rotateZ(360deg / $sides * $i) | |
| translateY($height * -1.5) | |
| translateY($width) | |
| rotateX(-119.5deg) | |
| ; | |
| } | |
| } | |
| } | |
| } | |
| @mixin box($width, $height, $depth, $color) { | |
| width: $width; | |
| height: $height; | |
| .container { | |
| position: relative; | |
| width: 100%; | |
| height: 100%; | |
| * { | |
| position: absolute; | |
| bottom: 0; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .left { | |
| width: $depth; | |
| height: $height; | |
| background-color: $color; | |
| transform-origin: left top; | |
| transform: | |
| rotateY(-90deg) | |
| translateX($depth / -2); | |
| } | |
| .right { | |
| width: $depth; | |
| height: $height; | |
| background-color: $color; | |
| transform-origin: left top; | |
| transform: | |
| rotateY(90deg) | |
| translateX($depth / -2) | |
| translateZ($width); | |
| } | |
| .top { | |
| background-color: lighten($color, 5%); | |
| width: $width; | |
| height: $depth; | |
| transform-origin: bottom left; | |
| transform: | |
| rotateX(90deg) | |
| translateY($depth / 2) | |
| translateZ($height); | |
| } | |
| .bottom { | |
| background-color: lighten($color, 5%); | |
| width: $width; | |
| height: $depth; | |
| transform-origin: bottom left; | |
| transform: | |
| rotateX(-90deg) | |
| translateY($depth / 2); | |
| } | |
| .front { | |
| background-color: darken($color, 8%); | |
| width: $width; | |
| height: $height; | |
| transform-origin: bottom left; | |
| transform: | |
| translateZ($depth / 2); | |
| } | |
| .back { | |
| background-color: darken($color, 8%); | |
| width: $width; | |
| height: $height; | |
| transform-origin: center; | |
| transform: | |
| rotateY(180deg) | |
| translateZ($depth / 2); | |
| } | |
| } | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| display: grid; | |
| place-items: center; | |
| min-height: 100vh; | |
| background-image: radial-gradient(lighten($color-main, 10%), darken($color-main, 15%)); | |
| overflow: hidden; | |
| perspective: 1000px; | |
| .scene, .scene * { | |
| transform-style: preserve-3d; | |
| } | |
| .scene { | |
| position: relative; | |
| width: $scene-width; | |
| height: $scene-height; | |
| transform: | |
| rotateX(-30deg) | |
| rotateY(-10deg) | |
| scale3d($scale, $scale, $scale); | |
| animation: rot 20s ease-in-out 0s infinite alternate; | |
| @keyframes rot { | |
| to { | |
| transform: | |
| rotateX(0deg) | |
| rotateY(440deg) | |
| scale3d($scale, $scale, $scale); | |
| } | |
| } | |
| // base | |
| &::after { | |
| content: ''; | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| left: 0; | |
| top: 0; | |
| z-index: -100; | |
| // background-color: darken(brown, 10%); | |
| transform: | |
| rotateX(90deg) | |
| translateZ(calc(#{$scene-depth} / -2)) | |
| scale(1.0); | |
| } | |
| .cube, .cube * { | |
| position: absolute; | |
| bottom: 0; | |
| } | |
| #ground { | |
| z-index: -50; | |
| $width: $scene-width; | |
| $height: 3vmin; | |
| $depth: $scene-depth; | |
| $color: #92C54E; | |
| @include box($width, $height, $depth, $color); | |
| .container { | |
| .left, .right, .front, .back { | |
| background-image: | |
| linear-gradient(180deg, #0000 0% 20%, #6C883E 20% 45%, #BC7D3D 45% 100%); | |
| } | |
| .bottom { | |
| background-color: #E1B366; | |
| filter: drop-shadow(0 0 3.75rem black); | |
| } | |
| .top { | |
| box-shadow: inset 0 0 15vmin #000a; | |
| background-image: | |
| radial-gradient(#0008, #0000 10em), | |
| repeating-linear-gradient(90deg, #0000 0% 50%, #0001 50% 100%); | |
| background-size: 100%, 4em 4em, 4em 4em; | |
| // animation: moveGround 0.5s infinite linear; | |
| @keyframes moveGround { | |
| to { | |
| background-position-x: center, 4em, 4em; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| .flowers { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| bottom: 0; | |
| transform: translate3d(0, -3.02vmin, 0); | |
| div { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| bottom: 0; | |
| } | |
| #flower-1 { | |
| @include flower(#F15D5C, #ECD015); | |
| transform: translate3d(14vmin, -0vmin, -25vmin); | |
| } | |
| #flower-2 { | |
| @include flower(#F47A2D, #0D6B37); | |
| transform: translate3d(7vmin, -0vmin, 20vmin); | |
| } | |
| #flower-3 { | |
| @include flower(#81ACD8, #EC3536); | |
| transform: translate3d(53vmin, -0vmin, -20vmin); | |
| } | |
| #flower-4 { | |
| @include flower(#AE7CB7, #ECD016); | |
| transform: translate3d(45vmin, -0vmin, 25vmin); | |
| } | |
| } | |
| .bee { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| bottom: 0; | |
| transform-origin: center left; | |
| transform: | |
| translate3d(25vmin, -10vmin, 0); | |
| animation: fly 10s ease-in-out infinite alternate; | |
| @keyframes fly { | |
| 33% { | |
| transform: | |
| translate3d(25vmin, -20vmin, 0vmin) | |
| rotate3d(0.0, 0.2, 0.05, 20deg); | |
| } | |
| 66% { | |
| transform: | |
| translate3d(25vmin, -20vmin, 0vmin) | |
| rotate3d(0.0, 0.2, 0.05, -20deg); | |
| } | |
| 100% { | |
| transform: | |
| translate3d(25vmin, -20vmin, 0vmin) | |
| rotate3d(0.0, 1, 0.0, 360deg); | |
| } | |
| } | |
| .body, .feet, .eyes, .antennas, .wings, .pyramid { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| bottom: 0; | |
| } | |
| .body { | |
| @for $i from 1 through 5 { | |
| #{'#body-' + $i} { | |
| $width: 4vmin; | |
| $height: 12vmin; | |
| $depth: 15vmin; | |
| $color: $color-body; | |
| @if $i % 2 == 0 { $color: black; } | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(($i - 1) * 4.05vmin, -2vmin, 0); | |
| } | |
| } | |
| #stinger { | |
| transform: | |
| translate3d(20.2vmin, -6vmin, 0vmin) | |
| rotateZ(90deg); | |
| @include pyramid(5vmin, 5vmin, 4, #111); | |
| } | |
| } | |
| .eyes { | |
| #eye-left { | |
| $width: 1vmin; | |
| $height: 5.5vmin; | |
| $depth: 6vmin; | |
| $color: white; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(-0.2vmin, -6.5vmin, 4.6vmin); | |
| .container { | |
| .left { | |
| background-image: | |
| linear-gradient(180deg, white 0% 50%, #0000 50% 100%), | |
| linear-gradient(90deg, #0000 0% 25%, black 20% 75%, #0000 75% 100%); | |
| } | |
| } | |
| } | |
| #eye-right { | |
| $width: 1vmin; | |
| $height: 5.5vmin; | |
| $depth: 6vmin; | |
| $color: white; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(-0.2vmin, -6.5vmin, -4.6vmin); | |
| .container { | |
| .left { | |
| background-image: | |
| linear-gradient(180deg, white 0% 50%, #0000 50% 100%), | |
| linear-gradient(90deg, #0000 0% 25%, black 20% 75%, #0000 75% 100%); | |
| } | |
| } | |
| } | |
| } | |
| .wings { | |
| #wing-left { | |
| $width: 10vmin; | |
| $height: 1vmin; | |
| $depth: 20vmin; | |
| $color: $color-wing; | |
| @include box($width, $height, $depth, $color); | |
| // transform-origin: bottom right; | |
| transform: | |
| translate3d(4.5vmin, -9vmin, 7.5vmin) | |
| rotateX(-20deg); | |
| animation: flap-left $wing-speed linear infinite alternate; | |
| @keyframes flap-left { | |
| to { | |
| transform: | |
| translate3d(4.5vmin, -9vmin, 7.5vmin) | |
| rotateX(20deg); | |
| } | |
| } | |
| } | |
| #wing-right { | |
| $width: 10vmin; | |
| $height: 1vmin; | |
| $depth: 20vmin; | |
| $color: $color-wing; | |
| @include box($width, $height, $depth, $color); | |
| // transform-origin: bottom right; | |
| transform: | |
| translate3d(4.5vmin, -9vmin, -7.5vmin) | |
| rotateX(-20deg); | |
| animation: flap-right $wing-speed linear infinite alternate-reverse; | |
| @keyframes flap-right { | |
| to { | |
| transform: | |
| translate3d(4.5vmin, -9vmin, -7.5vmin) | |
| rotateX(20deg); | |
| } | |
| } | |
| } | |
| } | |
| .antennas { | |
| #antenna-left { | |
| $width: 1vmin; | |
| $height: 2vmin; | |
| $depth: 1vmin; | |
| $color: black; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(0, -14vmin, 4vmin); | |
| } | |
| #antenna-left-front { | |
| $width: 1vmin; | |
| $height: 1.5vmin; | |
| $depth: 1vmin; | |
| $color: $color-body; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(-1vmin, -14.5vmin, 4vmin); | |
| } | |
| #antenna-right { | |
| $width: 1vmin; | |
| $height: 2vmin; | |
| $depth: 1vmin; | |
| $color: black; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(0, -14vmin, -4vmin); | |
| } | |
| #antenna-right-front { | |
| $width: 1vmin; | |
| $height: 1.5vmin; | |
| $depth: 1vmin; | |
| $color: $color-body; | |
| @include box($width, $height, $depth, $color); | |
| transform: | |
| translate3d(-1vmin, -14.5vmin, -4vmin); | |
| } | |
| } | |
| .feet { | |
| div { | |
| $width: 2vmin; | |
| $height: 4vmin; | |
| $depth: 2vmin; | |
| $color: black; | |
| @include box($width, $height, $depth, $color); | |
| } | |
| @for $i from 1 through 3 { | |
| #{'#feet-' + $i} { | |
| transform: | |
| translate3d($i * 4.5vmin, 0, 6vmin); | |
| } | |
| } | |
| @for $i from 4 through 6 { | |
| #{'#feet-' + $i} { | |
| transform: | |
| translate3d(($i - 3) * 4.5vmin, 0, -6vmin); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment