在父div中适合画布

时间:2019-01-31 20:49:50

标签: javascript html three.js window particles

我正在尝试使我的画布适合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。问题是在移动过程中,画布希望忽略@media样式,该样式告诉它将大小调整为100vw ;;;如果这个笨拙的画布只是坚持div的宽度,那它将起作用。

我仍然是Java语言的初学者,因此非常欢迎您进行任何解释。

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

2 个答案:

答案 0 :(得分:0)

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

键是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
}

}

答案 1 :(得分:0)

如果您希望渲染器遵守容器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建立的任何媒体查询。