🔮 me:DERU

Extensible Multi-EFX Engine — Manual拡張型マルチEFXエンジン — マニュアル

Part of mederu Ateliermederu Atelier の一部

me:DERU is an extensible multi-EFX engine with two processing modes — pick the one that fits your workflow. me:DERU は拡張型マルチEFXエンジンです。2つの方式で画像を加工できます。

ModeモードStyleスタイル
🎨DERULayer-based compositing — linear, intuitiveレイヤー合成 — 直線的、直感的
🧩NODENode graph pipeline — flexible, powerfulノードグラフ — 自由度が高い、強力

📑 Table of Contents📑 目次

📐 me:DERU Architecture📐 me:DERU アーキテクチャ

flowchart LR
    DRAW["✏️ DRAW\n(velvet.html)"] -->|📸 Snapshot| LIB["📸 LIBRARY\n(IndexedDB)"]
    subgraph MEDERU["🔮 me:DERU"]
        DERU["🎨 DERU\nLayer Compositing"]
        NODE["🧩 NODE\nGraph Pipeline"]
    end
    LIB -->|"Select image"| DERU
    LIB -->|"Select / L key"| NODE
    DERU <-->|"Shared LIBRARY"| NODE
    DERU -->|Export| POST["📮 POST\nMint / Share"]
    NODE -->|"S key / Output"| POST

me:DERU is the extensible multi-EFX engine within mederu Atelier. It offers two modes — DERU for intuitive layer-based compositing, and NODE for flexible graph-based pipelines. Both share the same LIBRARY and EFX modules, which are fully plugin-based.me:DERU は mederu Atelier の拡張型マルチEFXエンジンです。DERU(直感的なレイヤー合成)と NODE(自由度の高いグラフパイプライン)の2つのモードを提供します。LIBRARYとEFXモジュールは共通で、プラグイン方式で拡張可能です。


🎨 DERU Mode — Layer Compositing🎨 DERU モード — レイヤー合成

DERU mode is a layer-based image compositing engine. Stack multiple images as layers, apply EFX chains to each, and composite them together.DERU モードはレイヤーベースの画像合成エンジンです。複数の画像をレイヤーとして重ね、各レイヤーに EFX チェーンを適用して合成します。

flowchart TD
    A["📸 Select from LIBRARY"] --> B["📚 Add as Layer"]
    B --> C["🎛️ Add EFX Chain"]
    C --> D["Adjust Parameters"]
    D --> E["🔄 Real-time Preview"]
    E --> F{"Satisfied?"}
    F -->|No| C
    F -->|Yes| G["📤 Export → POST"]

Mode Tabsモード切替

TabDescription説明
🎛️ LAYERSLayer compositing mode — stack images and apply EFXレイヤー合成モード。画像を重ねてEFX適用
🎞️ GIFGIF animation creation modeGIFアニメーション作成モード

⌨️ DERU Keyboard Shortcuts⌨️ DERU キーボードショートカット

KeyキーAction機能
HToggle help panelヘルプパネル 表示/非表示
Space[GIF] Play / Pause animation[GIF] 再生/一時停止
Delete / ⌫[GIF] Remove current frame[GIF] 現在のフレーム削除
EscapeClose help / modalsヘルプ/モーダルを閉じる

📚 LAYERS Section📚 LAYERS セクション

Action操作Method方法
Add layerレイヤー追加Click LIBRARY thumbnail or ➕ Add LayerLIBRARY の画像クリック or ➕ Add Layer
Select layerレイヤー選択Click layer rowレイヤー行をクリック
Show / Hide表示/非表示👁️ / 🚫
Delete layerレイヤー削除🗑️ Delete Layer
Collapse sectionセクション折りたたみClick section titleセクションタイトルクリック

Layer Orderレイヤー表示順序

Layer Parametersレイヤーパラメータ

ParameterパラメータDescription説明
Opacity0–100%
Blend Modenormal · multiply · screen · overlay · difference · color-dodge · color-burn · hard-light · soft-light

📸 LIBRARY Section📸 LIBRARY セクション

Action操作Method方法
Add as layerレイヤーとして追加Click thumbnailサムネイルクリック
Delete individual個別削除Hover → ✕ buttonサムネイルにホバー → ✕
Clear all全削除🗑️ Clear All (shown when 2+ frames)🗑️ Clear All (2個以上で表示)
Import images画像インポート📁 Import
Collapse折りたたみClick titleタイトルクリック

🎛️ EFX Chain🎛️ EFX チェーン

Apply effects as a chain to the selected layer. Effects are processed in order.選択中のレイヤーに対してエフェクトをチェーン(連鎖)で適用できます。

flowchart LR
    SRC["Source Image"] --> E1["EFX 1\nColor Adjust"]
    E1 --> E2["EFX 2\nMelt"]
    E2 --> E3["EFX 3\nNoise"]
    E3 --> OUT["Output"]
Action操作Method方法
Add EFXEFX 追加➕ Add Effect
Remove EFXEFX 削除
Toggle ON/OFFEFX ON/OFFClick EFX nameEFX名クリック

🎞️ GIF Mode🎞️ GIF モード

Action操作Method方法
Select framesフレーム選択Click LIBRARY thumbnails (checkmark)LIBRARYのサムネイルをクリック
Add to timelineタイムラインに追加➕ Add Selected
Frame delayフレーム遅延Delay slider per frame各フレームの delay スライダー
Play direction再生方向forward / reverse / pingpong

🌊 Auto-Motion Presets🌊 Auto-Motion プリセット

Generate GIF animations from a single image automatically:単一画像からGIFアニメーションを自動生成:

PresetプリセットIconDescription説明
Wave H🌊Horizontal wave distortion水平方向の波形変形
Wave V🌊Vertical wave distortion垂直方向の波形変形
Squishy🫠Squish & stretch bounce伸び縮みバウンス
3D Spin🔄Pseudo-3D card flip疑似3Dカード回転
Spiral🌀Rotate + scale spiral回転+スケールスパイラル
BounceVertical bouncing垂直バウンス
Trail👻Ghost trail effectゴーストトレイル
Pulse💫Pulsing scale脈動スケール

Parameters: Amplitude (strength), Frequency (cycles), Speedパラメータ: Amplitude(強度), Frequency(サイクル数), Speed(速度)


🧩 NODE Mode — Graph Pipeline🧩 NODE モード — グラフパイプライン

NODE mode is a node-graph-based image processing pipeline. Connect nodes with wires to build your processing flow.NODE モードはノードグラフベースの画像処理パイプラインです。ノード同士を線で繋いで処理フローを構築します。

flowchart TD
    A["Tab / A to open palette"] --> B["Add nodes"]
    B --> C["Connect ports with wires"]
    C --> D["Load image: D&D / click / L key"]
    D --> E["Adjust parameters"]
    E --> F{"Auto mode?"}
    F -->|Yes| G["🔄 Auto-execute\n600ms debounce"]
    F -->|No| H["E / Enter to execute"]
    G --> I["Preview updates"]
    H --> I
    I --> J["S to send to POST"]

⌨️ NODE Keyboard Shortcuts⌨️ NODE キーボードショートカット

※ Case-insensitive — works with CapsLock ON※ 大文字・小文字どちらでも動作します (CapsLock OK)

KeyキーAction機能
HToggle help panelヘルプパネル 表示/非表示
Tab / AToggle Add Node paletteAdd Node パレット 表示/非表示
LToggle LIBRARY popup (select Source image)LIBRARY ポップアップ(Source画像選択)
E / EnterExecute graph pipelineグラフ実行
SSave — export output to POSTSave — 出力画像を POST に送る
Delete / Delete selected node or edge選択中のノード/エッジを削除
EscapeClose all panels / deselect全パネルを閉じる / 選択解除
FFit view (zoom to show all nodes)ビューをフィット

🖱️ Mouse Controls🖱️ マウス操作

Action操作Method方法
Move nodeノード移動Drag nodeノードをドラッグ
Connect接続Drag port ● → port ●ポート●からポート●へドラッグ
Select edgeエッジ選択Click wire線をクリック
Load image画像読込D&D / click Source / L for LIBRARYD&D / クリック / L でLIBRARY
ZoomズームMouse wheelマウスホイール
PanパンDrag background背景をドラッグ
Zoom previewプレビュー拡大Click EFX node preview imageEFXノードのプレビュー画像をクリック

📦 Node Types📦 ノードタイプ

flowchart LR
    subgraph UTILITY["🔧 UTILITY"]
        SRC["🖼️ Source\nImage Input"]
        BLD["🔀 Blend\nCompositing"]
        OUT["📤 Output\nFinal Result"]
    end
    subgraph EFX["🎛️ EFX"]
        FLT["🟣 Filter"]
        DST["🔵 Distortion"]
        GEN["🟡 Generative"]
    end
    SRC --> FLT --> DST --> OUT
    SRC --> BLD --> OUT
NodeColorDescription説明
🖼️ Source🟢Image input — D&D, click, or L key画像入力。D&D / クリック / L でLIBRARY
🔀 Blend🟠Mix 2 inputs (multiply, screen, overlay…)2つの入力を合成
📤 Output🔴Final output — ⛶ fullscreen preview最終出力先。⛶ で全画面プレビュー

🎛️ EFX Module Catalog🎛️ EFX モジュール一覧

🟣 FILTER 11

ModuleIconParametersDescription説明
Color Adjust🎨Brightness, Contrast, SaturationColor correction色調補正
Invert🔄Color inversion (negative)色反転(ネガ)
Posterize🖼️LevelsPosterizationポスタリゼーション
ThresholdLevelBlack & white binarize白黒二値化
Duotone🎭Shadow, HighlightDual-tone mappingダブルトーン
Gradient Map🌈Shadow, Mid, HighlightGradient mapグラデーションマップ
Lo-Fi📼Pixelate, Noise, ScanlinesRetro / VHS effectレトロ風加工
Color Shift🎨IntensityRandom hue shiftランダム色相シフト
Line Art✏️Threshold, ThicknessLine extraction線画抽出
ASCII Art🔤Size, DensityASCII art conversionASCIIアート変換
Line Edge✍️ThresholdEdge detectionエッジ検出

🔵 DISTORTION 9

ModuleIconParametersDescription説明
Melt🫠Intensity, Direction, DripMelt / dissolveメルト(溶解)
Transform🔄Scale, Rotate, X, YScale / rotate / translate変形
Feedback♾️Intensity, Zoom, RotateFeedback loopフィードバック
RGB Split🔴🟢🔵Red X/Y, Blue X/YRGB channel separationRGBチャンネル分離
RGB Glitch🌈IntensitySimple RGB glitch簡易RGBグリッチ
Slit Scan📊IntensitySlit scanスリットスキャン
Portrait Distort📐Intensity, SliceWidth, FreqVertical slice distortion縦スライス歪み
Horizontal Distort📏Intensity, SliceHeight, FreqHorizontal slice distortion横スライス歪み
Fragment Glitch💥Intensity, BlockSize, RandomnessFragment glitchフラグメントグリッチ

🟡 GENERATIVE 1

ModuleIconParametersDescription説明
Noise📺LevelAdd noiseノイズ付加

🔄 Auto / Manual Mode🔄 Auto / Manual モード

ModeモードButtonボタンBehavior動作
Auto🔄 AutoAuto-execute 600ms after parameter changeパラメータ変更後 600ms で自動実行
Manual⏸ ManualPress E / Enter to execute manuallyE / Enter キーで手動実行
For heavy effect chains, switch to Manual and execute once after adjusting all parameters.重いエフェクトチェーンでは Manual に切り替えて、調整完了後に一括実行すると効率的です。

📊 Execution Pipeline📊 実行パイプライン

flowchart TD
    subgraph Pipeline["Execution Pipeline"]
        direction TB
        S1["🖼️ Source 1"] --> E1["🎨 Color Adjust"]
        E1 --> E2["🫠 Melt"]
        S2["🖼️ Source 2"] --> BL["🔀 Blend"]
        E2 --> BL
        BL --> E3["📺 Noise"]
        E3 --> OUT["📤 Output"]
    end
Source node previews always show the original image (never overwritten by processing results). EFX / Blend / Output nodes show their processed result. Click any EFX preview to view full-size.Source ノードのプレビューは常に元画像を表示。EFX / Blend / Output は処理結果を表示。EFXのプレビューをクリックでフルサイズ表示。

🔧 DERU vs NODE🔧 DERU vs NODE の使い分け

🎨 me:DERU🧩 NODE
Workflow操作感Linear (top → down)直線的Free graph (node wiring)自由グラフ
Layersレイヤー✅ via Blend node✅ Blendノードで
EFX ChainEFXチェーンPer-layer chainレイヤーごとFree connections自由接続
PreviewプレビューReal-time autoリアルタイムAuto / Manual toggleAuto / Manual
GIFGIF作成✅ Timeline + Auto-Motion
LIBRARYAlways visible in sidebarサイドバーに常時表示L key popupL キーでポップアップ
Best for向いている用途Quick compositingシンプルな合成Complex pipelines複雑なパイプライン

📁 Adding EFX Modules — Developer Guide📁 EFX モジュール追加ガイド(開発者向け)

The EFX system is fully plugin-based. You can add a new image effect in 2 files and it will automatically appear in both DERU and NODE editors.EFXシステムは完全なプラグイン方式です。2ファイルの変更だけで新しいエフェクトがDERUとNODE両方に自動的に反映されます。

flowchart LR
    A["1. Create\nmodules/my-effect.ts"] --> B["2. Import + register in\nregistry.ts"]
    B --> C["3. Auto-appears in\nDERU 'Add Effect'\n& NODE palette"]
    C --> D["4. Parameters auto-generate\nslider / color / select UI"]

📋 File Structure📋 ファイル構造

// Project structure
src/lib/efx/
├── types.ts         // EFXModule, EFXParamDef, Frame, etc.
├── utils.ts         // loadImage, dataUrlToCanvas, generateThumbnail
├── registry.ts      // EFX_REGISTRY — master list of all modules
└── modules/
    ├── color.ts     // Color Adjust, Invert, Posterize, etc.
    ├── distortion.ts // Melt, Transform, Feedback, etc.
    ├── glitch.ts    // RGB Glitch, Slit Scan, Fragment, etc.
    ├── ascii.ts     // ASCII Art, Line Edge
    └── my-effect.ts // ← YOUR NEW MODULE

🔧 EFXModule Interface🔧 EFXModule インターフェース

Every module must implement this interface (defined in types.ts):すべてのモジュールは次のインターフェースを実装します(types.tsで定義):

interface EFXModule {
  id: string;              // Unique ID (kebab-case) e.g. 'my-sepia'
  name: string;            // Display name e.g. 'Sepia Tone'
  icon: string;            // Emoji icon e.g. '🟤'
  category: EFXCategory;   // 'filter' | 'distortion' | 'generative' | 'composite'
  params: EFXParamDef[];   // Parameter definitions → auto UI

  // REQUIRED: Process a single frame
  processFrame: (
    frame: Frame,                 // Input image (has .dataUrl)
    params: Record<string, any>,  // User-adjusted parameter values
    context: EFXContext,           // Canvas size, frame index, etc.
  ) => Promise<ProcessedFrameData>; // Return { dataUrl, thumbnail }

  // OPTIONAL: Batch processing (for transitions)
  processBatch?: (frames, params, ctx, onProgress?) => Promise<...>;

  // OPTIONAL: Low-res fast preview
  previewFrame?: (frame, params) => Promise<string>;
}

📝 Parameter Types📝 パラメータタイプ

Parameters you define in params[] automatically generate the corresponding UI controls:params[]に定義したパラメータは自動的に対応するUIコントロールを生成します:

typeUIRequired Fields必須フィールドExample
rangeSlidermin, max, step, default{ key:'amount', label:'Amount', type:'range', default:50, min:0, max:100 }
colorColor pickerdefault{ key:'tint', label:'Tint', type:'color', default:'#ff6b9d' }
selectDropdownoptions[], default{ key:'mode', label:'Mode', type:'select', default:'a', options:[{value:'a',label:'A'}] }
toggleCheckboxdefault{ key:'on', label:'Enable', type:'toggle', default:true }
numberNumber inputmin, max, default{ key:'count', label:'Count', type:'number', default:4, min:1, max:20 }

🛠️ Helper Utilities🛠️ ヘルパーユーティリティ

Available from ../utils — these handle common Canvas operations:../utilsから利用可能 — Canvas操作の共通処理:

FunctionDescription説明
dataUrlToCanvas(dataUrl, w, h)Load a data URL into a Canvas element, scaled to w×hdata URLをCanvasに読み込み、w×hにスケーリング
loadImage(dataUrl)Load data URL → HTMLImageElement (for thumbnail gen)data URL → HTMLImageElement(サムネイル生成用)
generateThumbnail(img, size)Create a thumbnail data URL (default 150px)サムネイルdata URLを生成(デフォルト150px)

✨ Example 1: Sepia Effect (Pixel Manipulation)✨ 例1: セピアエフェクト(ピクセル操作)

A complete, minimal module that manipulates pixel data directly:ピクセルデータを直接操作する最小限のモジュール:

// src/lib/efx/modules/sepia.ts
import type { EFXModule, Frame, EFXContext, ProcessedFrameData } from '../types';
import { loadImage, generateThumbnail, dataUrlToCanvas } from '../utils';

export const SepiaEFX: EFXModule = {
  id: 'sepia',
  name: 'Sepia Tone',
  icon: '🟤',
  category: 'filter',

  params: [
    { key: 'intensity', label: 'Intensity', type: 'range',
      default: 100, min: 0, max: 100, step: 1 },
  ],

  processFrame: async (
    frame: Frame,
    params: Record<string, any>,
    context: EFXContext,
  ): Promise<ProcessedFrameData> => {
    // 1. Load input into a canvas
    const canvas = await dataUrlToCanvas(
      frame.dataUrl, context.canvasWidth, context.canvasHeight
    );
    const ctx = canvas.getContext('2d')!;

    // 2. Get pixel data
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const d = imageData.data;
    const mix = params.intensity / 100;

    // 3. Apply sepia per pixel
    for (let i = 0; i < d.length; i += 4) {
      const r = d[i], g = d[i+1], b = d[i+2];
      const sr = r * 0.393 + g * 0.769 + b * 0.189;
      const sg = r * 0.349 + g * 0.686 + b * 0.168;
      const sb = r * 0.272 + g * 0.534 + b * 0.131;
      d[i]   = Math.min(255, r + (sr - r) * mix);
      d[i+1] = Math.min(255, g + (sg - g) * mix);
      d[i+2] = Math.min(255, b + (sb - b) * mix);
    }
    ctx.putImageData(imageData, 0, 0);

    // 4. Return result
    const dataUrl = canvas.toDataURL('image/png');
    const img = await loadImage(dataUrl);
    const thumbnail = generateThumbnail(img, 150);
    return { dataUrl, thumbnail };
  },
};

✨ Example 2: Vignette (Canvas Drawing API)✨ 例2: ビネット(Canvas描画API)

Using the makeModule shorthand helper (from color.ts pattern) for simpler Canvas-based effects:color.tsパターンの makeModule ショートハンドで、シンプルなCanvas描画エフェクト:

// Even shorter using makeModule (copy this pattern from color.ts)

function makeModule(id, name, icon, category, paramDefs, fn): EFXModule {
  return {
    id, name, icon, category,
    params: paramDefs,
    processFrame: async (frame, params, context) => {
      const canvas = await dataUrlToCanvas(
        frame.dataUrl, context.canvasWidth, context.canvasHeight
      );
      const ctx = canvas.getContext('2d')!;
      fn(ctx, canvas.width, canvas.height, params); // ← your logic here
      const dataUrl = canvas.toDataURL('image/png');
      const img = await loadImage(dataUrl);
      return { dataUrl, thumbnail: generateThumbnail(img, 150) };
    },
  };
}

// Vignette effect using makeModule shorthand
export const VignetteEFX = makeModule(
  'vignette', 'Vignette', '🔲', 'filter',
  [
    { key: 'strength', label: 'Strength', type: 'range',
      default: 50, min: 0, max: 100 },
    { key: 'color', label: 'Color', type: 'color',
      default: '#000000' },
  ],
  (ctx, w, h, p) => {
    const gradient = ctx.createRadialGradient(
      w/2, h/2, w * 0.2,  // inner circle
      w/2, h/2, w * 0.7,  // outer circle
    );
    gradient.addColorStop(0, 'transparent');
    gradient.addColorStop(1, p.color + Math.round(p.strength * 2.55)
      .toString(16).padStart(2, '0'));
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, w, h);
  },
);

🔌 Step 3: Register in registry.ts🔌 ステップ3: registry.tsに登録

// src/lib/efx/registry.ts

// Add import at the top:
import { SepiaEFX } from './modules/sepia';
import { VignetteEFX } from './modules/vignette';

// Add to EFX_REGISTRY array:
export const EFX_REGISTRY: EFXModule[] = [
  // ... existing modules ...
  ColorAdjustEFX,
  InvertEFX,

  // ── Your new modules ──
  SepiaEFX,       // ← just add here!
  VignetteEFX,    // ← done!
];
That's it — no other changes needed. Your module will automatically appear in:
• DERU → "Add Effect" dropdown
• NODE → Add Node palette (under the matching category)
• Parameter sliders/pickers are auto-generated from your params[] definition.
以上で完了 — 他の変更は不要です。モジュールは自動的に以下に反映されます:
• DERU → 「Add Effect」ドロップダウン
• NODE → Add Node パレット(対応カテゴリに自動分類)
• パラメータのスライダー/ピッカーは params[] 定義から自動生成されます。

📐 Processing Pipeline Deep Dive📐 処理パイプラインの詳細

flowchart TD
    INPUT["frame.dataUrl\nPNG data URL string"] --> CANVAS["dataUrlToCanvas\nscaled to canvasWidth × canvasHeight"]
    CANVAS --> PROCESS["Your processing logic\ngetImageData / fillRect / drawImage"]
    PROCESS --> EXPORT["canvas.toDataURL\n→ full-size PNG data URL"]
    EXPORT --> THUMB["generateThumbnail\n→ 150px thumbnail"]
    THUMB --> RETURN["return { dataUrl, thumbnail }"]

💡 Tips & Best Practices💡 ヒントとベストプラクティス