THREE.AudioLoader 是 three.js 库中的一个类,用于异步加载音频文件。three.js 是一个流行的 JavaScript 库,用于在网页上创建和显示 3D 图形。

demo案例
在这里插入图片描述

THREE.AudioLoaderthree.js 库中的一个类,用于异步加载音频文件。three.js 是一个流行的 JavaScript 库,用于在网页上创建和显示 3D 图形。以下是关于 THREE.AudioLoader 的一些基本用法和属性:

入参 (Input Parameters):

  • manager (可选): 一个 THREE.LoadingManager 实例,用于管理加载状态和资源。

出参 (Output):

THREE.AudioLoader 本身并不直接返回加载的音频数据。相反,它通常与 load 方法的回调函数一起使用,该回调函数会在音频加载完成后被调用。

方法 (Methods):

  • load(url, onLoad, onProgress, onError): 加载音频文件。
    • url: 音频文件的 URL 或路径。
    • onLoad: 音频加载完成时的回调函数,通常接收一个 Audio 实例作为参数。
    • onProgress: (可选) 加载进度更新时的回调函数,通常接收加载进度(0 到 1 之间)作为参数。
    • onError: (可选) 加载错误时的回调函数,通常接收错误对象作为参数。

属性 (Properties):

THREE.AudioLoader 本身并没有很多直接暴露给用户的属性。它主要通过方法和回调函数来与用户交互。但是,你可以通过 load 方法的 onLoad 回调函数来访问加载后的 Audio 实例,该实例具有音频文件的相关属性和方法。

例如:

var audioLoader = new THREE.AudioLoader();

audioLoader.load(
  'path/to/audio.mp3',
  function(audio) {
    // 音频加载完成,可以在这里操作 audio 实例
    audio.play(); // 播放音频
  },
  function(xhr) {
    // 加载进度更新,可以在这里获取进度信息
    console.log((xhr.loaded / xhr.total * 100) + '% loaded');
  },
  function(error) {
    // 加载出错,可以在这里处理错误
    console.error('An error happened', error);
  }
);

在上面的例子中,audio 是一个 Audio 实例,你可以调用它的方法(如 playpausesetVolume 等)来控制音频的播放。

demo 源码

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webaudio - timing</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>

<div id="overlay">
    <button id="startButton">Play</button>
</div>
<div id="container"></div>
<div id="info">
    <a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> webaudio - timing<br/>
    sound effect by <a href="https://freesound.org/people/michorvath/sounds/269718/" target="_blank" rel="noopener noreferrer">michorvath</a>
</div>

<script type="importmap">
    {
        "imports": {
            "three": "../build/three.module.js",
            "three/addons/": "./jsm/"
        }
    }
</script>

<script type="module">
    // 导入所需的模块
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

    // 定义全局变量
    let scene, camera, renderer, clock;
    const objects = [];
    const speed = 2.5;
    const height = 3;
    const offset = 0.5;

    // 获取开始按钮并添加点击事件监听器
    const startButton = document.getElementById('startButton');
    startButton.addEventListener('click', init);

    // 初始化函数
    function init() {
        const overlay = document.getElementById('overlay');
        overlay.remove();
        const container = document.getElementById('container');

        // 创建场景和时钟
        scene = new THREE.Scene();
        clock = new THREE.Clock();

        // 创建相机
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
        camera.position.set(7, 3, 7);

        // 添加灯光
        const ambientLight = new THREE.AmbientLight(0xcccccc);
        scene.add(ambientLight);
        const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5);
        directionalLight.position.set(0, 5, 5);
        scene.add(directionalLight);
        directionalLight.castShadow = true;
        directionalLight.shadow.camera.left = -5;
        directionalLight.shadow.camera.right = 5;
        directionalLight.shadow.camera.top = 5;
        directionalLight.shadow.camera.bottom = -5;
        directionalLight.shadow.camera.near = 1;
        directionalLight.shadow.camera.far = 20;
        directionalLight.shadow.mapSize.x = 1024;
        directionalLight.shadow.mapSize.y = 1024;

        // 加载音频文件并创建球体
        const audioLoader = new THREE.AudioLoader();
        const listener = new THREE.AudioListener();
        camera.add(listener);
        const floorGeometry = new THREE.PlaneGeometry(10, 10);
        const floorMaterial = new THREE.MeshLambertMaterial({ color: 0x4676b6 });
        const floor = new THREE.Mesh(floorGeometry, floorMaterial);
        floor.rotation.x = Math.PI * -0.5;
        floor.receiveShadow = true;
        scene.add(floor);
        const ballGeometry = new THREE.SphereGeometry(0.3, 32, 16);
        ballGeometry.translate(0, 0.3, 0);
        const ballMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc });

        audioLoader.load('sounds/ping_pong.mp3', function (buffer) {
            for (let i = 0; i < 5; i++) {
                const s = i / 5 * Math.PI * 2;
                const ball = new THREE.Mesh(ballGeometry, ballMaterial);
                ball.castShadow = true;
                ball.userData.down = false;
                ball.position.x = 3 * Math.cos(s);
                ball.position.z = 3 * Math.sin(s);
                const audio = new THREE.PositionalAudio(listener);
                audio.setBuffer(buffer);
                ball.add(audio);
                scene.add(ball);
                objects.push(ball);
            }
            animate();
        });

        // 创建渲染器和控制器
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMap.enabled = true;
        container.appendChild(renderer.domElement);
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.minDistance = 1;
        controls.maxDistance = 25;

        // 监听窗口大小变化
        window.addEventListener('resize', onWindowResize);
    }

    // 窗口大小变化时更新相机和渲染器尺寸
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    // 动画循环
    function animate() {
        requestAnimationFrame(animate);
        render();
    }

    // 渲染函数
    function render() {
        const time = clock.getElapsedTime();
        for (let i = 0; i < objects.length; i++) {
            const ball = objects[i];
            const previousHeight = ball.position.y;
            ball.position.y = Math.abs(Math.sin(i * offset + (time * speed)) * height);
            if (ball.position.y < previousHeight) {
                ball.userData.down = true;
            } else {
                if (ball.userData.down === true) {
                    const audio = ball.children[0];
                    audio.play();
                    ball.userData.down = false;
                }
            }
        }
        renderer.render(scene, camera);
    }
</script>

</body>
</html>

本内容来源于小豆包,想要更多内容请跳转小豆包 》

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值