.container#example_container
#example_wrapper
canvas#example_canvas
.call-to-action
h1 Voxel Chicky
p I created this model using MagicaVoxel
button.btn-bounce#btn_bounce Make Chicky bounce!
View Compiled
@import url("https://fonts.googleapis.com/css2?family=Luckiest+Guy")
@import url("https://fonts.googleapis.com/css2?family=Rubik")
$yellow: #ffec1c
$orange: #e37807
html, body
width: 100%
height: 100%
body
font-size: 24px
background-image: linear-gradient(#2bb5ff, #3366ff)
.container
width: 100%
height: 100%
margin: auto
position: relative
.call-to-action
text-align: center
width: 100%
height: 100%
display: flex
flex-direction: column
position: absolute
top: 0
left: 0
h1, p
padding: 0 1rem
h1
color: $yellow
font-family: "Luckiest Guy", cursive
margin: 3rem 0 1rem
text-shadow: 0 0.35rem $orange
p
color: #efefef
font-family: "Rubik", sans-serif
margin: 0
.btn-bounce
color: #4f4f4f
font-family: "Rubik", sans-serif
background-color: $yellow
padding: 1rem 2rem
border: 0
margin: auto 2rem 3rem
align-self: center
border-radius: 0.75rem
box-shadow: 0 0.35rem $orange
transition: box-shadow 64ms ease-out, transform 64ms ease-out
&:active
box-shadow: 0 0rem $orange
transform: translateY(0.35rem)
@media screen and (min-width: 568px)
.container
width: 568px
View Compiled
import {
Scene,
PerspectiveCamera,
WebGLRenderer,
Color,
AmbientLight,
DirectionalLight,
Group,
} from "https://cdn.skypack.dev/three@0.135.0";
import {
VOXLoader,
VOXMesh
} from "https://cdn.skypack.dev/three@0.135.0/examples/jsm/loaders/VOXLoader.js";
import gsap from "https://cdn.skypack.dev/gsap@3.8.0";
console.clear();
const exampleContainer = document.querySelector("#example_container");
const exampleCanvas = document.querySelector("#example_canvas");
const btnBounce = document.querySelector("#btn_bounce");
const scene = new Scene();
const camera = new PerspectiveCamera(
75, exampleContainer.clientWidth / exampleContainer.clientHeight, 0.1, 1000);
const renderer = new WebGLRenderer({
canvas: exampleCanvas,
alpha: true,
antialias: true,
});
const chicky = new Group();
const tl = gsap.timeline();
function setRenderer() {
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(exampleContainer.clientWidth, exampleContainer.clientHeight);
}
function setLighting() {
const ambientColor = 0xFFFFFF;
const ambientIntensity = 0.3;
const ambientLight = new AmbientLight(ambientColor, ambientIntensity);
scene.add(ambientLight);
const directionalColor = 0xFFFFFF;
const directionalIntensity = 1;
const directionalLight = new DirectionalLight(
directionalColor, directionalIntensity);
const directionalX = -10;
const directionalY = 30;
const directionalZ = 20;
directionalLight.position.set(directionalX, directionalY, directionalZ);
directionalLight.castShadow = true;
scene.add(directionalLight);
scene.add(directionalLight.target);
}
function loadModel() {
const loader = new VOXLoader();
loader.load("https://assets.codepen.io/430361/Chicky.vox", chunks => {
for (let chunk of chunks) {
const voxMesh = new VOXMesh(chunk);
voxMesh.scale.setScalar(0.25);
chicky.add(voxMesh);
}
scene.add(chicky);
});
}
function update() {
requestAnimationFrame(update);
renderer.render(scene, camera);
chicky.rotation.y += 0.0075;
}
function initialize() {
setRenderer();
// Initialize camera position
camera.position.z = 5;
setLighting();
loadModel();
update();
}
function bounceModel() {
tl.clear();
// Fall from top
tl.fromTo(chicky.position, {
y: 3,
}, {
y: 0,
duration: 0.8,
ease: "power2.in",
});
// Squish
tl.to(chicky.scale, {
x: 1.35,
y: 0.65,
duration: 0.24,
});
tl.to(chicky.position, {
y: -1.05,
duration: 0.24,
}, "-=0.24");
// Bounce
tl.to(chicky.scale, {
x: 0.75,
y: 1.25,
duration: 0.32,
});
tl.to(chicky.position, {
y: 1.5,
duration: 0.64,
ease: "power1.out",
}, "-=0.32");
// Fall again
tl.to(chicky.position, {
y: 0,
duration: 0.56,
ease: "power2.in",
});
tl.to(chicky.scale, {
x: 1,
y: 1,
duration: 0.56,
}, "-=0.56");
// Squish
tl.to(chicky.scale, {
x: 1.15,
y: 0.85,
duration: 0.16,
});
tl.to(chicky.position, {
y: -0.48,
duration: 0.16,
}, "-=0.16");
// Bounce again
tl.to(chicky.position, {
y: 1,
duration: 0.48,
});
tl.to(chicky.scale, {
x: 1,
y: 1,
duration: 0.48,
ease: "power1.out",
}, "-=0.48");
// Bounce animation
tl.to(chicky.position, {
y: 0,
duration: 1.024,
ease: "bounce.out",
});
}
initialize();
window.addEventListener("resize", () => {
camera.aspect = exampleContainer.clientWidth / exampleContainer.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(exampleContainer.clientWidth, exampleContainer.clientHeight);
});
btnBounce.addEventListener("click", () => {
bounceModel();
});
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.