无法使用 three.js 在 div 中添加 canvas

Can't add canvas inside a div using three.js

你好,我正在尝试使用 three.js 添加 canvas 我有

<div id="earth3D" bind:this={earth3DCanvas} />

为了在我的 js 部分添加 canvase,我做了

let earth3DCanvas;


    onMount(() => {
        const child = document.createElement(renderer.domElement);
        earth3DCanvas.appendChild(child);
    });

但出于某种原因,我收到了这个错误,我不知道它是什么意思。

VM2002:1 Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('[object HTMLCanvasElement]') is not a valid name.
    at HTMLDocument.createElement (<anonymous>:1:1536)
    at http://localhost:5000/build/bundle.js:51519:30
    at run (http://localhost:5000/build/bundle.js:14:16)
    at Array.map (<anonymous>)
    at http://localhost:5000/build/bundle.js:430:49
    at flush (http://localhost:5000/build/bundle.js:245:21)
    at init (http://localhost:5000/build/bundle.js:520:13)
    at new App (http://localhost:5000/build/bundle.js:51598:7)
    at http://localhost:5000/build/bundle.js:51609:17
    at http://localhost:5000/build/bundle.js:51618:3

Document.createElement() 需要一个 标签名称 作为参数(所以是一个像 'canvas' 或 'div' 这样的字符串),但你传递的是它一个 HTMLCanvasElement 对象。

这就像您试图重新创建一个已经存在的 canvas。

我不确定你的实际目标是什么,但如果你想创建并附加一个全新的 canvas,那么你会这样做:

onMount(() => {
    const child = document.createElement('canvas');
    earth3DCanvas.appendChild(child);
});

如果您想将 renderer.domElement 引用的 canvas 附加到您的容器 div:

onMount(() => {
    earth3DCanvas.appendChild(renderer.domElement);
});

请注意,如果 canvas 已经是 DOM 的一部分(给定 renderer.domElement 名称似乎就是这种情况?),那么它将被移动,而不是复制.

先绑定一个container然后onMount将渲染器添加到这个容器

<script>
    import { onMount } from 'svelte';
    let container;
    onMount(async () => {
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 1;
        renderer.outputEncoding = THREE.sRGBEncoding;
        container.appendChild(renderer.domElement);
    });
</script>
<div id="container" bind:this={container} />

这是一个有效的回复

https://svelte.dev/repl/446c6476fc0444b19ec95c0044564b96?version=3.44.2

如果您想使用条件语句,这里是解决方法

<script>
    const initContainer = (node) => {
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 1;
        renderer.outputEncoding = THREE.sRGBEncoding;
        node.appendChild(renderer.domElement);
    }
</script>
{#if condition}
    <div id="container" use:initContainer />
{/if}

这是一个使用这种方法的有效 repl

https://svelte.dev/repl/446c6476fc0444b19ec95c0044564b96?version=3.44.2