mirror of
https://github.com/storytold/spark.git
synced 2026-10-18 07:40:38 +00:00
Transition Effects (#172)
* Transition effects * Added two transition effects and refactored code into separate .js filesAdded two transition effects and refactorized code for effects in separate .js files * Deleted unused html file * Fixed a GUI bug * Fixed focus given to effect when dropdown changes * Fixed github verification errors * fix lints in splat-transitions and tweak defaults * lint fix on splat-transitions * lint fix on splat-transitions * Morph transition * Morph transition - better random function * Morph transition - better morphing of dishes * fixed lint errors
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import { SparkRenderer } from "@sparkjsdev/spark";
|
||||
import { GUI } from "lil-gui";
|
||||
import * as THREE from "three";
|
||||
|
||||
// Central renderer/scene/camera shared by effects
|
||||
const canvas = document.getElementById("canvas");
|
||||
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
|
||||
renderer.setClearColor(0x000000, 1);
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
const spark = new SparkRenderer({ renderer });
|
||||
scene.add(spark);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
50,
|
||||
canvas.clientWidth / canvas.clientHeight,
|
||||
0.01,
|
||||
2000,
|
||||
);
|
||||
camera.position.set(0, 3, 8);
|
||||
camera.lookAt(0, 0, 0);
|
||||
scene.add(camera);
|
||||
|
||||
// Resize handling
|
||||
function handleResize() {
|
||||
const w = canvas.clientWidth;
|
||||
const h = canvas.clientHeight;
|
||||
renderer.setSize(w, h, false);
|
||||
camera.aspect = w / h;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
// GUI
|
||||
const gui = new GUI();
|
||||
const params = { Effect: "Spherical" };
|
||||
const effectFiles = {
|
||||
Spherical: () => import("./effects/spheric.js"),
|
||||
Explosion: () => import("./effects/explosion.js"),
|
||||
Flow: () => import("./effects/flow.js"),
|
||||
Morph: () => import("./effects/morph.js"),
|
||||
};
|
||||
|
||||
let active = null; // { api, group }
|
||||
let last = 0;
|
||||
let effectFolder = null; // GUI folder for current effect
|
||||
|
||||
async function switchEffect(name) {
|
||||
const loading = document.getElementById("loading");
|
||||
loading.textContent = `Loading ${name}...`;
|
||||
loading.style.display = "block";
|
||||
|
||||
// Dispose previous
|
||||
if (active) {
|
||||
try {
|
||||
active.api.dispose?.();
|
||||
} catch {}
|
||||
if (active.group) scene.remove(active.group);
|
||||
active = null;
|
||||
}
|
||||
|
||||
// Destroy previous GUI folder to avoid accumulation
|
||||
if (effectFolder) {
|
||||
try {
|
||||
effectFolder.destroy();
|
||||
} catch {}
|
||||
effectFolder = null;
|
||||
}
|
||||
|
||||
const loader = effectFiles[name];
|
||||
if (!loader) return;
|
||||
const mod = await loader();
|
||||
|
||||
const context = { THREE, scene, camera, renderer, spark };
|
||||
const api = await mod.init(context);
|
||||
|
||||
if (api.group) scene.add(api.group);
|
||||
active = { api, group: api.group };
|
||||
|
||||
// Setup a per-effect GUI folder if exposed
|
||||
if (api.setupGUI) {
|
||||
effectFolder = gui.addFolder(name);
|
||||
api.setupGUI(effectFolder);
|
||||
}
|
||||
|
||||
loading.style.display = "none";
|
||||
|
||||
// Give focus back to the canvas so keyboard controls work immediately
|
||||
try {
|
||||
canvas.focus();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
gui.add(params, "Effect", Object.keys(effectFiles)).onChange(switchEffect);
|
||||
|
||||
// Animation loop
|
||||
renderer.setAnimationLoop((timeMs) => {
|
||||
const t = timeMs * 0.001;
|
||||
const dt = t - (last || t);
|
||||
last = t;
|
||||
|
||||
if (active?.api?.update) active.api.update(dt, t);
|
||||
renderer.render(scene, camera);
|
||||
});
|
||||
|
||||
// Kickoff
|
||||
switchEffect(params.Effect);
|
||||
Reference in New Issue
Block a user