@playcanvas/react
Version:
A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.
49 lines • 2.24 kB
JavaScript
"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { BoundingBox, Vec3, Mat4 } from "playcanvas";
import { Children, useLayoutEffect, useRef, useState } from "react";
import { Entity } from "../Entity.js";
import { useApp, useParent } from "../hooks/index.js";
export const Align = (props) => {
const { left, right, top, bottom, front, back, children } = props;
const containerRef = useRef(null);
const boundsRef = useRef(new BoundingBox(new Vec3(), new Vec3()));
const [, setBounds] = useState(null);
const app = useApp();
const parent = useParent();
// all children should be part of the scene hierarchy now
useLayoutEffect(() => {
if (!app)
return;
const entity = containerRef.current;
const bounds = boundsRef.current;
if (!entity)
return;
bounds.center.set(0, 0, 0);
bounds.halfExtents.set(0.0, 0.0, 0.0);
const tmpAABB = new BoundingBox();
const invWorldTransform = new Mat4();
const renderComponents = entity.findComponents("render");
// Compute the bounds of all render components
const updatedBounds = renderComponents.reduce((bounds, component) => {
const meshInstances = component.meshInstances;
meshInstances.forEach((mi) => {
invWorldTransform.copy(mi.node.getWorldTransform()).invert();
tmpAABB.setFromTransformedAabb(mi.aabb, invWorldTransform);
bounds.add(mi.aabb);
});
return bounds;
}, bounds);
boundsRef.current = updatedBounds;
setBounds(updatedBounds);
}, [app, parent, Children.count(children)]);
const { center, halfExtents } = boundsRef.current;
// Align based on bounds and alignment flags
const position = [
left ? -center.x + halfExtents.x : right ? -center.x - halfExtents.x : -center.x,
bottom ? -center.y + halfExtents.y : top ? -center.y - halfExtents.y : -center.y,
front ? -center.z + halfExtents.z : back ? -center.z - halfExtents.z : -center.z,
];
return (_jsx(Entity, { ref: containerRef, position: position, children: children }));
};
//# sourceMappingURL=Align.js.map