目录
- 1、渐变线
- 2、导入字体
- 3、定义几何体
- 4、tween补间动画
- 5、Sprite 粒子(精灵材质)
- 6、Sprite 粒子(精灵材质)---下雪
- 7、通过几何体创建点云
- 8、使用环境贴图创建虚假的反光效果
- 9、通过 Reflector 创建反光镜
- 10、背景用background-image设置
- 11、使用videoTexture用视频作为输出纹理
- 12、纹理offset偏移
- 13、形状缓冲几何体
- 14、自定义形状(墙)
- 15、光圈动画
- 16、water.js
- 17、第一视角WSAD按键控制前后左右
- 18、爆炸和还原效果
- 19、扩散波
- 20、点击发光
- 21、物体自发光
- 22、旋转棱锥
- 23、雷达扫描
- 24、信号波
- 25、渐变墙
- 26、太阳光晕
- 27、直线流光
- 28、框选
- 29、点选
- 30、添加标签
1、渐变线
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from '/three.js-r123/build/three.module.js';
import {
OrbitControls } from '/three.js-r123/examples/jsm/controls/OrbitControls.js';
// 现在浏览器支持ES6语法,自然包括import方式引入js文件
// 引入Three.js扩展库
// 引入线宽设置相关库
import {
LineGeometry } from '/three.js-r123/examples/jsm/lines/LineGeometry.js';
import {
LineMaterial } from '/three.js-r123/examples/jsm/lines/LineMaterial.js';
import {
Line2 } from '/three.js-r123/examples/jsm/lines/Line2.js';
function createLine() {
var geometry = new THREE.BufferGeometry(); //创建一个缓冲类型几何体
// 三维样条曲线
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(100, 0, -100),
new THREE.Vector3(0, 80, 0),
new THREE.Vector3(-100, 0, 100),
]);
var points = curve.getSpacedPoints(100); //分段数100,返回101个顶点
geometry.setFromPoints(points);
var material = new THREE.LineBasicMaterial({
color: 0x006666, //轨迹颜色
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line);
var index = 20; //取点索引位置
var num = 10; //从曲线上获取点数量
var points2 = points.slice(index, index + num); //从曲线上获取一段
var geometry2 = new LineGeometry();
var pointArr = []
points2.forEach(function (v3) {
pointArr.push(v3.x, v3.y, v3.z)
})
var material2 = new LineMaterial({
linewidth: 1, // 设置线宽
color: 0x7FE716
});
material2.resolution.set(window.innerWidth, window.innerHeight);
var line2 = new Line2(geometry2, material2);
scene.add(line2);
var indexMax = points.length - num;
function render() {
if (index > indexMax) index = 0;
index += 1
points2 = points.slice(index, index + num); //从曲线上获取一段
// geometry2.setFromPoints(points2);
var pointArr = []
//把圆弧曲线返回的顶点坐标Vector3中xyz坐标提取到pointArr数组中
points2.forEach(function (v3) {
pointArr.push(v3.x, v3.y, v3.z)
})
// 设置几何体顶点位置坐标
geometry2.setPositions(pointArr);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
}
</script>
</body>
</html>
简易版
let camera, scene, renderer, clock, controls, curve, boxMesh, points
let stats;
let step = 0
init();
animate();
function init() {
clock = new THREE.Clock();
const container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 5000);
camera.position.set(0, 100, 100);
scene = new THREE.Scene();
scene.background = new THREE.Color("#87CEFA")
// ------------------------------------------------------------------------------------mesh
curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-100, 0, 100),
new THREE.Vector3(-50, 50, 50),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(50, -50, 50),
new THREE.Vector3(100, 0, 100)
]);
points = curve.getPoints(500);
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({
color: 0xff0000 });
const curveObject = new THREE.Line(geometry, material);
// curveObject.visible = false
scene.add(curveObject)
const boxGeometry = new THREE.BoxGeometry(10, 10, 10)
const boxMaterial = new THREE.MeshBasicMaterial({
color: 0x00cc00
})
boxMesh = new THREE.Mesh(boxGeometry, boxMaterial)
scene.add(boxMesh)
// ------------------------------------------------------------------------------------
var hemisphereLight = new THREE.HemisphereLight(0x808080, 0x606060)
scene.add(hemisphereLight);
var ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
renderer = new THREE.WebGLRenderer({
antialias: true, alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
// renderer.outputEncoding = THREE.sRGBEncoding;
renderer.shadowMap.enabled = true;
controls = new OrbitControls(camera, renderer.domElement);
controls.dampingFactor = true
stats = new Stats();
container.appendChild(stats.dom);
var axes = new THREE.AxesHelper(20);
scene.add(axes);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
step += 1;
if (step >= points.length) {
step = 0
}
points[step].x && points[step].y && points[step].z && boxMesh.position.set(points[step].x, points[step].y, points[step].z)
controls.update()
requestAnimationFrame(animate);
render();
stats.update();
}
function render() {
renderer.render(scene, camera);
}
window.addEventListener('resize', onWindowResize);
2、导入字体
加载文字,可放大缩小
function initContent() {
var text = "three.js"
var loader = new FontLoader();
loader.load('./js/gentilis_regular.typeface.json', function (font) {
var fontMaterial = new THREE.MeshLambertMaterial({
color: 0x912CEE,
side: THREE.DoubleSide
});
var shapes = font.generateShapes(text, 10, 1);
var fontGeometry = new THREE.ShapeGeometry(shapes);
fontGeometry.computeBoundingBox();
var font = new THREE.Mesh(fontGeometry, fontMaterial);
font.position.x = -1 - fontGeometry.boundingBox.max.x / 2;
font.position.y = 1 - fontGeometry.boundingBox.max.y / 2;
scene.add(font);
})
}
或者
function createFont (text, options={
bgColor: '', fontColor: ''}) {
var canvas = document.createElement("canvas");
canvas.width = 512;
canvas.height = 128;
var c = canvas.getContext('2d');
// 矩形区域填充背景
c.fillStyle = options.bgColor || '#ff0000';
c.fillRect(0, 0, 512, 128);
c.beginPath();
// 文字
c.beginPath();
c.translate(256,64);
c.fillStyle = options.fontColor || '#ffffff'; //文本填充颜色
c.font = 'bold 36px 微软雅黑'; //字体样式设置
c.textBaseline = 'middle'; //文本与fillText定义的纵坐标
c.textAlign = 'center'; //文本居中(以fillText定义的横坐标)
c.fillText(text, 0, 0);
var texture = new THREE.CanvasTexture(canvas);
var textMaterial = new THREE.MeshPhongMaterial({
map: texture, // 设置纹理贴图
// side: THREE.DoubleSide,
transparent: true,
opacity: 0.9
});
textMaterial.map.needsUpdate = true
return textMaterial
}
3、定义几何体
<script src="../../libs/examples/js/utils/SceneUtils.js"></script>
function initContent() {
let vertices = [
new THREE.Vector3(1, 3, 1),
new THREE.Vector3(1, 3, -1),
new THREE.Vector3(1, -1, 1),
new THREE.Vector3(1, -1, -1),
new THREE.Vector3(-1, 3, -1),
new THREE.Vector3(-1, 3, 1),
new THREE.Vector3(-1, -1, -1),
new THREE.Vector3(-1, -1, 1)
];
let faces = [
new THREE.Face3(0, 2, 1),
new THREE.Face3(2, 3, 1),
new THREE.Face3(4, 6, 5),
new THREE.Face3(6, 7, 5),
new THREE.Face3(4, 5, 1),
new THREE.Face3(5, 0, 1),
new THREE.Face3(7, 6, 2),
new THREE.Face3(6, 3, 2),
new THREE.Face3(5, 7, 0),
new THREE.Face3(7, 2, 0),
new THREE.Face3(1, 3, 4),
new THREE.Face3(3, 6, 4)
];
let geometry = new THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeFaceNormals();
let materials = [
new THREE.MeshLambertMaterial({
transparent : true, opacity : 0.6, color : 0x9F79EE}),
new THREE.MeshBasicMaterial({
color : 0x000, wireframe : true})
];
// 使用SceneUtils创建多材质对象
let mesh = new THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
mesh.scale.set(50, 50, 50);
scene.add(mesh);
}
4、tween补间动画
// <script src="js/Tween.js"></script>
function AddTween() {
tween = new TWEEN.Tween(camera.position);
tween.to({
x:500, y:200, z:100}, 5000);
tween.easing(TWEEN.Easing.Linear.None);
var tweenBack = new TWEEN.Tween(camera.position).to({
x:100, y:200, z:100}, 5000);
tweenBack.easing(TWEEN.Easing.Linear.None);
tween.chain(tweenBack);
tweenBack.chain(tween);
tween.start();
tween.onUpdate(function () {
console.log(this.x);
})
}
function update() {
TWEEN.update();
stats.update();
controls.update();
}
tweenjs的使用
//引入tweenjs
<script src="./js/tween.min.js"></script>
tween = new TWEEN.Tween({
})
console.log(tween);//能打印出来说明引入成功
动画运动算法(缓动函数)easing函数
- Linear ==> 线性匀速运动效果
- Quadratic ==> 二次方的缓动(t^2)
- Cubic ==> 三次方的缓动()
- Quartic ==> 四次方的缓动()
- Quintic ==> 五次方的缓动
- Sinusoidal ==> 正弦曲线的缓动()
- Exponential ==> 指数曲线的缓动()
- Circular ==> 圆形曲线的缓动()
- Elastic ==> 指数衰减的正弦曲线缓动()
- Back ==> 超过范围的三次方的缓动
- Bounce ==> 指数衰减的反弹缓动
缓动方式(效果)easing类型
- easeIn(In) ==> 加速,先慢后快
- easeOut(Out) ==> 减速,先快后慢
- easeInOut(InOut) ==> 前半段加速,后半段减速
使用公式
.easing(TWEEN.Easing.easing函数.easing类型)
tween = new TWEEN.Tween(camera.position);
tween.to({
x: 100, y: 200, z: 100 }, 2000);//从起始值改变到{ x: 100, y: 200, z: 100 },2秒时间
tween.easing(TWEEN.Easing.Linear.None);
var tweenBack = new TWEEN.Tween(camera.position).to({
x: 0, y: 100, z: 100 }, 2000);//从上个位置回到{ x: 0, y: 100, z: 100 },2秒时间
tweenBack.easing(TWEEN.Easing.Linear.None);
tween.chain(tweenBack);//tween结束执行tweenBack
tweenBack.chain(tween);//tweenBack结束执行tween
tween.start();//激活动画:
// tween.delay(1000);//第二次补间动画延迟1秒
// tween.repeat(2); // tween动画先执行2次,tween.repeat(Infinity); // repeats forever
tween.onUpdate(function () {
})
常用先快后慢
tween.easing(TWEEN.Easing.Quadratic.InOut);
github地址:https://github.com/tweenjs/tween.js
5、Sprite 粒子(精灵材质)
function initContent() {
/* 创建粒子 */
let spriteMaterial = new THREE.SpriteMaterial({
color: 0x9A32CD});
for (let x = -5; x < 5; x++ ) {
for (let y = -5; y < 5; y++ ) {
let sprite = new THREE.Sprite(spriteMaterial);/* Sprite 默认的材质是 SpriteMaterial */
sprite.position.set(x * 10, y * 10, 0);
scene.add(sprite);
}
}
}
6、Sprite 粒子(精灵材质)—下雪
function initContent() {
/* 雪花图片 */
let texture =