HTML+JS实现的一个跳动的爱心。集合了web动画库GSAP JS
、OBJ 文件加载器OBJLoader
、WebGL第三方库Three.js
等。效果非常棒!
由于是纯前端项目,JS代码没有任何加密,所以赶快给心爱的人,做一个跳动的爱心吧!
爱心
* {
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;
}
}
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 {
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
下载方式:
扫描公众号二维码,或搜索公众号DotNet宝藏库
关注我,回复爱心
下载。
欢迎大家关注我的微信公众号,一起进步,一起成长
参与评论
手机查看
返回顶部