大家好,这里是 CSS 魔法使——alphardex。
以下是最终实现的效果图
撒,哈吉马路由!
准备工作
笔者的three.js模板:点击右下角的fork即可复制一份
世界同步
在我的上一篇博文中,讲到了如何将HTML世界和webgl的世界同步起来,本文也是同样的思路,先同步好两个世界,再进行特效创作
首先搭建HTML和JS
<div class="relative w-screen h-screen">
<div class="absolute w-screen h-screen flex-center opacity-0">
<img src="https://i.loli.net/2021/03/08/uYcvELkr4dqFj9w.jpg" class="w-60 cursor-pointer" alt="" crossorigin="anonymous" />
</div>
<div class="particle-explode w-full h-full bg-black"></div>
</div>
复制代码
class ParticleExplode extends Base {
// 初始化
async init() {
this.createScene();
this.createPerspectiveCamera();
this.createRenderer();
this.createParticleExplodeMaterial();
await preloadImages();
this.createPoints();
this.createClickEffect();
this.createLight();
this.trackMousePos();
this.createOrbitControls();
this.addListeners();
this.setLoop();
}
}
const start = () => {
const particleExplode = new ParticleExplode(".particle-explode", true);
particleExplode.init();
};
start();
复制代码
单位同步
class ParticleExplode extends Base {
constructor(sel: string, debug: boolean) {
...
this.cameraPosition = new THREE.Vector3(0, 0, 1500);
const fov = this.getScreenFov();
this.perspectiveCameraParams = {
fov,
near: 0.1,
far: 5000
};
}
// 获取跟屏幕同像素的fov角度
getScreenFov() {
return ky.rad2deg(
2 * Math.atan(window.innerHeight / 2 / this.cameraPosition.z)
);
}
}
复制代码
预加载图片
import imagesLoaded from "https://cdn.skypack.dev/imagesloaded@4.1.4";
const preloadImages = (sel = "img") => {
return new Promise((resolve) => {
imagesLoaded(sel, { background: true }, resolve);