akari-video 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -62,7 +62,7 @@ v1.1(2026-10-02)では pattern に限り `id` に `heart` / `thunder` を追
|
|
|
62
62
|
|
|
63
63
|
## 3. 柄の定義と変換元
|
|
64
64
|
|
|
65
|
-
初期 7 id の図形、タイルの位相・基準寸法・重ね順は素材側 `assets/overlay/telop-pattern-*/fragment.html` の `--i-fill` と SVG データ URI を正本として固定する。`diamond`
|
|
65
|
+
初期 7 id の図形、タイルの位相・基準寸法・重ね順は素材側 `assets/overlay/telop-pattern-*/fragment.html` の `--i-fill` と SVG データ URI を正本として固定する。`diamond` は 45deg / -45deg の筋(各 2px / 13px 周期、`fg` 32%)を菱形 SVG(幅 26px、図形 opacity .5)の上に重ねる。`dot` は 16px タイルの radial 2 層で、中心 (8,8) は 2→3px のフェードと `fg` 50%、中心 (0,0) は 1.6→2.6px のフェードと `fg` 35% を持つ。`gingham` は 90deg / 0deg の格子 2 層(各 9px / 22px 周期、`fg` 55%)で、0deg 層は下端起点、交差部の合成 opacity は .7975 とする。`stripe` は帯、`skull` は髑髏、`hazard` は警告三角、`night` は星点と星形を持つ。描画側は id から固定テンプレートを選び、検証済み `fg` / `bg` と `scale` を埋めて自己完結した CSS 画像を作る。これら 3 柄の筋・水玉・格子は fragment と同じ CSS gradient 層で作り、菱形だけ SVG データ URI を使う。同じ id と 3 値は 4 経路で同じ画素入力とする。素材の多色グラデや複数の独立した色を単一 `fg` / `bg` に縮約できないときは、変換プリセットに別の展開済み色を追加する改訂契約を起こすか §9 の残留とする。CSS `mask` による切り抜きはこの v1 pattern に含めない。
|
|
66
66
|
|
|
67
67
|
v1.1 の `heart` / `thunder` は別の正本 URI を §11 で追加する。透過柄の下に `bg` のグラデーションを敷く 2 層合成を用いるため、上記の 2 色縮約条件はこの 2 id には適用しない。
|
|
68
68
|
|
|
@@ -263,14 +263,14 @@ TODO(B-2 所有外): インスペクタの「文字色」操作は `fill`
|
|
|
263
263
|
|
|
264
264
|
## 11. v1.1(2026-10-02)
|
|
265
265
|
|
|
266
|
-
素材側の仕分けで、`telop-pop-heart`
|
|
266
|
+
素材側の仕分けで、`telop-pop-heart` は地がグラデーション、`telop-pop-thunder` は地が繰り返し縞(`repeating-linear-gradient`)であり、単色 `pattern.bg` では原画を表せないと確定した。v1.1 の `thunder` は縞を 2 色グラデーションで近似する。`pattern.bg` の gradient は保存時に停止点と角度を展開し、描画時は `background-image: <透過 pattern SVG>, linear-gradient(...)` の順に合成する。**`diamond` / `dot` / `gingham` 以外の `bg` 文字列は v1 の 1 層(SVG 内の `<rect>`)をバイト不変で維持し、2 層は `bg` がグラデーションオブジェクトのときだけ使う。**3 柄は §3 の CSS gradient 層を保つため、`bg` が文字列でも最背面に単色の CSS gradient を敷く。第 1 層のサイズは基準タイル × `scale`、地のグラデーションは行全体の描画矩形とする。各層の位置は行の共通原点に合わせ、`words[]` 分割後も位相を戻さない。透過 SVG に地色を焼き込まない。
|
|
267
267
|
|
|
268
268
|
| 項目 | v1 | v1.1 |
|
|
269
269
|
|---|---|---|
|
|
270
270
|
| `pattern.id` enum | `diamond` / `dot` / `stripe` / `gingham` / `skull` / `hazard` / `night` | 左記に `heart` / `thunder` を追加 |
|
|
271
271
|
| `pattern.bg` の型 | `hexColor` 文字列 | `hexColor` 文字列または `{stops,angle_deg}` |
|
|
272
272
|
| `fg` の alpha | `hexColor` の `#RRGGBBAA` を受理 | 9 id とも SVG の `fill` に alpha を保持し、図形固有の opacity と合成 |
|
|
273
|
-
| CSS 合成式 `background-image` | `url("<rect を持つ pattern SVG>")` の 1 層 | `bg`
|
|
273
|
+
| CSS 合成式 `background-image` | `url("<rect を持つ pattern SVG>")` の 1 層 | `diamond` / `dot` / `gingham` は §3 の CSS gradient 層 + 地の CSS gradient。他の id は `bg` 文字列で v1 とバイト一致し、`bg` グラデのみ `<透過 pattern>, linear-gradient(...)` の 2 層 |
|
|
274
274
|
| 位相・タイル寸法 | 初期 7 id の既定タイルと位相 | `heart` は 14px、`thunder` は 30px。`thunder` の位相は 4px 2px。1 層は位置 1 組・サイズ 1 組、2 層は位置 2 組・サイズはタイルと行全体 |
|
|
275
275
|
| 対象外の `night` / `skull` / `stripe` | id は受理 | 素材の textstyle 変換は対象外。`night` は星点が別色、`skull` は SVG 2 色、`stripe` は独立した斜線グラデーションが必要 |
|
|
276
276
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。 [akari-video npm vendor: bin/akari.mjs is reference-only. These CLI entrypoints are not included in the akari-video npm package. Use `akari doctor --json` and run the path reported in `render_cut.path`. Full installations provide it in a monorepo checkout, ~/.akari/app, /Applications/AKARI Video.app/Contents/Resources/packages, or %LOCALAPPDATA%\\Programs\\@akari-videoshell\\resources\\packages.]",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -50,7 +50,9 @@ function alignCaptionRichFillPhase(root) {
|
|
|
50
50
|
const gradient = fillType === 'gradient';
|
|
51
51
|
const pattern = fillType === 'pattern';
|
|
52
52
|
const patternGradient = pattern && root.getAttribute('data-rich-pattern-bg') === 'gradient';
|
|
53
|
-
const
|
|
53
|
+
const patternId = root.getAttribute('data-rich-pattern-id');
|
|
54
|
+
const thunder = patternId === 'thunder';
|
|
55
|
+
const fragmentPattern = pattern && (patternId === 'diamond' || patternId === 'dot' || patternId === 'gingham');
|
|
54
56
|
for (const line of root.querySelectorAll('.akari-caption__line,.akari-caption__resolved-line')) {
|
|
55
57
|
const lineRect = line.getBoundingClientRect();
|
|
56
58
|
for (const fill of line.querySelectorAll('.akari-caption__rich-fill')) {
|
|
@@ -58,6 +60,18 @@ function alignCaptionRichFillPhase(root) {
|
|
|
58
60
|
const x = Number((lineRect.left - rect.left).toFixed(3));
|
|
59
61
|
const y = Number((lineRect.top - rect.top).toFixed(3));
|
|
60
62
|
const patternPosition = `${Number((x + (thunder ? 4 : 0)).toFixed(3))}px ${Number((y + (thunder ? 2 : 0)).toFixed(3))}px`;
|
|
63
|
+
if (fragmentPattern) {
|
|
64
|
+
const position = `${x}px ${y}px`;
|
|
65
|
+
const sizes = globalThis.getComputedStyle(fill).backgroundSize.split(',').map((part) => part.trim());
|
|
66
|
+
const halfTile = Number.parseFloat(sizes[0]) / 2;
|
|
67
|
+
const positions = patternId === 'diamond' ? [position, position, position, position]
|
|
68
|
+
: patternId === 'dot' ? [position, `${Number((x + halfTile).toFixed(3))}px ${Number((y + halfTile).toFixed(3))}px`, position]
|
|
69
|
+
: [position, position, position];
|
|
70
|
+
fill.style.setProperty('--caption-rich-fill-position', positions.join(', '));
|
|
71
|
+
const lineSize = `${Number(lineRect.width.toFixed(3))}px ${Number(lineRect.height.toFixed(3))}px`;
|
|
72
|
+
fill.style.setProperty('--caption-rich-fill-size', sizes.map((size) => size === '100% 100%' ? lineSize : size).join(', '));
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
61
75
|
fill.style.setProperty('--caption-rich-fill-position', patternGradient
|
|
62
76
|
? `${patternPosition}, ${x}px ${y}px`
|
|
63
77
|
: pattern ? patternPosition : `${x}px ${y}px`);
|
|
@@ -1850,10 +1864,10 @@ function readMetallicHue(stops) {
|
|
|
1850
1864
|
? { hue, variant } : null;
|
|
1851
1865
|
}
|
|
1852
1866
|
const RICH_PATTERN_SHAPES = {
|
|
1853
|
-
diamond: { size: 46, viewBox: 24, shape: '<path d="M12 2 21 12 12 22 3 12z" fill="FG" fill-opacity=".5"
|
|
1854
|
-
dot: { size: 16, viewBox: 16, shape: '
|
|
1867
|
+
diamond: { size: 26, svgSize: 46, viewBox: 24, shape: '<path d="M12 2 21 12 12 22 3 12z" fill="FG" fill-opacity="0.5"/>' },
|
|
1868
|
+
dot: { size: 16, viewBox: 16, shape: '' },
|
|
1855
1869
|
stripe: { size: 14, viewBox: 14, shape: '<path d="M0 0h14v7H0z" fill="FG"/>' },
|
|
1856
|
-
gingham: { size: 22, viewBox: 22, shape: '
|
|
1870
|
+
gingham: { size: 22, viewBox: 22, shape: '' },
|
|
1857
1871
|
skull: { size: 30, viewBox: 24, shape: '<g fill="FG" fill-opacity=".9"><circle cx="12" cy="10" r="6.5"/><rect x="8.5" y="14" width="7" height="4.5" rx="1.5"/></g><circle cx="9.6" cy="9.6" r="1.7" fill="BG"/><circle cx="14.4" cy="9.6" r="1.7" fill="BG"/><path d="M12 12l-1.2 2.1h2.4z" fill="BG"/>' },
|
|
1858
1872
|
hazard: { size: 22, viewBox: 24, shape: '<polygon points="12,5 20,19 4,19" fill="FG" fill-opacity=".85"/>' },
|
|
1859
1873
|
night: { size: 26, viewBox: 26, shape: '<circle cx="4" cy="6" r="1.2" fill="FG"/><circle cx="19" cy="21" r="1.1" fill="FG"/><path d="M16 3l1.5 4.5L22 9l-4.5 1.5L16 15l-1.5-4.5L10 9l4.5-1.5z" fill="FG"/>' },
|
|
@@ -1886,7 +1900,7 @@ function richPatternImage(pattern, layered) {
|
|
|
1886
1900
|
const template = RICH_PATTERN_SHAPES[pattern.id];
|
|
1887
1901
|
const rect = layered ? '' : `<rect width="100%" height="100%" fill="${pattern.bg}"/>`;
|
|
1888
1902
|
const bg = layered ? 'transparent' : pattern.bg;
|
|
1889
|
-
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${template.size}" height="${template.size}" viewBox="0 0 ${template.viewBox} ${template.viewBox}">${rect}${template.shape.replace(/FG/g, pattern.fg).replace(/BG/g, bg)}</svg>`;
|
|
1903
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${template.svgSize ?? template.size}" height="${template.svgSize ?? template.size}" viewBox="0 0 ${template.viewBox} ${template.viewBox}">${rect}${template.shape.replace(/FG/g, pattern.fg).replace(/BG/g, bg)}</svg>`;
|
|
1890
1904
|
return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
|
|
1891
1905
|
}
|
|
1892
1906
|
function resolveCaptionRichFillVars(fill, scale = 1) {
|
|
@@ -1902,6 +1916,42 @@ function resolveCaptionRichFillVars(fill, scale = 1) {
|
|
|
1902
1916
|
const bg = pattern.bg;
|
|
1903
1917
|
const tile = formatCssNumber(RICH_PATTERN_SHAPES[pattern.id].size * pattern.scale * scale);
|
|
1904
1918
|
const offset = pattern.id === 'thunder' ? '4px 2px' : '0 0';
|
|
1919
|
+
if (pattern.id === 'diamond' || pattern.id === 'dot' || pattern.id === 'gingham') {
|
|
1920
|
+
const factor = pattern.scale * scale;
|
|
1921
|
+
const px = (value) => `${formatCssNumber(value * factor)}px`;
|
|
1922
|
+
const fg = pattern.fg;
|
|
1923
|
+
const tint = (percent) => `color-mix(in srgb, ${fg} ${percent}%, transparent)`;
|
|
1924
|
+
const ground = typeof bg === 'string' ? `linear-gradient(${bg}, ${bg})`
|
|
1925
|
+
: `linear-gradient(${bg.angle_deg}deg, ${bg.stops.map(stop => `${stop.color} ${stop.at}%`).join(', ')})`;
|
|
1926
|
+
const stripe = (angle, width, period, alpha) => `repeating-linear-gradient(${angle}deg, ${tint(alpha)} 0 ${px(width)}, transparent ${px(width)} ${px(period)})`;
|
|
1927
|
+
let images;
|
|
1928
|
+
let sizes;
|
|
1929
|
+
let positions;
|
|
1930
|
+
if (pattern.id === 'diamond') {
|
|
1931
|
+
images = [stripe(45, 2, 13, 32), stripe(-45, 2, 13, 32), richPatternImage(pattern, true)];
|
|
1932
|
+
sizes = ['100% 100%', '100% 100%', `${tile}px ${tile}px`];
|
|
1933
|
+
positions = ['0 0', '0 0', '0 0'];
|
|
1934
|
+
}
|
|
1935
|
+
else if (pattern.id === 'dot') {
|
|
1936
|
+
images = [
|
|
1937
|
+
`radial-gradient(circle, ${tint(50)} ${px(2)}, transparent ${px(3)})`,
|
|
1938
|
+
`radial-gradient(circle, ${tint(35)} ${px(1.6)}, transparent ${px(2.6)})`
|
|
1939
|
+
];
|
|
1940
|
+
sizes = [`${tile}px ${tile}px`, `${tile}px ${tile}px`];
|
|
1941
|
+
positions = ['0 0', `${px(8)} ${px(8)}`];
|
|
1942
|
+
}
|
|
1943
|
+
else {
|
|
1944
|
+
images = [stripe(90, 9, 22, 55), stripe(0, 9, 22, 55)];
|
|
1945
|
+
sizes = ['100% 100%', '100% 100%'];
|
|
1946
|
+
positions = ['0 0', '0 0'];
|
|
1947
|
+
}
|
|
1948
|
+
return {
|
|
1949
|
+
'--caption-rich-fill-color': 'transparent',
|
|
1950
|
+
'--caption-rich-fill-image': [...images, ground].join(', '),
|
|
1951
|
+
'--caption-rich-fill-size': [...sizes, '100% 100%'].join(', '),
|
|
1952
|
+
'--caption-rich-fill-position': [...positions, '0 0'].join(', ')
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1905
1955
|
if (typeof bg === 'string')
|
|
1906
1956
|
return {
|
|
1907
1957
|
'--caption-rich-fill-color': 'transparent',
|
|
@@ -5839,10 +5839,10 @@ var AkariEditKernel = (() => {
|
|
|
5839
5839
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
5840
5840
|
}
|
|
5841
5841
|
var RICH_PATTERN_SHAPES = {
|
|
5842
|
-
diamond: { size: 46, viewBox: 24, shape: '<path d="M12 2 21 12 12 22 3 12z" fill="FG" fill-opacity=".5"
|
|
5843
|
-
dot: { size: 16, viewBox: 16, shape:
|
|
5842
|
+
diamond: { size: 26, svgSize: 46, viewBox: 24, shape: '<path d="M12 2 21 12 12 22 3 12z" fill="FG" fill-opacity="0.5"/>' },
|
|
5843
|
+
dot: { size: 16, viewBox: 16, shape: "" },
|
|
5844
5844
|
stripe: { size: 14, viewBox: 14, shape: '<path d="M0 0h14v7H0z" fill="FG"/>' },
|
|
5845
|
-
gingham: { size: 22, viewBox: 22, shape:
|
|
5845
|
+
gingham: { size: 22, viewBox: 22, shape: "" },
|
|
5846
5846
|
skull: { size: 30, viewBox: 24, shape: '<g fill="FG" fill-opacity=".9"><circle cx="12" cy="10" r="6.5"/><rect x="8.5" y="14" width="7" height="4.5" rx="1.5"/></g><circle cx="9.6" cy="9.6" r="1.7" fill="BG"/><circle cx="14.4" cy="9.6" r="1.7" fill="BG"/><path d="M12 12l-1.2 2.1h2.4z" fill="BG"/>' },
|
|
5847
5847
|
hazard: { size: 22, viewBox: 24, shape: '<polygon points="12,5 20,19 4,19" fill="FG" fill-opacity=".85"/>' },
|
|
5848
5848
|
night: { size: 26, viewBox: 26, shape: '<circle cx="4" cy="6" r="1.2" fill="FG"/><circle cx="19" cy="21" r="1.1" fill="FG"/><path d="M16 3l1.5 4.5L22 9l-4.5 1.5L16 15l-1.5-4.5L10 9l4.5-1.5z" fill="FG"/>' },
|
|
@@ -5871,7 +5871,7 @@ var AkariEditKernel = (() => {
|
|
|
5871
5871
|
const template = RICH_PATTERN_SHAPES[pattern.id];
|
|
5872
5872
|
const rect = layered ? "" : `<rect width="100%" height="100%" fill="${pattern.bg}"/>`;
|
|
5873
5873
|
const bg = layered ? "transparent" : pattern.bg;
|
|
5874
|
-
const svg2 = `<svg xmlns="http://www.w3.org/2000/svg" width="${template.size}" height="${template.size}" viewBox="0 0 ${template.viewBox} ${template.viewBox}">${rect}${template.shape.replace(/FG/g, pattern.fg).replace(/BG/g, bg)}</svg>`;
|
|
5874
|
+
const svg2 = `<svg xmlns="http://www.w3.org/2000/svg" width="${template.svgSize ?? template.size}" height="${template.svgSize ?? template.size}" viewBox="0 0 ${template.viewBox} ${template.viewBox}">${rect}${template.shape.replace(/FG/g, pattern.fg).replace(/BG/g, bg)}</svg>`;
|
|
5875
5875
|
return `url("data:image/svg+xml,${encodeURIComponent(svg2)}")`;
|
|
5876
5876
|
}
|
|
5877
5877
|
function resolveCaptionRichFillVars(fill, scale = 1) {
|
|
@@ -5886,6 +5886,39 @@ var AkariEditKernel = (() => {
|
|
|
5886
5886
|
const bg = pattern.bg;
|
|
5887
5887
|
const tile = formatCssNumber(RICH_PATTERN_SHAPES[pattern.id].size * pattern.scale * scale);
|
|
5888
5888
|
const offset = pattern.id === "thunder" ? "4px 2px" : "0 0";
|
|
5889
|
+
if (pattern.id === "diamond" || pattern.id === "dot" || pattern.id === "gingham") {
|
|
5890
|
+
const factor = pattern.scale * scale;
|
|
5891
|
+
const px = (value) => `${formatCssNumber(value * factor)}px`;
|
|
5892
|
+
const fg = pattern.fg;
|
|
5893
|
+
const tint = (percent) => `color-mix(in srgb, ${fg} ${percent}%, transparent)`;
|
|
5894
|
+
const ground = typeof bg === "string" ? `linear-gradient(${bg}, ${bg})` : `linear-gradient(${bg.angle_deg}deg, ${bg.stops.map((stop) => `${stop.color} ${stop.at}%`).join(", ")})`;
|
|
5895
|
+
const stripe = (angle, width, period, alpha) => `repeating-linear-gradient(${angle}deg, ${tint(alpha)} 0 ${px(width)}, transparent ${px(width)} ${px(period)})`;
|
|
5896
|
+
let images;
|
|
5897
|
+
let sizes;
|
|
5898
|
+
let positions;
|
|
5899
|
+
if (pattern.id === "diamond") {
|
|
5900
|
+
images = [stripe(45, 2, 13, 32), stripe(-45, 2, 13, 32), richPatternImage(pattern, true)];
|
|
5901
|
+
sizes = ["100% 100%", "100% 100%", `${tile}px ${tile}px`];
|
|
5902
|
+
positions = ["0 0", "0 0", "0 0"];
|
|
5903
|
+
} else if (pattern.id === "dot") {
|
|
5904
|
+
images = [
|
|
5905
|
+
`radial-gradient(circle, ${tint(50)} ${px(2)}, transparent ${px(3)})`,
|
|
5906
|
+
`radial-gradient(circle, ${tint(35)} ${px(1.6)}, transparent ${px(2.6)})`
|
|
5907
|
+
];
|
|
5908
|
+
sizes = [`${tile}px ${tile}px`, `${tile}px ${tile}px`];
|
|
5909
|
+
positions = ["0 0", `${px(8)} ${px(8)}`];
|
|
5910
|
+
} else {
|
|
5911
|
+
images = [stripe(90, 9, 22, 55), stripe(0, 9, 22, 55)];
|
|
5912
|
+
sizes = ["100% 100%", "100% 100%"];
|
|
5913
|
+
positions = ["0 0", "0 0"];
|
|
5914
|
+
}
|
|
5915
|
+
return {
|
|
5916
|
+
"--caption-rich-fill-color": "transparent",
|
|
5917
|
+
"--caption-rich-fill-image": [...images, ground].join(", "),
|
|
5918
|
+
"--caption-rich-fill-size": [...sizes, "100% 100%"].join(", "),
|
|
5919
|
+
"--caption-rich-fill-position": [...positions, "0 0"].join(", ")
|
|
5920
|
+
};
|
|
5921
|
+
}
|
|
5889
5922
|
if (typeof bg === "string") return {
|
|
5890
5923
|
"--caption-rich-fill-color": "transparent",
|
|
5891
5924
|
"--caption-rich-fill-image": richPatternImage(pattern, false),
|