【问题标题】:Fitting canvas in parent div在父 div 中安装画布
【发布时间】:2019-01-31 20:49:50
【问题描述】:

我正在尝试使我的画布适合 div。

    // Make the Canvas Responsive

    window.onload = function(){
      wih = window.innerHeight;
      wiw = window.innerWidth;
    }
    window.onresize = function(){
      wih = window.innerHeight;
      wiw = window.innerWidth;
    }

    // Define the min and max Values for the Randomize Function.
    radiusMin = 1;
    radiusMax = 40;
    tubeMin = 1;
    tubeMax = 40;
    radialSegmentsMin = 1;
    radialSegmentsMax = 800;
    tubularSegmentsMin = 1;
    tubularSegmentsMax = 30;
    pMin = 1;
    pMax = 20;
    qMin = 1;
    qMax = 20;
    heightScaleMin = 0;
    heightScaleMax = 5;


    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(
        45, // fov (45 / 60)
        window.innerWidth / window.innerHeight, // wiw / wih,
        0.1,
        1000
    );

    // Create a WebGLRenderer
    var webGLRenderer = new THREE.WebGLRenderer();
    webGLRenderer.setClearColor(new THREE.Color(0x000000, 1.0));
    webGLRenderer.setSize(window.innerWidth, window.innerHeight);
    webGLRenderer.shadowMapEnabled = true;

    // Append the output of the renderer to the html element
    document.getElementById("WebGL-output").append(webGLRenderer.domElement);
    var step = 0;
    var knot;

    // Keep Aspect Ratio on Resize
    window.addEventListener("resize", onWindowResize, false);
    function onWindowResize() {
      camera.aspect = wiw / wih;
      camera.updateProjectionMatrix();
      webGLRenderer.setSize(window.innerWidth, window.innerHeight);
    }

    // Position and point the camera to the center of the scene
    camera.position.x = -30;
    camera.position.y = -40;
    camera.position.z = 50;
    camera.lookAt(new THREE.Vector3(10, 0, 0));
    var clock = new THREE.Clock();
    var trackballControls = new THREE.TrackballControls(camera, webGLRenderer.domElement);
    trackballControls.rotateSpeed = 4.0;
    trackballControls.zoomSpeed = 1.0;
    trackballControls.panSpeed = 1.0;
    trackballControls.noZoom = false;
    trackballControls.noPan = true;
    trackballControls.staticMoving = false;
    trackballControls.dynamicDampingFactor = 0.3;

    // Setup Controls for dat.GUI
    var controls = new function() {
      // Default Values
      this.color = "#7a4d0c";
      this.radius = 22;
      this.tube = 32;
      this.radialSegments = 800;
      this.tubularSegments = 12;
      this.p = 10; // wind p times around its axis of rotational symmetry
      this.q = 14; // wind q times around a circle in the interior of the torus
      this.heightScale = 2;
      this.asParticles = true;
      this.rotate = true;
      this.animate = false; // Animates radialSegments
      this.randomize = false; // Randomize Mesh

      this.redraw = function() {
        // Remove the old plane
        if (knot) scene.remove(knot);
        // Create a new one
        var geom = new THREE.TorusKnotGeometry(
            controls.radius,
            controls.tube,
            Math.round(controls.radialSegments),
            Math.round(controls.tubularSegments),
            Math.round(controls.p),
            Math.round(controls.q),
            controls.heightScale,
            controls.color
        );

        if (controls.asParticles) {
          knot = createParticleSystem(geom);
        } else {
          knot = createMesh(geom);
        }
        // Add it to the scene.
        scene.add(knot);
      };
    }();

    var gui = new dat.GUI({
      resizable : false
    });
    gui.addColor(controls, "color").onChange(controls.redraw);
    gui.add(controls, "radius", radiusMin, radiusMax).onChange(controls.redraw);
    gui.add(controls, "tube", tubeMin, tubeMax).onChange(controls.redraw);
    gui.add(controls, "radialSegments", radialSegmentsMin, radialSegmentsMax).step(1).onChange(controls.redraw);
    gui.add(controls, "tubularSegments", tubularSegmentsMin, tubularSegmentsMax).step(1).onChange(controls.redraw);
    gui.add(controls, "p", pMin, pMax).step(1).onChange(controls.redraw);
    gui.add(controls, "q", qMin, qMax).step(1).onChange(controls.redraw);
    gui.add(controls, "heightScale", heightScaleMin, heightScaleMax).onChange(controls.redraw);
    gui.add(controls, "asParticles").onChange(controls.redraw);
    gui.add(controls, "rotate").onChange(controls.redraw);
    gui.add(controls, "animate").onChange(controls.redraw);
    gui.add(controls, "randomize").onChange(controls.redraw);

    gui.close();
    controls.redraw();

    render();

    // From THREE.js examples
    // Create Sprites for the particleSystem
    function generateSprite() {
      var canvas = document.createElement("canvas");
      canvas.width = 16;
      canvas.height = 16;

      var context = canvas.getContext("2d");
      var gradient = context.createRadialGradient(
          canvas.width / 2,
          canvas.height / 2,
          0,
          canvas.width / 2,
          canvas.height / 2,
          canvas.width / 2
      );
      gradient.addColorStop(0.0, controls.color);
      gradient.addColorStop(0.2, controls.color);
      gradient.addColorStop(0.4, controls.color);
      gradient.addColorStop(1.0, "rgba(0,0,0,1)");

      context.fillStyle = gradient;
      context.fillRect(0, 0, canvas.width, canvas.height);

     var texture = new THREE.Texture(canvas);
      texture.needsUpdate = true;
      return texture;
    }

    // Create a particleSystem and use the Sprites
    function createParticleSystem(geom) {
      var material = new THREE.ParticleBasicMaterial({
        color: 0xffffff,
        size: 2,
        transparent: true,
        blending: THREE.AdditiveBlending, // Time to Shine!
        map: generateSprite()
      });

      var system = new THREE.ParticleSystem(geom, material);
      system.sortParticles = true;
      return system;
      }

目前,它想要占据整个宽度,因为我用 CSS 编辑了它并且只接受“重要”标签。 div 在平板电脑和台式机上为 50vw,但在移动设备上为 100vw。问题是在移动期间,画布想要忽略告诉它调整大小为 100vw 的 @media 样式;;;;如果这个愚蠢的画布只能坚持 div 的宽度,它会工作。

我仍然是 Javascript 的一个非常大的初学者,因此非常欢迎任何解释。

画布需要适合 DIV,因此当布局响应移动设备时,它会正常运行。

【问题讨论】:

  • 您是否尝试过降低负载大小?也许可以把它变小?
  • window.onload = function(){ wih = window.innerHeight; wiw = window.innerWidth;我应该用客户端替换内部吗?
  • 尝试在每个 window.innerHeight/2 上除以二; window.innerWidth/2
  • 我刚试过,但没有用。 BLEH
  • 你可能会找到this article useful

标签: javascript html three.js window particles


【解决方案1】:

不确定这是否对您和您的情况有用,但尝试没有害处...

关键是window.matchMedia。这传递了一个与 CSS 媒体查询中使用的相同的媒体查询字符串:

const mq = window.matchMedia( "(min-width: 500px)" );

if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}

您还可以添加一个在检测到更改时触发的事件侦听器:

// media query event handler
if (matchMedia) {
const mq = window.matchMedia("(min-width: 500px)");
mq.addListener(WidthChange);
WidthChange(mq);
}

// media query change
function WidthChange(mq) {
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}

}

【讨论】:

    【解决方案2】:

    如果您希望渲染器尊重容器 div 的宽度和高度,您需要检查该容器 div 的宽度和高度,而不是整个窗口:

    // Save reference of the parentDiv to be used later
    var parent = document.getElementById('parentDiv');
    parent.append(webGLRenderer.domElement);
    
    // When window is resized
    resizeRenderer() {
        // Get width & height of parentDiv
        var width = parent.clientWidth;
        var height = parent.clientHeight;
        webGLRenderer.setSize(width, height);
    }
    
    // Add window resize listener
    window.addEventListener('resize', resizeRenderer);
    
    // Force renderer resizing once
    resizeRenderer();
    

    这样,它将尊重您在 CSS 中为 parentDiv 建立的任何媒体查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      • 2016-09-22
      • 2022-08-14
      • 2022-11-08
      • 1970-01-01
      相关资源
      最近更新 更多