在 vuejs里面如何使用 three.js 实现3d动画?

发布于 2022-09-06 04:13:18 字数 7187 浏览 12 评论 0

项目要求实现一种3d效果,网上找到了demo,但是是估计是 es5 实现的,在本地可以看到效果,但是现在需要放到 vue.js 里面去,整了一下午,各种错误。

我把three.js直接拷贝到项目里面,然后按如下方式引入:

  1. require('../../assets/home-animation/three.min.js')
  2. import THREE_ from '../../assets/home-animation/three.min.js'

或者 npm install three --save

都试过了,全部报错,报错方式如下:

图片描述

到底该如何把如下的 js 代码 “翻译” 到 vue 文件里面呢????????

原版js代码如下(精简版):

<!DOCTYPE html>
<html>

<head>
    <title>Points</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            background-color: #000000;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <p style="position: absolute;left: 0;right: 0;bottom: 0;text-align: center;">
        <button type="button" id="click_btn">星云控制</button>
    </p>
    <script src="three.min.js"></script>
    <script src="tween.min.js"></script>
    <script>
        var container;
        var camera, scene, renderer;
        var mouseX = 0, mouseY = 0;
        var mesh6;
        var particles2, geometry2, material2, i2, sprite;
        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;

        init();
        animate();

        function init() {

            container = document.createElement('div');
            document.body.appendChild(container);

            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 15000);
            camera.position.z = 9000;

            scene = new THREE.Scene();

            var material = new THREE.LineBasicMaterial({
                color: 0xffffff,
                linewidth: 1000
            });

            var x = 6000;
            var geometry = new THREE.Geometry();
            geometry.vertices.push(
                new THREE.Vector3(-x, 0, 0),
                new THREE.Vector3(0, Math.sqrt(3 * x * x), 0),
                new THREE.Vector3(x, 0, 0),
                new THREE.Vector3(-x, 0, 0)
            );

            var loader = new THREE.JSONLoader();
            loader.load('Sphere.json', handle_load6);
            function handle_load6(geometry, material) {
                var colors = [];
                for (var i = 0; i < geometry.vertices.length; i++) {
                    colors[i] = new THREE.Color(0x6870F5);
                    var hsl = colors[i].getHSL();
                    colors[i].setHSL(hsl.h + 0.05, Math.random() * 0.4 + 0.5, Math.random() * 0.3 + 0.5);
                }
                geometry.colors = colors;
                var material = new THREE.PointsMaterial({
                    size: 50,
                    opacity: 0.5,
                    map: THREE.ImageUtils.loadTexture('orb.png'),
                    transparent: true,
                    blending: THREE.AdditiveBlending,
                    depthWrite: false,
                    vertexColors: THREE.VertexColors
                });
                mesh6 = new THREE.Points(geometry, material);
            }
            {
                geometry2 = new THREE.Geometry();
                sprite = new THREE.TextureLoader().load("orb.png");
                for (i2 = 0; i2 < 400; i2++) {
                    var vertex = new THREE.Vector3();
                    vertex.x = 12000 * Math.random() - 6000;
                    vertex.y = 12000 * Math.random() - 6000;
                    vertex.z = 12000 * Math.random() - 6000;
                    geometry2.vertices.push(vertex);
                }
                material2 = new THREE.PointsMaterial({
                    size: 50,
                    opacity: 0.8,
                    sizeAttenuation: true,
                    map: sprite,
                    depthWrite: false,
                    transparent: true
                });
                material2.color.setHSL(1.0, 1, 1);
                particles2 = new THREE.Points(geometry2, material2);
                scene.add(particles2);
            }
            renderer = new THREE.WebGLRenderer({
                antialias: true
            });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            container.appendChild(renderer.domElement);
            document.addEventListener('mousemove', onDocumentMouseMove, false);
            window.addEventListener('resize', onWindowResize, false);
        }
        function onWindowResize() {
            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }
        function onDocumentMouseMove(event) {
            mouseX = event.clientX - windowHalfX;
            mouseY = 2 * event.clientY - 2 * windowHalfY;
        }
        var isMeTweening = false;
        var meshobj = null;
        function clickMeOk() {
            if (null == meshobj) {
                //解决load立即加载动画,改为点击按钮才加载动画
                meshobj = 'ok';
                scene.add(mesh6);//按钮控制,默认未加载,点击按钮后才执行(这句确保load完成后时候显示鲜果)                
                //初始化,未了避免加载就显示相应动画效果
                mesh6.scale.x = 0.0010000000000000009;
                mesh6.scale.y = 0.0010000000000000009;
                mesh6.scale.z = 0.0010000000000000009;
                mesh6.material.opacity = 0;
            }
            if (isMeTweening) return;
            isMeTweening = true;

            console.log('qqqq', mesh6.scale);//1 - 0.0010000000000000009
            var scale = mesh6.scale.x < 1 ? 1 : 0.0010000000000000009;
            console.log('eeee' + scale);//0.001 - 1

            new TWEEN.Tween(mesh6.scale).to({ x: scale, y: scale, z: scale }, 2000).easing(TWEEN.Easing.Quartic.InOut).onComplete(function () {
                isMeTweening = false;
            }).start();
            var opacity = mesh6.material.opacity > 0 ? 0 : 0.5;
            new TWEEN.Tween(mesh6.material).to({ opacity: opacity }, 1800).easing(TWEEN.Easing.Quartic.InOut).start();
        }
        window.onload = function () {
            document.getElementById('click_btn').addEventListener('click', clickMeOk)
        }
        function animate() {
            requestAnimationFrame(animate);
            render();
            TWEEN.update();
        }
        function render() {
            camera.position.x += (mouseX - camera.position.x) * 0.08;
            camera.position.y += (- mouseY - camera.position.y) * 0.08;
            camera.lookAt(scene.position);

            particles2.rotation.y += 0.0009;
            renderer.render(scene, camera);
        }
    </script>
</body>

</html>

到底该如何把如上的 js 代码 “翻译” 到 vue 文件里面呢????????

如果需要效果源码的请留言,谢谢大牛

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪冰清 2022-09-13 04:13:18

问题找到了,直接用 npm 安装这两个包,然后导入,方式如下:

    import * as THREE from "three";
    import * as TWEEN from "tween";
时间海 2022-09-13 04:13:18

我遇到其他类似的情况, 模块导入出错, 要用模块版的 three

无名指的心愿 2022-09-13 04:13:18

1.大兄弟,你的three.js是什么版本?
2.安装是npm install three还是 npm install three-js?
我安装是第二个 ,

 import * as THREE from "three-js";

控制台一直提示

a.PerspectiveCamera is not a constructor

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文