HTML+JS实现的一个跳动的爱心。集合了web动画库GSAP JS、OBJ 文件加载器OBJLoader、WebGL第三方库Three.js等。效果非常棒!

目录

实际效果:目录结构:HTML代码CSS代码js代码:简单的修改完整文件下载

实际效果:

由于是纯前端项目,JS代码没有任何加密,所以赶快给心爱的人,做一个跳动的爱心吧!

目录结构:

HTML代码

爱心

CSS代码

* {

padding: 0;

margin: 0;

}

body {

background: #ff5555;

overflow: hidden;

margin: 0;

/* background-color: #000 !important; */

}

/**

* 主容器

*/

div#main {

width: 100vw;

height: 100vh;

}

/**

* 设置无限的动效

* 单次动效时间3s

*/

heart {

position: absolute;

width: 20px;

height: 20px;

color: #FFF;

text-align: center;

/* background: #e74c3c; */

font-size: 30px;

transform: rotate(360deg) scale(.6);

opacity: .5;

animation-name: opacity;

animation-duration: 3s;

animation-iteration-count: infinite;

}

/**

* 用伪类在heart content即是展示的文字效果

*/

heart::before {

position: absolute;

content: 'love-code';

width: 200px;

height: 20px;

/* background: #e74c3c; */

border-radius: 50%;

transform: translateX(-10px);

}

/**

*用伪类在heart

*/

heart::after {

position: absolute;

content: '';

width: 20px;

height: 20px;

/* background: #e74c3c; */

border-radius: 50%;

transform: translateY(-10px);

}

/**

* 改变透明度

*/

@keyframes opacity {

25%,

75% {

opacity: 1;

}

50%,

100% {

opacity: .5;

}

}

js代码:

gsap.min.js、OBJLoader.js、simplex-noise.js、three.min.js、TrackballControls.js 这几个JS都是现成的。 script.js代码:

console.clear();

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(

75,

window.innerWidth / window.innerHeight,

0.1,

1000

);

const renderer = new THREE.WebGLRenderer({

antialias: true

});

renderer.setClearColor(0xff5555);

renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

camera.position.z = 1;

const controls = new THREE.TrackballControls(camera, renderer.domElement);

controls.noPan = true;

controls.maxDistance = 3;

controls.minDistance = 0.7;

const group = new THREE.Group();

scene.add(group);

let heart = null;

let sampler = null;

let originHeart = null;

//new THREE.OBJLoader().load('./obj/heart_2.obj',obj => {

new THREE.OBJLoader().load('https://assets.codepen.io/127738/heart_2.obj',obj => {

heart = obj.children[0];

heart.geometry.rotateX(-Math.PI * 0.5);

heart.geometry.scale(0.04, 0.04, 0.04);

heart.geometry.translate(0, -0.4, 0);

group.add(heart);

heart.material = new THREE.MeshBasicMaterial({

color: 0xff5555

});

originHeart = Array.from(heart.geometry.attributes.position.array);

sampler = new THREE.MeshSurfaceSampler(heart).build();

init();

renderer.setAnimationLoop(render);

});

let positions = [];

const geometry = new THREE.BufferGeometry();

const material = new THREE.LineBasicMaterial({

color: 0xffffff

});

const lines = new THREE.LineSegments(geometry, material);

group.add(lines);

const simplex = new SimplexNoise();

const pos = new THREE.Vector3();

class Grass {

constructor () {

sampler.sample(pos);

this.pos = pos.clone();

this.scale = Math.random() * 0.01 + 0.001;

this.one = null;

this.two = null;

}

update (a) {

const noise = simplex.noise4D(this.pos.x*1.5, this.pos.y*1.5, this.pos.z*1.5, a * 0.0005) + 1;

this.one = this.pos.clone().multiplyScalar(1.01 + (noise * 0.15 * beat.a));

this.two = this.one.clone().add(this.one.clone().setLength(this.scale));

}

}

let spikes = [];

function init (a) {

positions = [];

for (let i = 0; i < 20000; i++) {

const g = new Grass();

spikes.push(g);

}

}

const beat = { a: 0 };

gsap.timeline({

repeat: -1,

repeatDelay: 0.3

}).to(beat, {

a: 1.2,

duration: 0.6,

ease: 'power2.in'

}).to(beat, {

a: 0.0,

duration: 0.6,

ease: 'power3.out'

});

gsap.to(group.rotation, {

y: Math.PI * 2,

duration: 12,

ease: 'none',

repeat: -1

});

function render(a) {

positions = [];

spikes.forEach(g => {

g.update(a);

positions.push(g.one.x, g.one.y, g.one.z);

positions.push(g.two.x, g.two.y, g.two.z);

});

geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(positions), 3));

const vs = heart.geometry.attributes.position.array;

for (let i = 0; i < vs.length; i+=3) {

const v = new THREE.Vector3(originHeart[i], originHeart[i+1], originHeart[i+2]);

const noise = simplex.noise4D(originHeart[i]*1.5, originHeart[i+1]*1.5, originHeart[i+2]*1.5, a * 0.0005) + 1;

v.multiplyScalar(1 + (noise * 0.15 * beat.a));

vs[i] = v.x;

vs[i+1] = v.y;

vs[i+2] = v.z;

}

heart.geometry.attributes.position.needsUpdate = true;

controls.update();

renderer.render(scene, camera);

}

window.addEventListener("resize", onWindowResize, false);

function onWindowResize() {

camera.aspect = window.innerWidth / window.innerHeight;

camera.updateProjectionMatrix();

renderer.setSize(window.innerWidth, window.innerHeight);

}

简单的修改

页面闪烁的love-code一共展现520个。可在index.html调整,大约在42行处love-code可以换成你想要的,可在css/style.css里修改,大约在43行处爱心是读取的网络的3dmax文件,你也可以修改为自己的3dmax文件,位置是js/script.js文件,大约在32行处。

完整文件下载

点击下方公众号卡片,关注我,回复爱心 下载!

相关文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。