div.sea
div.blowfish
div.blowfish__tail
div.blowfish__fins
div.blowfish__fin.blowfish__fin--left
div.blowfish__fin.blowfish__fin--right
div.blowfish__body
div.blowfish__face
div.blowfish__eyes
div.blowfish__eye.blowfish__eye--left
div.blowfish__eye.blowfish__eye--right
div.blowfish__mouth
div.blowfish__spikes
View Compiled
$standard-transition: 0.3s ease-in;
$jumpy-transition: 0.1s cubic-bezier(0.75, 0.25, 0.25, 0.75);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.sea {
display: flex;
justify-content: center;
align-items: center;
background: lightseagreen;
width: 100%;
height: 100vh;
background-image: linear-gradient(
to top,
darken(lightseagreen, 10%),
lightseagreen 30%,
lighten(lightseagreen, 30%) 90%
);
}
.blowfish {
--speed: 2s;
--distance-start: 10px;
--distance-end: 20px;
--x: 0;
--y: 0;
--rotate: 0;
position: relative;
left: var(--y);
top: var(--x);
width: 200px;
height: 200px;
transition: $standard-transition;
animation: float var(--speed) infinite alternate;
&__body {
position: relative;
width: 100%;
height: 100%;
&::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
transform: scaleY(0.6);
background: orange;
background-image: linear-gradient(
to top,
rgba(white, 1) 5%,
rgba(white, 0) 50%
),
linear-gradient(45deg, rgba(white, 1) 5%, rgba(white, 0) 50%),
linear-gradient(-45deg, rgba(white, 1) 5%, rgba(white, 0) 50%),
linear-gradient(to bottom, darken(orange, 10%) 10%, rgba(orange, 0) 50%);
border-radius: 5rem 5rem 3rem 3rem;
transition: $standard-transition;
}
&::after {
content: "";
position: absolute;
bottom: -10px;
left: -5px;
// z-index: -1;
width: calc(100% + 10px);
height: calc(100% + 10px);
transform: scaleY(0.6);
background-image: url("data:image/svg+xml,\
<svg xmlns='http://www.w3.org/2000/svg' viewbox='0 0 200 200'><polygon points='3,0 0,10 4,0' fill='orange' opacity='0.6' /></svg>"), url("data:image/svg+xml,\
<svg xmlns='http://www.w3.org/2000/svg' viewbox='0 0 200 200'><polygon points='0,0 2,10 2,1' fill='white' opacity='0.2' /></svg>");
background-repeat: repeat;
background-size: 20px 20px, 15px 25px;
border-radius: 5rem 5rem 3rem 3rem;
transition: $standard-transition;
}
&:hover {
&::before, &::after {
transform: scaleY(0.7);
border-radius: 5rem 5rem 4rem 4rem;
}
.blowfish__eye {
&::before {
transform: scale(0.7);
}
}
.blowfish__mouth {
border-radius: 15px 15px 20px 20px;
}
}
&--blowup,
&--blowup:hover {
&::before, &::after {
transform: scale(1.2);
border-radius: 50%;
transition: $jumpy-transition;
}
.blowfish__eye {
&:before {
transform: scale(0.6);
}
}
.blowfish__mouth {
border-radius: 30px 30px 10px 10px;
&::before, &::after {
opacity: 1;
}
}
}
}
&__fins {
position: absolute;
display: flex;
z-index: -1;
justify-content: space-between;
align-items: center;
width: calc(100% + 80px);
height: 100%;
margin-left: -40px;
}
&__fin {
position: relative;
z-index: -1;
border: orange solid 40px;
border-top-color: transparent;
border-radius: 10px;
-webkit-perspective: 600px;
perspective: 600px;
animation: flow var(--speed) infinite alternate;
filter: drop-shadow(0px -10px 0px darken(orange, 5%));
&::after {
content: "";
position: absolute;
top: -40px;
right: -40px;
z-index: 2;
background-image: linear-gradient(-60deg, white, rgba(white, 0) 30%);
border-radius: 10px;
width: 80px;
height: 80px;
}
&--left {
border-right-color: transparent;
&::after {
left: -40px;
background-image: linear-gradient(-160deg, rgba(white, 0) 40%, white);
}
}
&--right {
border-left-color: transparent;
}
}
&__face {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
&__eyes {
position: relative;
z-index: 1;
width: 100px;
display: flex;
justify-content: space-between;
}
&__eye {
position: relative;
background: white;
border: 4px orange solid;
width: 40px;
height: 40px;
border-radius: 50%;
&::before {
content: "";
position: absolute;
top: 0;
width: 100%;
height: 100%;
border-radius: 50%;
transform: scale(0.9);
background: black;
box-sizing: border-box;
transition: $standard-transition;
}
&::after {
content: "";
position: absolute;
top: 5px;
left: 2px;
width: 10px;
height: 10px;
border-radius: 50%;
background: white;
box-sizing: border-box;
}
}
&__mouth {
position: relative;
z-index: 1;
background: darken(orange, 80%);
width: 20px;
height: 10px;
margin-top: 10px;
border-radius: 10px 10px 40px 40px;
transition: $standard-transition;
&::before {
content: 'NO TOUCHY!!!';
opacity: 0;
transition: $standard-transition;
position: absolute;
top: -200px;
width: 200px;
height: 100px;
background: white;
border-radius: 10px;
padding: 2rem;
box-sizing: border-box;
font-family: 'Helvetica Neue', 'Open sans', sans-serif;
font-size: 20px;
font-weight: bold;
}
&::after {
content: '';
position: absolute;
opacity: 0;
transition: $standard-transition;
top: -110px;
border: white solid 10px;
border-bottom-color: transparent;
border-right-color: transparent;
border-radius: 1px;
box-sizing: border-box;
}
}
}
@keyframes float {
from {
transform: translateY(-10px) rotate(var(--rotate));
}
to {
transform: translateY(10px) rotate(0);
}
}
@keyframes flow {
from {
transform: rotateY(20deg);
}
to {
transform: rotateY(60deg);
}
}
View Compiled
const blowfish = document.querySelector('.blowfish');
const blowfishBody = document.querySelector('.blowfish__body');
let blown = false;
blowfishBody.addEventListener('click', (e) => {
const bounding = blowfishBody.getBoundingClientRect();
const x = e.clientX - window.innerWidth / 2;
const y = e.clientY - window.innerHeight / 2;
blown = !blown;
blowfishBody.classList.toggle('blowfish__body--blowup');
if (blown) {
blowfish.style.setProperty('--speed', '0.4s');
blowfish.style.setProperty('--rotate', '5deg');
blowfish.style.setProperty('--x', `${x * 2}px`);
blowfish.style.setProperty('--y', `${y * 2}px`);
} else {
blowfish.style.setProperty('--speed', '2s');
blowfish.style.setProperty('--rotate', '0');
blowfish.style.setProperty('--x', '0');
blowfish.style.setProperty('--y', '0');
}
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.