Camera Video Background
Put it anywhere in your scene to render a camera video behind your 3D scene Live demo
import { Behaviour, ClearFlags, RGBAColor } from "@needle-tools/engine";
export class VideoBackground extends Behaviour {
async awake() {
// create video element and put it inside the <needle-engine> component
const video = document.createElement("video");
video.style.cssText = `
position: fixed;
min-width: 100%;
min-height: 100%;
z-index: -1;
`
this.context.domElement.shadowRoot!.appendChild(video);
// get webcam input
const input = await navigator.mediaDevices.getUserMedia({ video: true })
if (!input) return;
video.srcObject = input;
video.play();
// make sure the camera background is transparent
const camera = this.context.mainCameraComponent;
if (camera) {
camera.clearFlags = ClearFlags.SolidColor;
camera.backgroundColor = new RGBAColor(125, 125, 125, 0);
}
}
}
USDZ: Hide Object on Start
This is an example from our Everywhere Actions. The following script hides an object on start on Android and on iOS AR
export class HideOnStart extends Behaviour implements UsdzBehaviour {
start() {
this.gameObject.visible = false;
}
createBehaviours(ext, model, _context) {
if (model.uuid === this.gameObject.uuid)
ext.addBehavior(new BehaviorModel("HideOnStart_" + this.gameObject.name,
TriggerBuilder.sceneStartTrigger(),
ActionBuilder.fadeAction(model, 0, false)
));
}
beforeCreateDocument() {
this.gameObject.visible = true;
}
afterCreateDocument() {
this.gameObject.visible = false;
}
}
Everywhere Action: Emphasize on Click
Example for adding custom USDZ behaviours for iOS AR
This is an USDZ / iOS AR only example
export class EmphasizeOnClick extends Behaviour implements UsdzBehaviour {
@serializable()
target?: Object3D;
@serializable()
duration: number = 0.5;
@serializable()
motionType: MotionType = MotionType.bounce;
beforeCreateDocument() { }
createBehaviours(ext, model, _context) {
if (!this.target) return;
if (model.uuid === this.gameObject.uuid) {
const emphasize = new BehaviorModel("emphasize " + this.name,
TriggerBuilder.tapTrigger(this.gameObject),
ActionBuilder.emphasize(this.target, this.duration, this.motionType, undefined, "basic"),
);
ext.addBehavior(emphasize);
}
}
afterCreateDocument(_ext, _context) { }
}
Control a Timeline by scroll
Use the mouse wheel or touch delta to update a timeline's time.
import { Behaviour, PlayableDirector, serializeable } from "@needle-tools/engine";
import { Mathf } from "@needle-tools/engine";
// Example of setting a timeline's time
// without relying on any HTML elements.
// Here we directly use the mousewheel scroll and the touch delta
export class ScrollTimeline_2 extends Behaviour {
@serializeable(PlayableDirector)
timeline?: PlayableDirector;
@serializeable()
scrollSpeed: number = 0.5;
@serializeable()
lerpSpeed: number = 2.5;
private targetTime: number = 0;
start() {
this.timeline?.pause();
// Grab the mousewheel event
window.addEventListener("wheel", (evt: WheelEvent) => this.updateTime(evt.deltaY));
// Touch events are a bit more complicated
// We need to keep track of the last touch position
// and calculate the delta between the current and the last position
let lastTouchPosition = -1;
window.addEventListener("touchmove", (evt: TouchEvent) => {
const delta = evt.touches[0].clientY - lastTouchPosition;
// We only want to apply the delta if it's not TOO big
// e.g. when the user is scrolling the page
if (delta < 10) this.updateTime(-delta);
// Update the last touch position
lastTouchPosition = evt.touches[0].clientY;
});
}
private updateTime(delta) {
if (!this.timeline) return;
this.targetTime += delta * 0.01 * this.scrollSpeed;
this.targetTime = Mathf.clamp(this.targetTime, 0, this.timeline.duration);
}
onBeforeRender(): void {
if (!this.timeline) return;
this.timeline.pause();
this.timeline.time = Mathf.lerp(this.timeline.time, this.targetTime, this.lerpSpeed * this.context.time.deltaTime);
this.timeline.evaluate();
}
}
Code Contribution Example
This is mostly a basic example on how to contribute. It will then be added on our documentation contributions page: https://engine.needle.tools/docs/community/contributions
Please include at least one code snippet, for example like this:
import { Behaviour, serializable } from "@needle-tools/engine"
import { Object3D } from "three"
export class MyComponent extends Behaviour {
@serializable(Object3D)
myObjectReference?: Object3D;
start() {
console.log("Hello world", this);
}
update() {
// called every frame
}
}