threejs,div.appendChild 和动态调整大小

threejs, div.appendChild & dynamic resize

我正在尝试调整由 three.js 创建的 canvas 的大小,但是一旦我取消注释 wrapResize2 函数中有关 three.js 的 6 行,立方体就会消失。

如果我查看 chrome-console,它似乎找不到附加的 canvas 元素。

如果我检查 Chrome 中的元素,我发现 canvas 元素不再存在。

我不知道为什么,但是当那 6 条调整大小的行出现时,threejs canvas 不再附加。

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        body {
            margin: 0;
            overflow: hidden;
        }
        #wrap {margin: auto}
        .abs {position: absolute}
    </style
</head>
<body>
<div id="wrap" class="abs">
    <svg id="back" class="abs" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
        <defs>
            <filter id="noise">
                <feTurbulence baseFrequency=".1" type="fractalNoise" />
            </filter>
        </defs>
        <rect width="500" height="500" filter="url(#noise)"/>
    </svg>
    <div id="sriJs" class="abs">
    </div>
    <svg id="front" class="abs" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
        <defs>
            <style>
                .cls-1 {
                    fill: #f0f;
                    opacity: 0.3;
                }
                .cls-2 {
                    fill: aqua;
                    opacity: 0.4;
                }
                .cls-3 {
                    fill: #ff0;
                    opacity: 0.5;
                }
            </style>
        </defs>
        <path d="M0,0V500H500V0ZM245,490H10V255H245Zm0-245H10V10H245ZM490,490H255V255H490Zm0-245H255V10H490Z"/>
        <rect class="cls-1" x="10" y="10" width="235" height="235"/>
        <rect class="cls-2" x="255" y="10" width="235" height="235"/>
        <rect class="cls-3" x="10" y="255" width="235" height="235"/>
    </svg>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.1/gsap.min.js'></script>
<script type="text/javascript">
    var fullScreen = 1,
    wrapWidth = 500,
    wrapHeight = 500,
    rotationX = 2,
    rotationY = 2,
    rotationZ = 2,
    animTime = 30,
//-------------------
    idQsel = function (e) {return document.querySelector('#' + e)},
    mf3 = function mf3(v){return Math.floor(v*1000)/1000},
    wrap = idQsel('wrap'),
    sriJs = idQsel('sriJs'),
    back = idQsel('back'),
    front = idQsel('front'),
    sriJsW,sriJsH,
    iifeMain = (function() {
        var camera, scene, renderer, cube,
        init = function () {
            camera = new THREE.PerspectiveCamera(45, sriJsW/sriJsH, 1, 20000);
            camera.position.z = 250;
            scene = new THREE.Scene();
            renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true});
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(sriJsW,sriJsH);
            sriJs.appendChild(renderer.domElement);
        },
        cubeInit = function () {
            var mat = new THREE.MeshNormalMaterial(),
            cubeSize = 100;
            cube = new THREE.Mesh(new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize), mat);
            scene.add( cube );
        },
        animate = function () {
            requestAnimationFrame(animate);
            render();
        },
        render = function () {renderer.render(scene, camera);},

        cubeRotation = function () {
            var obj = cube.rotation;
            TweenMax.to(cube.rotation, animTime/2, {
                x: obj.x + rotationX,
                y: obj.y + rotationY,
                z: obj.z + rotationZ,
                onComplete: cubeRotation
            });
        },
            
        wrapResize2 = function(wW,wH,cW,cH) {
            if ((wH < cH) || (fullScreen==1)) {
                wrap.style.width = wW + 'px';
                wrap.style.height = wH  + 'px';
                back.style.width = wW + 'px';
                back.style.height = wH  + 'px';
                front.style.width = wW + 'px';
                front.style.height = wH  + 'px';
                //renderer.setSize(wW,wH);
                //camera.aspect = wW/wH;
                //camera.updateProjectionMatrix();
                sriJsW = wW;
                sriJsH = wH;
            } else {
                wrap.style.height = cH + 'px';
                wrap.style.width = cW + 'px';
                back.style.height = cH  + 'px';
                back.style.width = cW + 'px';
                front.style.height = cH  + 'px';
                front.style.width = cW + 'px';
                //renderer.setSize(cW,cH);
                //camera.aspect = cW/cH;
                //camera.updateProjectionMatrix();
                sriJsH = cH;
                sriJsW = cW;
            }
        },
        wrapResize = function() {
            var wrapWbyH = wrapWidth/wrapHeight,
            winW = window.innerWidth,
            winH = window.innerHeight,
            winWbyH = winW / winH;
            if (winWbyH > wrapWbyH) winW = winH * wrapWbyH;
            else winH = winW / wrapWbyH;
            wrapResize2(winW,winH,wrapWidth,wrapHeight);
        },
        winit = function() {
            wrap.style.top = 0;
            wrap.style.right = 0;
            wrap.style.bottom = 0;
            wrap.style.left = 0;

            wrapResize();

            init();
            cubeInit();
            animate();
            cubeRotation();
        };
        window.addEventListener('load', winit, false);
        window.addEventListener('resize', wrapResize, false);
        window.addEventListener('orientationchange', winit, false);
    })();
</script>
</body>
</html>

谁能帮帮我?

我制作了一个代码笔,其中 6 行未注释:https://codepen.io/trufo/pen/powgRpB

干杯

迈克尔

ps:忽略我下面关于重命名的评论。我设法在上面的代码片段中做到了。

我找到了另一种方法来做同样的事情,但没有 appendChild。我把 canvas 直接放在包装 div...

    <canvas id="cnv" class="abs">
    </canvas>

...然后在渲染器变量中使用它。

renderer = new THREE.WebGLRenderer({antialias: true, alpha: true, canvas: cnv })

在此处查看代码笔: https://codepen.io/trufo/pen/qBjbzqd