文章が適当です。
Scratchと似た感覚でJavaScriptから動画を作れるライブラリを作っています。
どういうことか
AviUtl等の動画編集アプリは外部プラグインで実現できるものもありますが
独自のイージングを書くのは難しい...
また、動画編集アプリでは中間点を多用しないといけなくて大変...
そこで、Scratchはそのようなめんどくさいもの無しで動画のようなものを作れたりできます。
しかしScratchはマウスを多用しないといけない。トラックパッド生活の自分にとっては地獄..
そこでScratchのようなものをJavaScriptで実現できれば!ということで作りました。
仕組み
今回は知らない人もいるであろうジェネレータ関数というものを使います。
何それ?おいしいの?
説明しましょう。
function* GeneratorFunc(){
yield 0;
yield 1;
yield 2;
}
const generator = GeneratorFunc();
console.log(generator.next().value); //0
console.log(generator.next().value); //1
console.log(generator.next().value); //2
ジェネレーター関数はジェネレーターを生成し、next関数でyieldが出るまで処理をし、yieldが出たところでその値を返すような仕組みです。
非同期処理に活用されてたりしますがみなさんからは忘れられているでしょう...
yieldで処理を中断できるので、自分はこれを再レンダリングに活用できると思いました。
複数の、Scratchでスプライトに相当するものを以下のように同時進行で進められるためです。
function drawSprites(sprites){
for(let i = 0;i < 60;i++){
sprites.forEach(e=>e.next());
}
}
またこれにもメリットあって再レンダリング(再描画)のタイミングが明示的になるんです。Scratchはソースコードでも見ない限り分からないので。
現状の使い方
複数のレイヤーがジェネレーターを実行してそれがステートを変更する感じです。
import { L } from "jsvideo";
export default L.text(function*(state){
state.text = "Hello!";
yield; //再描画
for(let i = 0;i < 30;i++){
state.y += (300-state.y)/10; //イージング
yield;
}
})
import text from "./text.js"
import { createVideoRenderer, L } from "jsvideo"
const video = createVideoRenderer(640, 480, [
L.rect(function*(state){
state.width = 640;
state.height = 480;
while(true) yield true; //trueを指定すると他のレイヤーが終わった場合に一緒に終わる
}),
text
])
document.appendChild(video.canvas);
requestAnimationFrame(function callback(){
if(video.render()) return; //renderがtrueを返したら終わり
else requestAnimationFrame(callback)
})
こんな感じで作れます。
使いたかったら使ってみてください。
$ bun i jsvideo
npmを使っている人なら
$ npm install jsvideo
こんな一般的な単語があいてたのはラッキーですね。