@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
74 lines (62 loc) • 2.4 kB
JavaScript
async function generatePoster() {
const { screenshot2 } = await import("@needle-tools/engine");
try {
const needleEngine = document.querySelector("needle-engine");
if (!needleEngine) return null;
// Keep in sync with og:image:width meta tags
// https://developers.facebook.com/docs/sharing/best-practices/
const width = 1080;
const height = 1080;
const context = await needleEngine.getContext();
// wait a fixed time for e.g. fonts to load
while(context.time.frameCount < 2)
await new Promise((resolve) => setTimeout(resolve, 200));
const mimeType = "image/webp";
// We're reading back as a blob here because that's async, and doesn't seem
// to stress the GPU so much on memory-constrained devices.
const blob = await screenshot2({context, width, height, mimeType, type: "blob"});
// We can only send a DataURL, so we need to convert it back here.
const dataUrl = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function() {
resolve(reader.result);
};
reader.onloadend = function() {
resolve(null);
};
reader.readAsDataURL(blob);
});
return dataUrl;
}
catch (e) {
console.error(e);
return null;
}
}
async function sendPoster() {
const blob = await generatePoster();
import.meta.hot.send("needle:screenshot", { data: blob });
}
// communicate via vite
if (import.meta.hot) {
// wait for needle engine to be fully loaded
const needleEngine = document.querySelector("needle-engine");
needleEngine?.addEventListener("loadfinished", () => {
// wait a moment
setTimeout(() => {
sendPoster();
}, 200);
});
// for debugging: build extra button with dev-only options
/*
var button = document.createElement("button");
button.id = "send-msg";
button.innerHTML = "Generate Poster";
button.style.position = "fixed";
button.style.zIndex = "9999";
document.body.appendChild(button);
document.querySelector("#send-msg").addEventListener("click", async () => {
sendPoster();
});
*/
}