【问题标题】:How to use Three JS with Angular 7如何在 Angular 7 中使用三个 JS
【发布时间】:2020-12-23 11:14:55
【问题描述】:

我正在使用 Angular 7,我想在我的项目中添加三个 JS Thee JS,但结果证明它并不是很有效。我不确定我做对了。请帮帮我

这是我的代码

    ngAfterViewInit(): void {
    let script = this._renderer2.createElement('script');
    script.type = `text/javascript`;
    script.text = `
    {

        $(document).ready(function () {
          var SEPARATION = 100, AMOUNTX = 50, AMOUNTY = 50;


    var container, stats;
    var camera, scene, renderer;

    var particles, count = 0;

    var mouseX = 0, mouseY = 0;

    var windowHalfX = window.innerWidth / 2;
    var windowHalfY = window.innerHeight / 2;
    mouseX = 635 - windowHalfX;
    mouseY = 27 - windowHalfY;

    init();
    animate();

    function init() {

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

        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;

        scene = new THREE.Scene();

        //

        var numParticles = AMOUNTX * AMOUNTY;

        var positions = new Float32Array(numParticles * 3);
        var scales = new Float32Array(numParticles);

        var i = 0, j = 0;

        for (var ix = 0; ix < AMOUNTX; ix++) {

            for (var iy = 0; iy < AMOUNTY; iy++) {

                positions[i] = ix * SEPARATION - ((AMOUNTX * SEPARATION) / 2); // x
                positions[i + 1] = 0; // y
                positions[i + 2] = iy * SEPARATION - ((AMOUNTY * SEPARATION) / 2); // z

                scales[j] = 1;

                i += 3;
                j++;

            }

        }

        var geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
        geometry.setAttribute('scale', new THREE.BufferAttribute(scales, 1));

        var material = new THREE.ShaderMaterial({

            uniforms: {
                color: { value: new THREE.Color(0xffffff) },
            },
            vertexShader: document.getElementById('vertexshader').textContent,
            fragmentShader: document.getElementById('fragmentshader').textContent

        });

        //

        particles = new THREE.Points(geometry, material);
        scene.add(particles);

        //

        renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        //renderer = new THREE.CanvasRenderer({alpha: true});
        renderer.setClearColor(0x83d3ec, 0);
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        container.appendChild(renderer.domElement);

        stats = new Stats();
        container.appendChild(stats.dom);

        document.addEventListener('mousemove', onDocumentMouseMove, false);
        document.addEventListener('touchstart', onDocumentTouchStart, false);
        document.addEventListener('touchmove', onDocumentTouchMove, 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 = event.clientY - windowHalfY;

    }

    function onDocumentTouchStart(event) {

        if (event.touches.length === 1) {

            event.preventDefault();

            mouseX = event.touches[0].pageX - windowHalfX;
            //mouseY = event.touches[0].pageY - windowHalfY;

        }

    }

    function onDocumentTouchMove(event) {

        if (event.touches.length === 1) {

            event.preventDefault();

            mouseX = event.touches[0].pageX - windowHalfX;
            //mouseY = event.touches[0].pageY - windowHalfY;

        }

    }

    //

    function animate() {

        requestAnimationFrame(animate);

        render();
        stats.update();

    }

    function render() {

        camera.position.x += (mouseX - camera.position.x) * .05;
        camera.position.y += (- mouseY - camera.position.y) * .05;
        camera.lookAt(scene.position);

        var positions = particles.geometry.attributes.position.array;
        var scales = particles.geometry.attributes.scale.array;

        var i = 0, j = 0;

        for (var ix = 0; ix < AMOUNTX; ix++) {

            for (var iy = 0; iy < AMOUNTY; iy++) {

                positions[i + 1] = (Math.sin((ix + count) * 0.3) * 50) +
                    (Math.sin((iy + count) * 0.5) * 50);

                scales[j] = (Math.sin((ix + count) * 0.3) + 1) * 8 +
                    (Math.sin((iy + count) * 0.5) + 1) * 8;

                i += 3;
                j++;

            }

        }

        particles.geometry.attributes.position.needsUpdate = true;
        particles.geometry.attributes.scale.needsUpdate = true;

        renderer.render(scene, camera);

        count += 0.1;

       }

        });
       }
     `;
     this._renderer2.appendChild(this._document.body, script);
    }

我已经导入了所需的模块,但仍然无法正常工作,并且显示“三个不是函数”之类的错误。

【问题讨论】:

  • 这是一个相当广泛的问题,但这里的方法完全不可行。你只想安装这三个库和它的类型并正常导入并使用它。使用 Angular 提供的工具来做这些事情,使用 ViewChild 来获取容器,宿主监听器来做事件,等等。如果你发现自己在 Angular 组件中构建脚本标签,那你就错了

标签: javascript angular three.js


【解决方案1】:

首先使用npm安装three.js

npm i three

然后在组件中像下面这样导入它

import * as THREE from 'three';

现在您可以像下面的代码一样从您的组件中使用它。注意:这只是举例

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

var animate = function () {
  requestAnimationFrame( animate );

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  renderer.render( scene, camera );
};

animate();

在 package.json 文件中将 typescript 更新到最新版本 (3.7.2)

"devDependencies": {
    ...
    "typescript": "3.7.2"
  }

由于您在 tsconfig.json 文件中使用 Angular 7,请禁用 TypeScript 版本检查。如果您使用的是最新的 Angular 版本,则无需执行此操作。

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  },
   "angularCompilerOptions": {
    "disableTypeScriptVersionCheck": true,
  }
 }

工作DEMO is here

【讨论】:

  • 当我尝试像您的示例那样做时,它不起作用并在 vs 代码终端中显示错误提示 node_modules/three/src/core/BufferAttribute.d.ts(21, 6):错误 TS1086:无法在环境上下文中声明访问器。 node_modules/three/src/renderers/WebGLRenderer.d.ts(35,31):错误 TS2304:找不到名称“OffscreenCanvas”。 node_modules/three/src/renderers/webgl/WebGLAttributes.d.ts(6,43):错误 TS2304:找不到名称“WebGL2RenderingContext”。 node_modules/three/src/renderers/webgl/WebGLUtils.d.ts(3,43):错误 TS2304:找不到名称“WebGL2RenderingContext”
  • 您的 tsconfig.json 文件应如下所示 { "compileOnSave": false, "compilerOptions": { "baseUrl": "./", "outDir": "./dist/out-tsc", "sourceMap": true, "declaration": false, "module": "es2015", "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", "typeRoots": [ "node_modules/@types" ], "lib": [ "es2018", "dom" ] } } ?
  • 没错就是这样
  • 必须将 typescript 更新为 "typescript": "3.7.2" 并在 tsconfig.json 中添加这一行 "angularCompilerOptions": { "disableTypeScriptVersionCheck": true, }
  • 我正在使用 Angular 9 并且正在工作,新项目复制粘贴到构造函数上,一切正常。 但是我会使用 ngAfterViewInit 钩子和不直接添加到正文的组件来使用更 Angular 的方式。 BUT 就问题而言是 100% 有效的!谢谢!!!
【解决方案2】:

如果没有必要在angular组件中包含threejs。您可以在下面的 index.html 中包含 threejs 脚本 代码演示在这里ThreeJS Angular Demo

    <body>
      <app-root></app-root>
      <script src="https://threejs.org/build/three.js"></script>
      <script>
         <!--  Your threejs script that creates and animates the scene --->
         <!--  Note: skip the import threejs module import statement --->

        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera( 75, 
        window.innerWidth/window.innerHeight, 0.1, 1000 );

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );

        var geometry = new THREE.BoxGeometry( 1, 1, 1 );
        var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
        var cube = new THREE.Mesh( geometry, material );
        scene.add( cube );

         camera.position.z = 5;

         var animate = function () {
         requestAnimationFrame( animate );

         cube.rotation.x += 0.01;
         cube.rotation.y += 0.01;

         renderer.render( scene, camera );
       };

       animate();

      </script>
    
    </body>

【讨论】:

  • 感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 2019-07-05
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 2013-10-26
  • 2019-10-04
  • 1970-01-01
相关资源
最近更新 更多