12/29

日記

2025/12/29

gpgpuほぼ毎日やりたい three.jsexampleもcompute色々ある。かなり興味深い。

manualはよおわらせよ。

アニメーション練習

久しぶりにこのサイト触った。本当は毎日更新していきたい。

動画&スクロールアニメーション

https://site-training-zeta.vercel.app/ssite2

以前、実際の動画に対して、スクロールトリガーでcurerntTimeプロパティかなんかで動かしてみても、あまりスムーズに見えなかった。別の方法を模索していた。

動画を〇〇分割してそれをスクロールアニメーションのupdate関数で現在の位置の画像をcanvasにdrawImageしている。

知らなかったのは以下

画像読み込み確認について

const img = new Image()

  • img.complete 読み込み完了かどうかが取れる。
  • img.naturalWidth その画像本来の幅が取れる。

キャンバスと画像のアスペクト比を比べて、object-fit:coverみたいにしたい

描画時にひと手間。多分この例だとやらなくてもいいんだけど、まあ今後のために

const imageAspect = img.naturalWidth / img.naturalHeight;  // 画像のアスペクト比を計算
const canvasAspect = canvasWidth / canvasHeight;  // Canvasのアスペクト比を計算

let drawWidth: number, drawHeight: number, drawX: number, drawY: number;

if (imageAspect > canvasAspect) {
  drawHeight = canvasHeight;
  drawWidth = drawHeight * imageAspect;
  drawX = (canvasWidth - drawWidth) / 2;
  drawY = 0;
} else {
  drawWidth = canvasWidth;
  drawHeight = drawWidth / imageAspect;
  drawX = 0;
  drawY = (canvasHeight - drawHeight) / 2;
}

ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight);

画像が横長の場合

if (imageAspect > canvasAspect) {
  drawHeight = canvasHeight;
  drawWidth = drawHeight * imageAspect;

drawHeightをcanvasの高さに合わせ、imageAspectから画像の幅を求める。

見える範囲を真ん中にするため、drawXをずらす。

同様に高さも。

パフォーマンス - Paintng

PaintingフェーズはPaint,Rasterize,CompositeLayersに分かれる。

  • Paint
    描画の命令をレイヤーごとに生成。
    ここがパフォーマンスのボトルネックになることはほぼない。
  • Rasterize
    命令を実行して描画。
  • CompositeLayers
    レイヤーを一枚に合成。

インタラクションのたびにPaintingは引き起こされる。
これを再描画(Repaint)という。

検証ツールで3点アイコン>レンダリング>ペイント点滅 で再ペイントにチェックを入れると可視化できる

再描画が引き起こされるとき

  • その前のLayoutが引き起こされるとき
  • Layoutが引き起こされないCSSプロパティ変更により、Paintから再描画
    colorなど
  • cssのopacityかtransformアニメーションによりCompositeLayersのみ再描画

特に最後はCompositeLayersだけで再描画が終わるため、コスト軽。
opacityかtransformプロパティを変更してアニメーション実装はよい。

感想

やばい、YouTubeなしでは机に向かえない。明日休むか?

Oh,no. I can't sit at my desc without YouTube. Maybe I take a day off tomorrow.