Docs/Skills and code/skill video-visual-production

.claude/skills/video-visual-production/render/selftest-scenes.js

Code40 lines2.0 KBSkill: video-visual-production

What the file says about itself

Self-test for the scene library: draws every example in scenes-data.js at its end state and at mid-build, writes a contact sheet.

#!/usr/bin/env node
// Self-test for the scene library: draws every example in scenes-data.js at its end state and at mid-build, writes a contact sheet.
//   node render/selftest-scenes.js [outDir]
// A scene that throws, or draws text outside the canvas, fails here before any beat uses it.
const fs = require('fs');
const path = require('path');
const { createCanvas, loadImage } = require('@napi-rs/canvas');
const D = require('./draw');
const data = { ...require('./scenes-data'), ...require('./scenes-more') };
data.EXAMPLES = { ...require('./scenes-data').EXAMPLES, ...require('./scenes-more').EXAMPLES };

D.registerFonts();
const out = process.argv[2] || path.join(process.env.VIDEO_BUILD_DIR || 'C:/video-build', 'selftest');
fs.mkdirSync(out, { recursive: true });
const cv = createCanvas(D.W, D.H), env = D.makeEnv(cv, 1);
let failed = 0;
const files = [], labels = [];
for (const [name, ex] of Object.entries(data.EXAMPLES)) {
  const fn = data[ex.type || name];
  const last = Math.max(...Object.values(ex.cues)) + 2.2;
  for (const [tag, t] of [['mid', last * 0.45], ['end', last]]) {
    try {
      env.boxes = [];
      env.ctx.setTransform(1, 0, 0, 1, 0, 0);
      fn(env, t, ex.props, { cues: ex.cues, dur: last + 0.5, assets: {} });
      const off = env.boxes.filter((b) => b.x < 0 || b.x + b.w > D.W || b.y < 0 || b.y + b.h > D.H);
      if (off.length) { failed++; console.log(`FAIL ${name} ${tag}: text off the canvas: ${off.map((b) => b.text).join(', ')}`); }
      const f = path.join(out, `${name}-${tag}.png`);
      fs.writeFileSync(f, cv.toBuffer('image/png'));
      if (tag === 'end') { files.push(f); labels.push(name); }
    } catch (e) { failed++; console.log(`FAIL ${name} ${tag}: ${e.message}`); }
  }
}
(async () => {
  const { sheet } = require('../scripts/contact-sheet');
  await sheet(files, labels, path.join(out, 'selftest-sheet.png'), 4, 480);
  console.log(failed ? `${failed} failure(s)` : `all ${Object.keys(data.EXAMPLES).length} scene types draw`, '->', path.join(out, 'selftest-sheet.png'));
  process.exit(failed ? 1 : 0);
})();

Shown as it is in the repository at build time (2026-11-03); the home directory appears as <home>. If this page and the file differ, the file is right. Back to the catalogue.