threejs实现三维泡泡球聚集碰撞物理动画效果代码
代码语言:html
所属分类:三维
代码描述:threejs实现三维泡泡球聚集碰撞物理动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://cdn.jsdelivr.net/gh/alphardex/aqua.css/dist/aqua.min.css'>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
:root {
--white-grad-1: linear-gradient(to top, #e6e9f0 0%, #eef1f5 100%);
}
.bg-white-grad-1 {
background: var(--white-grad-1);
}
</style>
</head>
<body>
<div class="relative w-screen h-screen">
<div class="bouncy-balloon w-full h-full bg-black bg-white-grad-1"></div>
</div>
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.124.0";
import ky from "https://cdn.skypack.dev/kyouka@1.2.5";
import {
OrbitControls
} from "https://cdn.skypack.dev/three@0.124.0/examples/jsm/controls/OrbitControls";
import {
GLTFLoader
} from "https://cdn.skypack.dev/three@0.124.0/examples/jsm/loaders/GLTFLoader";
import {
FBXLoader
} from "https://cdn.skypack.dev/three@0.124.0/examples/jsm/loaders/FBXLoader";
import Stats from "https://cdn.skypack.dev/three@0.124.0/examples/jsm/libs/stats.module";
import * as CANNON from "https://cdn.skypack.dev/cannon-es@0.18.0";
import {
EffectComposer,
RenderPass,
NormalPass,
SSAOEffect,
EffectPass
} from "https://cdn.skypack.dev/postprocessing@6.22.2";
const calcAspect = (el) => el.clientWidth / el.clientHeight;
const getNormalizedMousePos = (e) => {
return {
x: (e.clientX / window.innerWidth) * 2 - 1,
y: -(e.clientY / window.innerHeight) * 2 + 1
};
};
// 三维点
class Point {
constructor(p) {
this.x = p.x;
this.y = p.y;
this.z = p.z;
}
}
// 数组转化为点
const array2Point = (arr) => new Point({
x: arr[0], y: arr[1], z: arr[2]
});
// 点转化为数组
const point2Array = (point) => [point.x, point.y, point.z];
// 多个数组转化为多个点
const arrays2Point = (arrs) => arrs.map((item) => array2Point(item));
// 点转化为Three.js的向量
const point2ThreeVector = (point) => new THREE.Vector3(point.x, point.y, point.z);
// 点转化为Cannon.js的向量
const point2CannonVec = (point) => new CANNON.Vec3(point.x, point.y, point.z);
class MeshPhysicsObject {
constructor(mesh, body, copyPosition = true, copyQuaternion = true) {
this.mesh = mesh;
this.body = body;
this.copyPosition = copyPosition;
this.copyQuaternion = copyQuaternion;
}
}
class Base {
constructor(sel, debug = false) {
this.debug = debug;
this.container = document.querySelector(sel);
this.perspectiveCameraParams = {
fov: 75,
near: 0.1,
far: 100
};
this.orthographicCameraParams = {
zoom: 2,
near: -100,
far: 1000
};
this.cameraPosition = new THREE.Vector3(0, 3, 10);
this.lookAtPosition = new THREE.Vector3(0, 0, 0);
this.rendererParams = {
outputEncoding: THREE.LinearEncoding,
config: {
alpha: true,
antialias: true
}
};
this.mousePos = new THREE.Vector2(0, 0);
this.mouseSpeed = 0;
}
// 初始化
init() {
this.createScene();
this.createPerspectiveCamera();
this.createRenderer();
this.createMesh({});
this.createLight();
this.createOrbitControls();
this.addListeners();
this.setLoop();
}
// 创建场景
createScene() {
const scene = new THREE.Scene();
if (this.debug) {
scene.add(new THREE.AxesHelper());
const stats = Stats();
this.container.appendChild(stats.dom);
this.stats = stats;
}
this.scene = scene;
}
// 创建透视相机
createPerspectiveCamera() {
const {
perspectiveCameraParams,
cameraPosition,
lookAtPosition
} = this;
const {
fov,
near,
far
} = perspectiveCameraParams;
const aspect = calcAspect(this.container);
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.copy(cameraPosition);
camera.lookAt(lookAtPosition);
this.camera = camera;
}
// 创建正交相机
createOrthographicCamera() {
const {
orthographicCameraParams,
cameraPosition,
lookAtPosition
} = this;
const {
left,
right,
top,
bottom,
near,
far
} = orthographicCameraParams;
const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
camera.position.copy(cameraPosition);
camera.lookAt(lookAtPosition);
this.camera = camera;
}
// 更新正交相机参数
updateOrthographicCameraParams() {
const {
container
} = this;
const {
zoom,
near,
far
} = this.orthographicCameraParams;
const aspect = calcAspect(container);
this.orthographicCameraParams = {
left: -zoom * aspect,
right: zoom * aspect,
top: zoom,
bottom: -zoom,
near,
far,
zoom
};
}
// 创建渲染
createRenderer(useWebGL1 = false) {
var _a;
const {
rendererParams
} = this;
const {
outputEncoding,
config
} = rendererParams;
const renderer = !useWebGL1
? new THREE.WebGLRenderer(config): new THREE.WebGL1Renderer(config);
renderer.setSize(this.container.clientWidth, this.container.clientHeight);
renderer.outputEncoding = outputEncoding;
this.resizeRendererToDisplaySize();
(_a = this.container) === null || _a === void 0 ? void 0: _a.appendChild(renderer.domElement);
this.renderer = renderer;
this.renderer.setClearColor(0x000000, 0);
}
// 允许投影
enableShadow() {
this.renderer.shadowMap.enabled = true;
}
// 调整渲染器尺寸
resizeRendererToDisplaySize() {
const {
renderer
} = this;
if (!renderer) {
return;
}
const canvas = renderer.domElement;
const pixelRatio = window.devicePixelRatio;
const {
clientWidth,
clientHeight
} = canvas;
const width = (clientWidth * pixelRatio) | 0;
const height = (clientHeight * pixelRatio) | 0;
const isResizeNeeded = canvas.width !== width || canvas.height !== height;
if (isResizeNeeded) {
renderer.setSize(width, height, false);
}
return isResizeNeeded;
}
// 创建网格
createMesh(meshObject, container = this.scene) {
const {
geometry = new THREE.BoxGeometry(1, 1, 1),
material = new THREE.MeshStandardMaterial({
color: new THREE.Color("#d9dfc8")
}),
position = new THREE.Vector3(0, 0, 0)
} = meshObject;
const mesh = new THREE.Mesh(geometry, material);
mesh.position.copy(position);
container.add(mesh);
return mesh;
}
// 创建光源
createLight() {
const dirLight = new THREE.DirectionalLight(new THREE.Color("#ffffff"), 0.5);
dirLight.position.set(0, 50, 0);
this.scene.add(dirLight);
const ambiLight = new THREE.AmbientLight(new THREE.Color("#ffffff"), 0.4);
this.scene.add(ambiLight);
}
// 创建轨道控制
createOrbitControls() {
const controls = new OrbitControls(this.camera, this.renderer.domElement);
const {
lookAtPosition
} = this;
controls.target.copy(lookAtPosition);
controls.update();
this.controls = controls;
}
// 监听事件
addListeners() {
this.onResize();
}
// 监听画面缩放
onResize() {
window.addEventListener("resize", (e) => {
if (this.shaderMaterial) {
this.shaderMaterial.uniforms.uResolution.value.x = window.innerWidth;
this.shaderMaterial.uniforms.uResolution.value.y = window.innerHeight;
this.renderer.setSize(window.innerWidth, window.innerHeight);
} else {
if (this.camera instanceof THREE.PerspectiveCamera) {
const aspect = calcAspect(this.container);
const camera = this.camera;
camera.aspect = aspect;
camera.updateProjectionMatrix();
} else if (this.camera instanceof THREE.OrthographicCamera) {
this..........完整代码请登录后点击上方下载按钮下载查看
网友评论0