Files
AR-Menu/AR Menu/Needle/MenuScene/node_modules/three-mesh-ui/examples/tut__sprite.js
2025-11-30 08:35:03 +02:00

280 lines
6.2 KiB
JavaScript

// xfg:title Sprite
// xfg:category learn
// xfg:type explore
import { Block } from 'three-mesh-ui';
let rootBlock;
function example() {
const texture = new TextureLoader().load("./assets/spiny_bush_viper_sprite.jpg", ()=>{
exampleRender();
});
texture.minFilter = LinearFilter;
// If we are going to display ThreeMeshUI Text elements
rootBlock = new Block( {
name: "rootBlock",
width: 1,
height: 1,
boxSizing: 'border-box',
// A Block can define its "layout" properties
justifyContent: 'start',
textAlign: 'left',
backgroundOpacity: 1,
backgroundColor: 0xffffff,
// Must be stretch for slice
backgroundSize: "stretch",
backgroundImage : texture,
// Must provide slice in instanciation
// top left right bottom are normalized
// width and height can be use to define scale
slice : {top:0.1,left:.1,right:0.2,bottom:0.1, width: 2, height:2}
} );
rootBlock.renderOrder = -1;
// rootBlock.backgroundMaterial.depthTest = false;
// three-mesh-ui root elements must be added on threejs display stack
// In the scene, or in another Object3D of our choice
scene.add( rootBlock );
// three-mesh-ui Block, Text (or Boxes) are Object3D agreemented with three-mesh-ui capabilities
// so you can use any existing Object3D methods and properties
rootBlock.position.set(0, 1, -1.8);
rootBlock.rotation.x = -0.55;
}
/***********************************************************************************************************************
* Above this comment, you could find the contextual setup of this example.
* Not really related to the example itself : Creating three renderer, scene, lights, etc...
**********************************************************************************************************************/
import { exampleAddResizer, exampleManualRenderThreeOnly, exampleNoRenderLoop, exampleRender, exampleThreeSetup } from 'three-mesh-ui/examples/_setup/ThreeSetup';
import { exampleFontPreloadRoboto } from 'three-mesh-ui/examples/_setup/RobotoFont';
import exampleGUI from 'three-mesh-ui/examples/_setup/gui/exampleGUI';
import { DefaultValues, Inline, Text } from 'three-mesh-ui';
import { LinearFilter, TextureLoader } from 'three';
import { exampleCameraPerspective, exampleCameraPerspectiveResize } from './_setup/CameraPerspective';
import { exampleRoomVR } from './_setup/RoomVR';
/* eslint-disable no-unused-vars */
// building three setup
const { camera } = exampleCameraPerspective();
exampleAddResizer( exampleCameraPerspectiveResize );
camera.position.set(0, 1.6, 0);
// controls.target = new THREE.Vector3(0, 1, -1.8);
const { scene, renderer } = exampleThreeSetup( camera );
exampleNoRenderLoop();
exampleAddResizer( exampleRender );
exampleRoomVR( scene );
// preload fonts and run example() after
const defaultFontFamily = exampleFontPreloadRoboto( () => { example(); additionalUI(); exampleRender(); boxSizingUI(); });
DefaultValues.set({fontFamily:defaultFontFamily});
let infoBlock, border;
function additionalUI(){
infoBlock = new Block({
name: 'info-block',
width: 'auto',
padding: 0.05,
height: 'auto',
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center',
backgroundColor: 0x000000,
borderRadius : 0.025,
});
infoBlock.backgroundMaterial.depthWrite = false;
infoBlock.position.z = -2
infoBlock.position.y = 0.4;
infoBlock.position.set(0, 0.6, -1.5);
infoBlock.rotation.x = -0.35;
scene.add( infoBlock );
border = new Block({
name: 'border-container',
height: 'auto',
flexDirection: 'column',
justifyContent: "start",
fontOpacity: 1
})
const borderTitle = new Text({name:'border-title', textContent: `Slice`, fontWeight: '700', fontSize: 0.08, lineHeight:1.5, width: 'auto',margin:0.05});
const borderContent = new Text({
name: 'border-content',
textAlign: "left",
lineHeight: 0.8
}).add(
new Inline({
textContent: 'A slice definition '
}),
new Inline({
textContent: 'MUST ',
fontWeight: '700',
fontStyle: 'italic'
}),
new Inline({
textContent: 'be provided during instanciation. '
}),
new Inline({
textContent: '\n\nbackgroundSize MUST ',
fontWeight: '700',
fontStyle: 'italic'
}),
new Inline({
textContent: 'be set to '
}),
new Inline({
textContent: '"stretch".',
fontWeight: '700',
}),
new Inline({
textContent: '\n\nborderRadius, borderWidth ',
fontWeight: '700',
fontStyle: 'italic'
}),
new Inline({
textContent: 'may produce unexpected results.'
}),
new Inline({
textContent: '\n\nDepending on the output size, texture',
}),
new Inline({
textContent: '.minFilter ',
fontWeight: '700',
fontStyle: 'italic'
}),
new Inline({
textContent: 'can be handy.',
}),
);
border.add( borderTitle, borderContent )
infoBlock.add( borderTitle,border);
}
function boxSizingUI() {
const gui = exampleGUI();
// const boxlayout = new BoxLayoutBehavior( rootBlock, exampleRender );
// boxlayout.attach();
const params = {
infoBox: true,
zoom: camera.zoom,
width: rootBlock._width._value,
height: rootBlock._height._value,
borderWidth: rootBlock._borderWidth._value.clone(),
backgroundSize: rootBlock._backgroundSize._value,
render: exampleManualRenderThreeOnly,
opacity: rootBlock._backgroundOpacity._value,
}
gui.add( params, 'infoBox' ).onChange( ib => {
infoBlock.visible = ib;
exampleRender();
});
gui.add( params, 'zoom', 100, 800, 10).onChange( z => {
camera.zoom = z;
camera.updateProjectionMatrix();
exampleRender();
})
const rootBlockGui = gui.addFolder( 'rootBlock properties' );
rootBlockGui.add( params, 'width', 0, 3, 0.01 ).onChange( w => {
rootBlock.set({width:w});
exampleRender();
})
rootBlockGui.add( params, 'height', 0, 3, 0.01 ).onChange( h => {
rootBlock.set({height:h});
exampleRender();
})
rootBlockGui.add( params, 'backgroundSize', {"cover":"cover", "contain":"contain",'stretch':'stretch'}).onChange( bs => {
rootBlock.set({backgroundSize:bs});
exampleRender();
})
rootBlockGui.add( params, 'opacity', 0,1,0.01).onChange( o => {
rootBlock.set({backgroundOpacity: o});
exampleRender();
})
rootBlockGui.addD4( params, 'borderWidth', 0, 2, 0.1 ).onChange( bw => {
rootBlock.set({borderWidth:bw});
exampleRender();
})
rootBlockGui.add( params, 'render');
}