Skip to content

Html ^3.5.0

This component allows you to project HTML content to any object in your scene. TresJS will automatically update the position of the HTML content to match the position of the object in the scene.

Usage

vue
<script setup lang="ts">
import { Html, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'

import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'

const gl = {
  clearColor: '#82DBC5',
  shadows: true,
  alpha: false,
  shadowMapType: BasicShadowMap,
  outputColorSpace: SRGBColorSpace,
  toneMapping: NoToneMapping,
}
</script>

<template>
  <TresCanvas v-bind="gl">
    <TresPerspectiveCamera :position="[3, 3, 8]" />
    <OrbitControls />
    <TresMesh :position="[1, 1, 1]">
      <TresBoxGeometry />
      <TresMeshNormalMaterial />
      <Html
        center
        transform
        :distance-factor="4"
        :position="[0, 0, 0.65]"
        :scale="[0.75, 0.75, 0.75]"
      >
        <h1 class="bg-white dark:bg-dark text-xs p-1 rounded">
          I'm a Box 📦
        </h1>
      </Html>
    </TresMesh>
    <TresGridHelper />
    <TresAmbientLight />
  </TresCanvas>
</template>

Occlusion

By default, the HTML content will be visible through other objects in the scene. You can use the occlude prop to make the HTML content occlude other objects in the scene.

Html can hide behind geometry using the occlude prop.

<Html occlude>

You can also choose which objects should occlude the HTML content by passing an array of objects refs to the occlude prop.

vue
<script setup lang="ts">
import { Html, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'

import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'
import { ref } from 'vue'

const gl = {
  clearColor: '#82DBC5',
  shadows: true,
  alpha: false,
  shadowMapType: BasicShadowMap,
  outputColorSpace: SRGBColorSpace,
  toneMapping: NoToneMapping,
}

const sphereRef = ref(null)
</script>

<template>
  <TresCanvas v-bind="gl">
    <TresPerspectiveCamera :position="[3, 3, 8]" />
    <OrbitControls />
    <TresMesh :position="[1, 1, 1]">
      <TresBoxGeometry />
      <TresMeshNormalMaterial />
      <Html
        center
        transform
        :occlude="[sphereRef]"
        :distance-factor="4"
      >
        <h1 class="bg-white dark:bg-dark text-xs p-1 rounded">
          Move camera
        </h1>
      </Html>
    </TresMesh>
    <TresMesh
      ref="sphereRef"
      :position="[3, 1, 1]"
    >
      <TresSphereGeometry />
      <TresMeshNormalMaterial />
      <Html
        center
        transform
        :distance-factor="4"
      >
        <h1 class="bg-white dark:bg-dark text-xs p-1 rounded">
          Sphere
        </h1>
      </Html>
    </TresMesh>
    <TresGridHelper />
    <TresAmbientLight :intensity="1" />
  </TresCanvas>
</template>

Using iframes

You can achieve pretty cool results with the Html component by using iframes. For example, you can use an iframe to display a YouTube video in your scene or a webpage with a 3D model.

vue
<script setup lang="ts">
import { ContactShadows, Html, OrbitControls, useGLTF } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'

import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'

const gl = {
  clearColor: '#241a1a',
  shadows: true,
  alpha: false,
  shadowMapType: BasicShadowMap,
  outputColorSpace: SRGBColorSpace,
  toneMapping: NoToneMapping,
}

const { nodes }
  = await useGLTF('https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/macbook/model.gltf', { draco: true })
</script>

<template>
  <TresCanvas v-bind="gl">
    <TresPerspectiveCamera :position="[-5, 4, 3]" />
    <OrbitControls />

    <primitive :object="nodes.Macbook">
      <Html
        transform
        wrapper-class="webpage"
        :distance-factor="11"
        :position="[0, 10.5, -13.6]"
        occlude
        :rotation-x="-0.256"
      >
        <iframe
          class="rounded-lg w-[1024px] h-[670px]"
          src="https://tresjs.org"
          frameborder="0"
        ></iframe>
      </Html>
    </primitive>

    <ContactShadows
      :blur="3.5"
      :resolution="512"
      :opacity="1"
    />
    <TresAmbientLight :intensity="1" />
    <TresDirectionalLight
      :intensity="2"
      :position="[2, 3, 0]"
      :cast-shadow="true"
      :shadow-camera-far="50"
      :shadow-camera-left="-10"
      :shadow-camera-right="10"
      :shadow-camera-top="10"
      :shadow-camera-bottom="-10"
    />
  </TresCanvas>
</template>

Props

PropDescriptionDefault
asWrapping html element.'div'
wrapperClassThe className of the wrapping element.
prependProject content behind the canvas.false
centerAdds a -50%/-50% CSS transform. [Ignored in transform mode]false
fullscreenAligns to the upper-left corner, fills the screen. [Ignored in transform mode]false
distanceFactorChildren will be scaled by this factor, and also by distance to a PerspectiveCamera / zoom by an OrthographicCamera.
zIndexRangeZ-order range.[16777271, 0]
portalReference to target container.
transformIf true, applies matrix3d transformations.false
spriteRenders as sprite, but only in transform mode.false
calculatePositionOverride default positioning function. [Ignored in transform mode]
occludeCan be true, Ref<TresObject3D>[], 'raycast', or 'blending'. True occludes the entire scene.
geometryCustom geometry to be usePlaneGeometry
materialCustom shader material to be use

Events

EventDescription
onOccludeCalled when the occlusion state changes.