trois icon indicating copy to clipboard operation
trois copied to clipboard

How to place trois Renderer into an HTML element by id

Open EFeru opened this issue 2 years ago • 10 comments

Hi, Thank you for your work. I was trying to place one of the vue components from here into my website header which has an id but without success. Any idea how to do it?

I tryied the code below added in the component vue file itself, e.g., in Demo4.vue:

mounted() {
    //... code from Demo4.vue
    const renderer = this.$refs.renderer;
    var container = document.getElementById('mastheadBackground'); // 'mastheadBackground' is my header id
    container.appendChild(renderer.domElement);
}

The animation appears at the end of the website but not in the header element. In the console, the folowing error is shown: image

Any help is appreciated. Thanks!

EFeru avatar Mar 22 '22 18:03 EFeru

Did you try this? container.appendChild(renderer.three.renderer.domElement); Fixed incorrect code.

Lightnet avatar Mar 22 '22 19:03 Lightnet

@Lightnet thanks a lot, it is now displayed on the header! One issue still left is it does not ocuppy fully the container space. image

I already tryied adding resize="window" in the Renderer:

<template>
  <Renderer ref="renderer" resize="window" :orbit-ctrl="{ enableDamping: true, dampingFactor: 0.05, autoRotate : true }" shadow>
    <Camera :position="{ y: 100, z: 100 }" />
    <Scene>
      <SpotLight color="#ffffff" :intensity="0.5" :position="{ y: 150, z: 0 }" :cast-shadow="true" :shadow-map-size="{ width: 1024, height: 1024 }" />
      <SpotLight color="#ff0000" :intensity="0.5" :position="{ y: -150, z: 0 }" :cast-shadow="true" :shadow-map-size="{ width: 1024, height: 1024 }" />
      <InstancedMesh ref="imesh" :count="NUM_INSTANCES" :cast-shadow="true" :receive-shadow="true">
        <SphereGeometry :radius="5" />
        <PhongMaterial />
      </InstancedMesh>
    </Scene>
    <EffectComposer>
      <RenderPass />
      <UnrealBloomPass :strength="2" />
    </EffectComposer>
  </Renderer>
</template>

However, then I get full width but not full height occupied. image

Any idea how to approach it?

EFeru avatar Mar 22 '22 21:03 EFeru

If you on chrome browser you try inspect your element. Hover over the element to see the height of parent to children by layers. Html, body and #app #root div effect your size screen a bit. The height is base on the current content.

Try this as it work for me as it resize base on parent div. <Renderer ref="renderer" resize="div" >

It the same problem with threejs. It should be similar. Just edit the css file or style.

Lightnet avatar Mar 23 '22 01:03 Lightnet

Did you try https://vuejs.org/guide/built-ins/teleport.html ? (never tried)

klevron avatar Mar 28 '22 20:03 klevron

Thanks @klevron I will give it a try. @Lightnet the resize="div" did not work as expected, it behave similar to resize="window" but I have to check a bit more to be sure.

EFeru avatar Mar 29 '22 03:03 EFeru

I was curios about trying out since I need to resize to div for building for my project. resize="div"

Lightnet avatar Mar 29 '22 04:03 Lightnet

I found something by trying:

renderer.three.renderer.setSize(container.clientWidth, container.clientHeight);

Actually resize="window" and resize="div" they both work, but for some reason my header background image in the header enlarges. So it appears like in this figure: image

Not sure what the issue is because if I use Vantajs library (github repository here) it all works fine. I just had to include the three.min.js and vanta.net.min.js and add the code below into App.vue:

  mounted() {
    this.vantaEffect = window.VANTA.NET({
      el: "#mastheadBackground",
      mouseControls: true,
      touchControls: true,
      gyroControls: false,
      minHeight: 200.00,
      minWidth: 200.00,
      scale: 1.00,
      scaleMobile: 1.00,
      showDots: true,
      color: 0x41bdff,
      backgroundColor: 0x212529,
      backgroundAlpha: 0.7,
      points: 10.00,
      maxDistance: 20.00,
      spacing: 16.00
    })
  },
  beforeUnmount() {
    if (this.vantaEffect) {
      this.vantaEffect.destroy()
    }
  }

EFeru avatar Mar 29 '22 16:03 EFeru

Oh right I forgot that you need to calculate the header image to adjust the height. I had to reread your post. You need image height to fit correctly with renderer.

<div style="height:100%">
  <img src="" height="180px">
  <div style="height:calc(100% - 180px)">
    <canvas>
  </div>
</div>

This should work.

Lightnet avatar Mar 29 '22 16:03 Lightnet

Not sure if I understand where to place the code above. I have my image specified in the scss file:

header.masthead {
    padding-top: 6rem + 4.5rem;
    padding-bottom: 6rem;
    text-align: center;
    color: $white;
    background-image: url('~@/assets/img/header-bg.jpg');
    background-repeat: no-repeat;
    background-attachment: scroll;
    background-position: center center;
    background-size: cover;

EFeru avatar Mar 29 '22 17:03 EFeru

Well you need image height of to fit the canvas render height. That was example or render output layout. You need to find the correct image height since calc() and 100% current element height parent if parent is 100% height. Without correct height image it would not fix correct.

Here is example of it.

https://jsfiddle.net/8u269nzg/

Lightnet avatar Mar 29 '22 17:03 Lightnet