JSFiddle - React, Tailwind, and code Playground
by Paul West
HTML
<script src="https://threejs.org/build/three.min.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(0, 0, 5);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var limit = 1.8;
var step = limit / 1000;
var points = [];
for (let i = -limit; i <= limit; i+=step){
points.push(new THREE.Vector3(i, 0, 0));
}
//console.log(points.length);
var geom = new THREE.BufferGeometry().setFromPoints(points);
var material = new THREE.ShaderMaterial({
uniforms:{
aVal: {value: 25}
},
vertexShader:`
#define PI 3.1415926
uniform float aVal;
float heart(float x, float a){
return pow(abs(x), 2. / 3.) + 0.9 * sqrt(3.3 - x * x) * sin(a * PI * x);
}
void main()
{
vec3 pos = position;
pos.y = heart(pos.x, aVal);
vec4 mvPosition = modelViewMatrix * vec4( pos, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
`,
fragmentShader:`
void main()
{
gl_FragColor = vec4( 1., 0., 0., 1.0 );
}
`
});
var heart = new THREE.Line(geom, material);
scene.add(heart);
var clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
material.uniforms.aVal.value = Math.sin(clock.getElapsedTime() * 0.5) * 25 + 25;
renderer.render(scene, camera);
})