Hi guys, I have a html element to put side-by-side to the render window. Let’s call it a sidebar (but not really).
I want the render window to adapt to the available size because it seemed the easiest way to move the camera’s perspective point to the side as well and not waste any render resources.
Now this leads to the render output being stretched or squished for a frame. Is this avoidable?
The other option would be to overlay the sidebar but then I’d need to manually shift the camera’s offset and this is a bit harder to orchestrate than just take the layouting system take of it
To make sure your Needle Engine render window adapts correctly to the sidebar without stretching or squishing the output, you should consider the following approach:
Set Fixed Height and Width for Sidebar: Make sure that the sidebar has a set width when it is opened and maintain the height: 100%; correctly in the CSS.
Use Right Flex Configuration: Adjust the flex property for the render area to hold its aspect ratio. This will help in ensuring that the rendering output stays consistent during animation.
Request Animation Frame: Use requestAnimationFrame in your JavaScript to update the render when the sidebar width changes. This minimizes render output stretching during transitions.
Maintain Aspect Ratio: You can also lock the aspect ratio of the rendering area based on the original window size when it initializes.
Here’s some sample code to illustrate this approach:
<div class="container" style="display: flex; width: 100%; height: 100vh; overflow: hidden;">
<needle-engine id="renderArea" style="flex: 1; height: 100%;"></needle-engine>
<div id="sidebar" class="sidebar" style="width: 0; height: 100%; transition: width 0.3s;"></div>
</div>
<script>
const sidebar = document.getElementById('sidebar');
const renderArea = document.getElementById('renderArea');
function animateSidebar(expanding) {
if (expanding) {
sidebar.style.width = '250px'; // or desired width
} else {
sidebar.style.width = '0px';
}
}
// Call this function to expand/collapse the sidebar
// animateSidebar(true);
// animateSidebar(false);
</script>
Key Points:
Use CSS transitions for smooth animation of the sidebar.
Set the sidebar width dynamically on user action (like a button click).
Ensure that the render area is set to flex-grow to utilize available space properly.
Additional Recommendations:
Check for any reflows during the animation, as this affects performance.
For positioning the camera, if it gets tricky, you could consider listening to the sidebar’s width state and updating the camera position accordingly to precisely avoid visual artifacts.
If you need further details or adjustments, feel free to ask!
1 replies left - Get a PRO license for more AI replies. thread_eJdb11JlHLizENXfAFSvVqju Reply to this message to continue the conversation
You can utilize requestAnimationFrame to smoothly update the render when the sidebar state changes. Here’s a more detailed example to show how to use it:
Define your animation function that will adjust the camera position or any necessary rendering reset.
Use requestAnimationFrame within that function to ensure smooth rendering without janky updates.
Here’s how you can integrate it into the previous example:
<div class="container" style="display: flex; width: 100%; height: 100vh; overflow: hidden;">
<needle-engine id="renderArea" style="flex: 1; height: 100%;"></needle-engine>
<div id="sidebar" class="sidebar" style="width: 0; height: 100%; transition: width 0.3s;"></div>
</div>
<script>
const sidebar = document.getElementById('sidebar');
const renderArea = document.getElementById('renderArea');
let sidebarWidth = 0;
function updateRender() {
// Call your render update function here
// For example: needleEngineInstance.render();
requestAnimationFrame(updateRender); // Continue requesting frames
}
function animateSidebar(expanding) {
if (expanding) {
sidebarWidth = 250; // Desired width
} else {
sidebarWidth = 0;
}
sidebar.style.width = `${sidebarWidth}px`; // Set new width
// Calculate and adjust camera position after sidebar width is set
requestAnimationFrame(() => {
// Adjust camera position logic here
// Example: needleEngineInstance.camera.position.x = sidebarWidth / 2;
});
}
// Start the render loop
updateRender();
// Call this function to expand/collapse the sidebar
// animateSidebar(true);
// animateSidebar(false);
</script>
Explanation:
updateRender: This function can represent the continuous rendering process and is invoked using requestAnimationFrame. It ensures that rendering is optimized and involves any drawing routines you may have.
animateSidebar: Adjusts the width of the sidebar, and after setting the width, another requestAnimationFrame is called to accommodate any adjustments in the camera position or render updates.
Aspect Ratio Maintenance: Adjust the camera based on sidebarWidth immediately after the sidebar width is defined to maintain visuals correctly.
This structure should help prevent visual artifacts during the transition and keep everything in sync. If you require more details or adjustments, let me know!
0 replies left - Get a PRO license for more AI replies. thread_eJdb11JlHLizENXfAFSvVqju Reply to this message to continue the conversation
I think the issue is caused by the resize happens after the frame or inbetween frames. Check the main.ts above, it adds another resize observer to the needle-engine canvas and triggers an update + re-render if it happens outside of the frameloop/inbetween frames and seems to fix it (i added the step-start)