JSFiddle - React, Tailwind, and code Playground
by Paul West
HTML
<script src="https://cdn.jsdelivr.net/npm/three@0.93.0/build/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.93.0/examples/js/controls/OrbitControls.js"></script>
CSS
body {
overflow: hidden;
margin: 0;
}
JavaScript
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(2, 3, 5).setLength(4);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.GridHelper(4, 4));
var geom = new THREE.SphereGeometry(1, 8, 4);
// heart morphTargets
var heart = geom.vertices.map(v => {
let tv = v.clone();
let absX = Math.abs(tv.x * 0.75);
// reference for the formula of heart: https://www.youtube.com/watch?v=aNR4n0i2ZlM
tv.y += absX * (Math.sqrt((20 - absX) / 15));
tv.z *= 0.5;
tv.x *= 1.2;
return tv;
});
geom.morphTargets.push({
name: "heart",
vertices: heart
});
var mesh = new THREE.Mesh(geom, new THREE.MeshLambertMaterial({
color: "red",
wireframe: false,
morphTargets: true,
transparent: true
}));
scene.add(mesh);
// tweenings
var tweenHeart = new TWEEN.Tween(mesh.morphTargetInfluences)
.to({
"0": 1
}, 1000)
.delay(500)
.yoyo(true)
.repeat(Infinity);
tweenHeart.start();
render();
function render() {
requestAnimationFrame(render);
TWEEN.update();
renderer.render(scene, camera);
}