A small Blazor Server app that renders a shipping container in 3D and animates a set of boxes into it, one at a time, in load order. You can orbit, pan and zoom the scene while it loads.
The code was written in January 2023. This README was added in August 2026, when the repository was made public. Nothing else has been changed.
The C# side owns the data, the JavaScript side owns the rendering.
Data/BoxService.csreturns aBoxResponse: the container dimensions plus a list of boxes, each with a size, a colour, a target position inside the container and aLoadOrder.Data/Box.csderives the rest.StartPositionputs each box at the mouth of the container (same X and Y as its target, Z of zero) so it slides in along the container's length, andCenterStartPosition/CenterEndPositionconvert corner coordinates into the centre coordinates that Three.js meshes are positioned by. Doing that conversion once, server side, keeps the renderer free of layout maths.Pages/CubeMove.razorfetches the response on init and, after the first render, passes the container size and the box array into JavaScript throughIJSRuntime.wwwroot/js/cubeMove.jsbuilds the scene and animates each box from its start position to its end position, adding the next box only once the previous one has landed.
All of this is hand-written against Three.js rather than assembled from a component library:
THREE.WebGLRendererwith antialiasing, device pixel ratio and shadow maps enabled.- A
PerspectiveCamera, anAmbientLightand aDirectionalLight. OrbitControlsfor free inspection of the scene while the load animation runs.- The container drawn as
LineSegmentswith aLineDashedMaterial, over aBufferGeometrywhose 24 vertices for the 12 edges are built by hand inmakeContainer, withcomputeLineDistances()so the dashes render correctly. TextureLoaderfor box faces, and a grid helper for ground reference.- TWEEN drives the movement, with circular easing and a duration proportional to the distance each box travels, so boxes with further to go take longer rather than all arriving together.
- The scene resizes with the window.
BoxService returns hardcoded sample data: nine boxes with fixed sizes, colours and target
positions. There is no bin packing or layout solver behind it. The point of the project was the
rendering and animation layer and the split between computed state and presentation, so the box
positions were hand-picked to exercise that.
containerId is threaded through the service but ignored, and Pages/Counter.razor and
Pages/FetchData.razor are leftovers from the Blazor project template.
Requires the .NET 7 SDK.
dotnet run
Then open the URL it prints. The scene is on the root route.
Data/BoxService.cs box set, sizes, colours, target positions, load order
Data/Box.cs derived start positions and corner-to-centre conversion
Pages/CubeMove.razor fetches the data, hands it to JavaScript
wwwroot/js/cubeMove.js the Three.js scene, container geometry and load animation