08.00. three.js我的开发笔记

自动播放模型动画

const mixer = new THREE.AnimationMixer(this);
this.animations.forEach(function (clip) {
    mixer.clipAction(clip).play();
});
clock = new THREE.Clock();
function update() {
    var delta = clock.getDelta();
    if (mixer) mixer.update(delta);
}

鼠标控制器

const orbitControls = new OrbitControls(camera, renderer.domElement);
orbitControls.target = new THREE.Vector3(0, 0.5, 0); //控制焦点
orbitControls.autoRotate = false; //将自动旋转关闭
function update() {
    if (orbitControls) orbitControls.update();
}

加载hdr环境图

const exrLoader = new EXRLoader();
exrLoader.crossOrigin = 'anonymous';
exrLoader.loadAsync("christmas_photo_studio_04_4k.exr", Progress).then((texture) => {
    texture.mapping = THREE.EquirectangularReflectionMapping;
    scene.background = texture;
    scene.environment = texture;
});

六面盒子贴图

let background = new THREE.CubeTextureLoader()
    .setPath('/360/background/tower/').load(
    [
        'pano_r.jpg',//右边
        'pano_l.jpg',//左边
        'pano_u.jpg',//顶部
        'pano_d.jpg',//地板
        'pano_f.jpg',//前面
        'pano_b.jpg'//后面
    ]
);
background.mapping = THREE.CubeRefractionMapping;
scene.background = background;
scene.environment = background;

创建可视射线

const arrowHelper = new THREE.ArrowHelper(direction, origin, 3, 0xff0000, 1, 0.1);
scene.add(arrowHelper)

创建文字屏幕

function addLEDScreen() {
    var canvas = document.createElement("canvas");
    canvas.width = 512;
    canvas.height = 64;
    var c = canvas.getContext('2d');
    c.fillStyle = "#aaaaff"; // 背景色
    c.fillRect(0, 0, 512, 64);
    c.beginPath();
    c.translate(256, 32);
    c.fillStyle = "#FF0000"; // 文本填充颜色
    c.font = "bold 28px 宋体"; // 字体样式设置
    c.textBaseline = "middle"; // 文本与fillText定义的纵坐标
    c.textAlign = "center"; // 文本居中(以fillText定义的横坐标)
    c.fillText("Three.js3D文字", 0, 0);
    var geometry = new THREE.PlaneGeometry(128, 32, 32);
    canvasTexture = new THREE.CanvasTexture(canvas);
    // 设置阵列模式
    canvasTexture.wrapS = THREE.RepeatWrapping;
    canvasTexture.wrapT = THREE.RepeatWrapping;
    // uv两个方向纹理重复数量
    canvasTexture.repeat.set(3, 3);
    var material = new THREE.MeshPhongMaterial({
        map: canvasTexture, // 设置纹理贴图
        side: THREE.DoubleSide
    });
    var cube = new THREE.Mesh(geometry, material);
    cube.rotation.copy(new THREE.Euler(0, Math.PI, 0));
    cube.position.copy(new THREE.Vector3(0, 18, 0));
    scene.add(cube);
}
addLEDScreen()

创建视频屏幕

function addVideoScreen() {
    let video = document.createElement('video');
    video.setAttribute("src", "https://stream7.iqilu.com/10339/upload_transcode/202002/17/20200217104524H4D6lmByOe.mp4"); // 设置视频地址
    video.setAttribute("autoplay", "autoplay");
    video.setAttribute("crossOrigin", "anonymous");
    video.setAttribute("webkit-playsinline", true);
    video.setAttribute("playsinline", true);
    video.muted = true;
    video.currentTime = 1;
    video.play();
    document.addEventListener("click", function () {
        if (video.muted) {
            video.currentTime = 1;
            video.muted = false;
        }
        video.play();
    })
    var geometry = new THREE.PlaneGeometry(360, 200, 32);
    canvasTexture = new THREE.VideoTexture(video);
    // 设置阵列模式
    canvasTexture.wrapS = THREE.RepeatWrapping;
    canvasTexture.wrapT = THREE.RepeatWrapping;
    // uv两个方向纹理重复数量
    canvasTexture.repeat.set(1, 1);
    canvasTexture.isVideoTexture = true;
    canvasTexture.needsUpdate = true;
    var material = new THREE.MeshPhongMaterial({
        map: canvasTexture, // 设置纹理贴图
        side: THREE.DoubleSide,
        emissive: 0xffffff,
        emissiveMap: canvasTexture
    });
    var cube = new THREE.Mesh(geometry, material);
    cube.rotation.copy(new THREE.Euler(0, 0, 0));
    cube.position.copy(new THREE.Vector3(0, 18, 0));
    scene.add(cube);
}
addVideoScreen()

已经存在的对象赋值素材

let video = document.createElement('video');
video.setAttribute("src", "https://stream7.iqilu.com/10339/upload_transcode/202002/17/20200217104524H4D6lmByOe.mp4"); // 设置视频地址
video.setAttribute("autoplay", "autoplay");
video.setAttribute("crossOrigin", "anonymous");
video.setAttribute("webkit-playsinline", true);
video.setAttribute("playsinline", true);
video.muted = true;
let zhou = true;
video.currentTime = 1;
video.play();
window.call_blackboard = () => {
    return scene.getObjectByName("移动黑板");
}
window.call_video = () => {
    return video;
}
window.videoFunction = typeof window.videoFunction == "undefined" ? function (e) {
    let video = window.call_video();
    let blackboard = window.call_blackboard();
    if (video.muted) {
        video.currentTime = 1;
        video.muted = false;
    }
    if (zhou) {
        new TWEEN.Tween(blackboard.position).to({
            z: -0.232
        }, 2000).easing(TWEEN.Easing.Elastic.InOut).start();
        zhou = false;
        video.muted = false;
    } else {
        new TWEEN.Tween(blackboard.position).to({
            z: 0
        }, 2000).easing(TWEEN.Easing.Elastic.InOut).start();
        zhou = true
        video.muted = true;
    }
    video.play();
} : window.videoFunction;
document.removeEventListener('click',
    videoFunction,
    false
);
document.addEventListener("click", videoFunction, false);
var geometry = new THREE.PlaneGeometry(360, 200, 32);
canvasTexture = new THREE.VideoTexture(video);
// 设置阵列模式
canvasTexture.wrapS = THREE.RepeatWrapping;
canvasTexture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
canvasTexture.repeat.set(1, 1);
canvasTexture.isVideoTexture = true;
canvasTexture.needsUpdate = true;
canvasTexture.center.set(0.5, 0.5); // 设置旋转中心
canvasTexture.rotation = THREE.MathUtils.degToRad(180); // 纹理对象旋转
canvasTexture.flipY = false;
var material = new THREE.MeshPhongMaterial({
    map: canvasTexture, // 设置纹理贴图
    emissive: 0xffffff,
    emissiveMap: canvasTexture
});
var LED = scene.getObjectByName("LED");
LED.material = material;

function update(event) {
    TWEEN.update();
}

加载外部场景或动画

const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
let mixer;
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.151.3/examples/jsm/libs/draco/');
dracoLoader.preload();
loader.setDRACOLoader(dracoLoader);
fetch('https://api.***.com/assets/***')
    .then(response => response.json())
    .then(data => {
    loader.requestHeader = { Authorization: `Bearer `+data.accessToken };
    loader.load(data.url, (gltf) => {
        gltf.scene.position.set(0,0,0)
        let axis = new THREE.Vector3(0,1,0);//向量axis
        gltf.scene.rotateOnAxis(axis,Math.PI/2);
        //绕axis轴逆旋转π/16
        gltf.scene.rotateOnAxis(axis,Math.PI/-20);
        gltf.scene.rotateOnAxis(axis,Math.PI/50);
        //gltf.rotateY(Math.PI / 2);
        gltf.scene.traverse(child => {
            if ( child.isMesh ) {
                child.castShadow = true;//产生阴影
                child.receiveShadow = true;//接收阴影
            }
        })
        scene.add(gltf.scene);
        renderer.render(scene, camera);
        mixer = new THREE.AnimationMixer(gltf.scene);
        gltf.animations.forEach(function (clip) {
            mixer.clipAction(clip).play();
        });
    }, Progress);
});
clock = new THREE.Clock();
function update() {
    var delta = clock.getDelta();
    if (mixer) mixer.update(delta);
}