Zum Inhalt

viewer/js/dropzone.js

// Dropzone for files dropped onto the viewer.
// - .ply: splat file (PlayCanvas SOG loader can't read blob: URLs, so user
//   uploads are limited to .ply; the bundled demo is SOG over http).
// - .collision.json: collision-mesh sidecar — routed to onSidecar handler.

const PLY = /\.ply$/i;
const SIDECAR = /\.collision\.json$/i;

export function initDropzone({ stage, hint, fileInput, openButton, onFile, onSidecar }) {
  async function handleFile(file) {
    if (!file) { onFile(null, ''); return; }
    if (SIDECAR.test(file.name)) {
      if (onSidecar) {
        const text = await file.text();
        onSidecar(text);
      }
      return;
    }
    if (PLY.test(file.name)) { onFile(file); return; }
    onFile(null, file.name);
  }

  ['dragenter', 'dragover'].forEach(ev =>
    stage.addEventListener(ev, (e) => {
      e.preventDefault();
      hint.hidden = false;
    }));

  ['dragleave', 'drop'].forEach(ev =>
    stage.addEventListener(ev, (e) => {
      e.preventDefault();
      if (ev === 'dragleave' && stage.contains(e.relatedTarget)) return;
      hint.hidden = true;
    }));

  stage.addEventListener('drop', (e) => {
    const file = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0];
    handleFile(file);
  });

  openButton.addEventListener('click', () => fileInput.click());
  fileInput.addEventListener('change', () => {
    handleFile(fileInput.files[0]);
    fileInput.value = '';
  });
}