@wasao/kagemusha 0.1.0 → 0.1.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/README.md CHANGED
@@ -18,7 +18,7 @@ When you push code, Kagemusha automatically captures screenshots of your app and
18
18
 
19
19
  ```bash
20
20
  # Install
21
- npm install -D kagemusha
21
+ npm install -D @wasao/kagemusha
22
22
 
23
23
  # Interactive setup (generates config, discovers pages, creates workflow)
24
24
  npx kagemusha init
@@ -1,6 +1,7 @@
1
1
  interface CaptureOptions {
2
2
  ids?: string;
3
3
  all?: boolean;
4
+ open?: boolean;
4
5
  }
5
6
  export declare function captureCommand(options: CaptureOptions): Promise<void>;
6
7
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC3E"}
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAkD3E"}
@@ -18,10 +18,21 @@ export async function captureCommand(options) {
18
18
  console.log(chalk.blue(`šŸ“ø Capturing ${definitions.length} screenshot(s)...`));
19
19
  const results = await captureScreenshots(config, definitions, projectRoot);
20
20
  console.log(chalk.blue("šŸŽØ Drawing annotations..."));
21
- await annotateScreenshots(definitions, results, projectRoot);
21
+ const annotated = await annotateScreenshots(definitions, results, projectRoot);
22
22
  console.log(chalk.bold.green(`\nāœ… Done! Screenshots saved to screenshots/\n`));
23
- for (const r of results) {
24
- console.log(chalk.gray(` ${r.id} → ${r.rawPath}`));
23
+ for (const r of annotated) {
24
+ console.log(chalk.gray(` ${r.id} → ${r.annotatedPath}`));
25
+ }
26
+ if (options.open) {
27
+ const { chromium } = await import("playwright-chromium");
28
+ const browser = await chromium.launch({ headless: false });
29
+ const context = await browser.newContext();
30
+ for (const result of annotated) {
31
+ const page = await context.newPage();
32
+ await page.goto(`file://${result.annotatedPath}`);
33
+ }
34
+ console.log(chalk.gray("\nPress Ctrl+C to close preview.\n"));
35
+ await new Promise(() => { });
25
36
  }
26
37
  }
27
38
  //# sourceMappingURL=capture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO1D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAElE,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC9D,OAAO;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,MAAM,mBAAmB,CAAC,CACjE,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAE3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,MAAM,mBAAmB,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAE7D,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,+CAA+C,CAAC,CACjE,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAQ1D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAElE,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC9D,OAAO;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,MAAM,mBAAmB,CAAC,CACjE,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAE3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAC1C,WAAW,EACX,OAAO,EACP,WAAW,CACX,CAAC;IAEF,OAAO,CAAC,GAAG,CACV,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,+CAA+C,CAAC,CACjE,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAE3C,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;AACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface EditOptions {
2
+ id?: string;
3
+ }
4
+ export declare function editCommand(options: EditOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"AAMA,UAAU,WAAW;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AAUD,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuHrE"}
@@ -0,0 +1,100 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import chalk from "chalk";
5
+ import { findProjectRoot, loadConfig, loadDefinitions } from "../lib/config.js";
6
+ const loadEditorScript = () => {
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+ const scriptPath = path.join(__dirname, "..", "editor", "inject-script.js");
9
+ return fs
10
+ .readFileSync(scriptPath, "utf-8")
11
+ .replace(/^export\s*\{\s*\};?\s*$/m, "");
12
+ };
13
+ export async function editCommand(options) {
14
+ console.log(chalk.bold("\n🄷 Kagemusha — Annotation Editor\n"));
15
+ const projectRoot = findProjectRoot();
16
+ const config = loadConfig(projectRoot);
17
+ let definitions = loadDefinitions(projectRoot);
18
+ if (options.id) {
19
+ definitions = definitions.filter((d) => d.id === options.id);
20
+ }
21
+ if (definitions.length === 0) {
22
+ console.log(chalk.red("No definitions found."));
23
+ return;
24
+ }
25
+ if (definitions.length > 1) {
26
+ const inquirer = await import("inquirer");
27
+ const { selected } = await inquirer.default.prompt({
28
+ type: "list",
29
+ name: "selected",
30
+ message: "Which page to edit?",
31
+ choices: definitions.map((d) => ({ name: d.id, value: d.id })),
32
+ });
33
+ definitions = definitions.filter((d) => d.id === selected);
34
+ }
35
+ const def = definitions[0];
36
+ const { chromium } = await import("playwright-chromium");
37
+ const browser = await chromium.launch({ headless: false });
38
+ const context = await browser.newContext({
39
+ viewport: {
40
+ width: config.screenshot.defaultViewport.width,
41
+ height: config.screenshot.defaultViewport.height,
42
+ },
43
+ });
44
+ const page = await context.newPage();
45
+ const urlPath = def.url.replace(/\{(\w+)\}/g, (_, key) => def.urlParams?.[key] ?? "");
46
+ const fullUrl = new URL(urlPath, config.app.baseUrl).toString();
47
+ console.log(chalk.blue(`🌐 Opening ${fullUrl}...`));
48
+ await page.goto(fullUrl, { waitUntil: "networkidle" });
49
+ if (def.hideElements?.length) {
50
+ for (const selector of def.hideElements) {
51
+ await page.evaluate((sel) => {
52
+ document.querySelectorAll(sel).forEach((el) => {
53
+ el.style.display = "none";
54
+ });
55
+ }, selector);
56
+ }
57
+ }
58
+ // Expose save function from Node.js to browser
59
+ const defPath = path.join(projectRoot, ".kagemusha/definitions", `${def.id}.json`);
60
+ let savedCount = 0;
61
+ let saveResolve;
62
+ const savePromise = new Promise((resolve) => {
63
+ saveResolve = resolve;
64
+ });
65
+ // Expose save function BEFORE injecting script
66
+ await page.exposeFunction("__kagemusha_save", (decorationsJson) => {
67
+ const decorations = JSON.parse(decorationsJson);
68
+ savedCount = decorations.length;
69
+ const updatedDef = { ...def, decorations };
70
+ fs.writeFileSync(defPath, `${JSON.stringify(updatedDef, null, 2)}\n`);
71
+ saveResolve();
72
+ });
73
+ // Set dpr BEFORE injecting script
74
+ const dpr = config.screenshot.defaultViewport.deviceScaleFactor ?? 2;
75
+ await page.evaluate((d) => {
76
+ window.__kagemusha_dpr = d;
77
+ }, dpr);
78
+ // Inject editor script and wait for it to fully load
79
+ const editorScript = loadEditorScript();
80
+ await page.evaluate(editorScript);
81
+ // Load existing annotations (script is now loaded)
82
+ if (def.decorations?.length) {
83
+ await page.evaluate((decs) => {
84
+ window.__kagemusha_loadAnnotations(decs);
85
+ }, def.decorations);
86
+ }
87
+ console.log(chalk.blue("šŸŽØ Editor ready. Draw annotations, then click Save.\n"));
88
+ // Wait for save or browser close
89
+ try {
90
+ await savePromise;
91
+ }
92
+ catch {
93
+ console.log(chalk.yellow("\n⚠ Editor closed without saving.\n"));
94
+ await browser.close().catch(() => { });
95
+ return;
96
+ }
97
+ await browser.close();
98
+ console.log(chalk.bold.green(`\nāœ… Saved ${savedCount} annotation(s) to ${defPath}\n`));
99
+ }
100
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAwQjD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAmQjD"}
@@ -90,22 +90,20 @@ export async function initCommand() {
90
90
  outputDir = dir;
91
91
  }
92
92
  else {
93
- const s3Answers = await inquirer.prompt([
94
- {
95
- type: "input",
96
- name: "cdnBucket",
97
- message: "S3 bucket name:",
98
- default: "kagemusha-screenshots",
99
- },
100
- {
101
- type: "input",
102
- name: "cdnBaseUrl",
103
- message: "S3 public URL base:",
104
- default: "https://kagemusha-screenshots.s3.ap-northeast-1.amazonaws.com",
105
- },
106
- ]);
107
- cdnBucket = s3Answers.cdnBucket;
108
- cdnBaseUrl = s3Answers.cdnBaseUrl;
93
+ const { bucket } = await inquirer.prompt({
94
+ type: "input",
95
+ name: "bucket",
96
+ message: "S3 bucket name:",
97
+ default: "kagemusha-screenshots",
98
+ });
99
+ cdnBucket = bucket;
100
+ const { url } = await inquirer.prompt({
101
+ type: "input",
102
+ name: "url",
103
+ message: "S3 public URL base:",
104
+ default: `https://${bucket}.s3.ap-northeast-1.amazonaws.com`,
105
+ });
106
+ cdnBaseUrl = url;
109
107
  }
110
108
  // Build config
111
109
  const config = {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,313 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Kagemusha Annotation Editor</title>
6
+ <style>
7
+ * { margin: 0; padding: 0; box-sizing: border-box; }
8
+ body { background: #1a1a2e; font-family: -apple-system, BlinkMacSystemFont, sans-serif; overflow: hidden; }
9
+
10
+ .toolbar {
11
+ position: fixed; top: 0; left: 0; right: 0; z-index: 100;
12
+ background: #16213e; padding: 8px 16px; display: flex; align-items: center; gap: 12px;
13
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
14
+ }
15
+ .toolbar button {
16
+ padding: 6px 14px; border: 1px solid #444; border-radius: 6px;
17
+ background: #1a1a2e; color: #fff; font-size: 13px; cursor: pointer;
18
+ }
19
+ .toolbar button:hover { background: #2a2a4e; }
20
+ .toolbar button.active { background: #6366f1; border-color: #6366f1; }
21
+ .toolbar .separator { width: 1px; height: 24px; background: #444; }
22
+ .toolbar .title { color: #888; font-size: 13px; margin-right: 8px; }
23
+ .toolbar .save-btn { background: #22c55e; border-color: #22c55e; font-weight: 600; margin-left: auto; }
24
+ .toolbar .save-btn:hover { background: #16a34a; }
25
+
26
+ .canvas-area {
27
+ margin-top: 48px; display: flex; justify-content: center; align-items: flex-start;
28
+ padding: 20px; height: calc(100vh - 48px); overflow: auto;
29
+ }
30
+
31
+ .editor-container {
32
+ position: relative; cursor: crosshair;
33
+ }
34
+ .editor-container img { display: block; width: 100%; height: auto; }
35
+
36
+ .annotation { position: absolute; }
37
+ .annotation.selected { outline: 2px dashed #6366f1; outline-offset: 2px; }
38
+
39
+ .label-input {
40
+ background: none; border: none; color: inherit; font: inherit;
41
+ width: 100%; outline: none;
42
+ }
43
+
44
+ .hint {
45
+ position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%);
46
+ color: #666; font-size: 12px;
47
+ }
48
+ </style>
49
+ </head>
50
+ <body>
51
+
52
+ <div class="toolbar">
53
+ <span class="title">🄷 Annotation Editor</span>
54
+ <button id="tool-rect" class="active" onclick="setTool('rect')">ā–­ Rectangle</button>
55
+ <button id="tool-arrow" onclick="setTool('arrow')">→ Arrow</button>
56
+ <button id="tool-label" onclick="setTool('label')">T Label</button>
57
+ <div class="separator"></div>
58
+ <button onclick="deleteSelected()">šŸ—‘ Delete</button>
59
+ <button class="save-btn" onclick="save()">šŸ’¾ Save</button>
60
+ </div>
61
+
62
+ <div class="canvas-area">
63
+ <div class="editor-container" id="editor">
64
+ <img id="screenshot" />
65
+ </div>
66
+ </div>
67
+
68
+ <div class="hint">Click and drag to add annotations. Click to select. Press Delete to remove.</div>
69
+
70
+ <script>
71
+ let tool = 'rect';
72
+ let annotations = [];
73
+ let selectedId = null;
74
+ let dragState = null;
75
+ let nextId = 1;
76
+
77
+ const editor = document.getElementById('editor');
78
+ const img = document.getElementById('screenshot');
79
+
80
+ // Mouse position relative to the editor container (in CSS px, matches display)
81
+ function getPos(e) {
82
+ const r = editor.getBoundingClientRect();
83
+ return { x: e.clientX - r.left, y: e.clientY - r.top };
84
+ }
85
+
86
+ // Ratio to convert display px → image natural px (for saving)
87
+ function getScale() {
88
+ return img.naturalWidth / editor.getBoundingClientRect().width;
89
+ }
90
+
91
+ window.initEditor = (screenshotDataUrl, existingDecorations) => {
92
+ img.src = screenshotDataUrl;
93
+ img.onload = () => {
94
+ // Set editor width to fit window
95
+ const maxW = window.innerWidth - 80;
96
+ const maxH = window.innerHeight - 108;
97
+ const ratio = img.naturalWidth / img.naturalHeight;
98
+ let w = maxW;
99
+ if (w / ratio > maxH) w = maxH * ratio;
100
+ editor.style.width = w + 'px';
101
+
102
+ if (existingDecorations) {
103
+ existingDecorations.forEach(d => addFromDecoration(d));
104
+ }
105
+ };
106
+ };
107
+
108
+ function setTool(t) {
109
+ tool = t;
110
+ document.querySelectorAll('.toolbar button').forEach(b => b.classList.remove('active'));
111
+ document.getElementById('tool-' + t)?.classList.add('active');
112
+ deselectAll();
113
+ }
114
+
115
+ function deselectAll() {
116
+ selectedId = null;
117
+ document.querySelectorAll('.annotation').forEach(el => el.classList.remove('selected'));
118
+ }
119
+
120
+ function selectEl(el) {
121
+ deselectAll();
122
+ selectedId = parseInt(el.dataset.id);
123
+ el.classList.add('selected');
124
+ }
125
+
126
+ function deleteSelected() {
127
+ if (!selectedId) return;
128
+ const el = document.querySelector(`[data-id="${selectedId}"]`);
129
+ if (el) el.remove();
130
+ annotations = annotations.filter(a => a.id !== selectedId);
131
+ selectedId = null;
132
+ }
133
+
134
+ document.addEventListener('keydown', e => {
135
+ if (e.key === 'Delete' || e.key === 'Backspace') {
136
+ if (document.activeElement.classList?.contains('label-input')) return;
137
+ deleteSelected();
138
+ }
139
+ });
140
+
141
+ // --- CREATE ---
142
+ editor.addEventListener('mousedown', e => {
143
+ if (e.target.closest('.annotation')) return;
144
+ const p = getPos(e);
145
+ deselectAll();
146
+
147
+ if (tool === 'rect') {
148
+ const id = nextId++;
149
+ const el = makeRect(id, p.x, p.y, 0, 0);
150
+ editor.appendChild(el);
151
+ dragState = { type: 'create-rect', id, el, sx: p.x, sy: p.y };
152
+ } else if (tool === 'arrow') {
153
+ const id = nextId++;
154
+ const el = makeArrow(id, p.x, p.y, p.x, p.y);
155
+ editor.appendChild(el);
156
+ dragState = { type: 'create-arrow', id, el, sx: p.x, sy: p.y };
157
+ } else if (tool === 'label') {
158
+ const id = nextId++;
159
+ annotations.push({ id, type: 'label', x: p.x, y: p.y, text: 'Label' });
160
+ const el = makeLabel(id, p.x, p.y, 'Label');
161
+ editor.appendChild(el);
162
+ selectEl(el);
163
+ el.querySelector('.label-input').focus();
164
+ el.querySelector('.label-input').select();
165
+ }
166
+ });
167
+
168
+ document.addEventListener('mousemove', e => {
169
+ if (!dragState) return;
170
+ const p = getPos(e);
171
+
172
+ if (dragState.type === 'create-rect') {
173
+ const el = dragState.el;
174
+ const w = p.x - dragState.sx;
175
+ const h = p.y - dragState.sy;
176
+ el.style.left = (w > 0 ? dragState.sx : p.x) + 'px';
177
+ el.style.top = (h > 0 ? dragState.sy : p.y) + 'px';
178
+ el.style.width = Math.abs(w) + 'px';
179
+ el.style.height = Math.abs(h) + 'px';
180
+ } else if (dragState.type === 'create-arrow') {
181
+ updateArrow(dragState.el, dragState.sx, dragState.sy, p.x, p.y);
182
+ } else if (dragState.type === 'move') {
183
+ const a = annotations.find(a => a.id === dragState.id);
184
+ if (!a) return;
185
+ a.x = p.x - dragState.ox;
186
+ a.y = p.y - dragState.oy;
187
+ dragState.el.style.left = a.x + 'px';
188
+ dragState.el.style.top = a.y + 'px';
189
+ }
190
+ });
191
+
192
+ document.addEventListener('mouseup', e => {
193
+ if (!dragState) return;
194
+ const p = getPos(e);
195
+
196
+ if (dragState.type === 'create-rect') {
197
+ const w = Math.abs(p.x - dragState.sx);
198
+ const h = Math.abs(p.y - dragState.sy);
199
+ if (w < 5 && h < 5) { dragState.el.remove(); }
200
+ else {
201
+ const a = { id: dragState.id, type: 'rect', x: Math.min(dragState.sx, p.x), y: Math.min(dragState.sy, p.y), width: w, height: h };
202
+ annotations.push(a);
203
+ selectEl(dragState.el);
204
+ }
205
+ } else if (dragState.type === 'create-arrow') {
206
+ const dist = Math.hypot(p.x - dragState.sx, p.y - dragState.sy);
207
+ if (dist < 5) { dragState.el.remove(); }
208
+ else {
209
+ annotations.push({ id: dragState.id, type: 'arrow', fromX: dragState.sx, fromY: dragState.sy, toX: p.x, toY: p.y });
210
+ selectEl(dragState.el);
211
+ }
212
+ }
213
+ dragState = null;
214
+ });
215
+
216
+ // --- ELEMENTS ---
217
+ function makeRect(id, x, y, w, h) {
218
+ const el = document.createElement('div');
219
+ el.className = 'annotation'; el.dataset.id = id;
220
+ el.style.cssText = `left:${x}px;top:${y}px;width:${w}px;height:${h}px;border:2px solid #FF0000;border-radius:4px;`;
221
+ el.addEventListener('mousedown', e => {
222
+ e.stopPropagation();
223
+ selectEl(el);
224
+ const a = annotations.find(a => a.id === parseInt(el.dataset.id));
225
+ if (a) {
226
+ const pp = getPos(e);
227
+ dragState = { type: 'move', id: a.id, el, ox: pp.x - a.x, oy: pp.y - a.y };
228
+ }
229
+ });
230
+ return el;
231
+ }
232
+
233
+ function makeArrow(id, x1, y1, x2, y2) {
234
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
235
+ svg.classList.add('annotation'); svg.dataset.id = id;
236
+ svg.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;';
237
+ svg.innerHTML = `
238
+ <defs><marker id="ah-${id}" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto" fill="#FF0000">
239
+ <polygon points="0 0, 10 3.5, 0 7"/></marker></defs>
240
+ <line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="#FF0000" stroke-width="2" marker-end="url(#ah-${id})" style="pointer-events:stroke;cursor:pointer;" />`;
241
+ svg.querySelector('line').addEventListener('mousedown', e => {
242
+ e.stopPropagation();
243
+ selectEl(svg);
244
+ });
245
+ return svg;
246
+ }
247
+
248
+ function updateArrow(svg, x1, y1, x2, y2) {
249
+ const line = svg.querySelector('line');
250
+ line.setAttribute('x1', x1); line.setAttribute('y1', y1);
251
+ line.setAttribute('x2', x2); line.setAttribute('y2', y2);
252
+ }
253
+
254
+ function makeLabel(id, x, y, text) {
255
+ const el = document.createElement('div');
256
+ el.className = 'annotation'; el.dataset.id = id;
257
+ el.style.cssText = `left:${x}px;top:${y}px;padding:4px 8px;background:#fff;border:1px solid #FF0000;border-radius:4px;color:#FF0000;font-size:14px;min-width:40px;`;
258
+ el.innerHTML = `<input class="label-input" value="${text}" style="color:#FF0000;font-size:14px;" />`;
259
+ el.querySelector('.label-input').addEventListener('input', e => {
260
+ const a = annotations.find(a => a.id === parseInt(el.dataset.id));
261
+ if (a) a.text = e.target.value;
262
+ });
263
+ el.addEventListener('mousedown', e => {
264
+ if (e.target.classList.contains('label-input')) return;
265
+ e.stopPropagation();
266
+ selectEl(el);
267
+ const a = annotations.find(a => a.id === parseInt(el.dataset.id));
268
+ if (a) {
269
+ const pp = getPos(e);
270
+ dragState = { type: 'move', id: a.id, el, ox: pp.x - a.x, oy: pp.y - a.y };
271
+ }
272
+ });
273
+ return el;
274
+ }
275
+
276
+ // --- LOAD EXISTING ---
277
+ function addFromDecoration(d) {
278
+ const id = nextId++;
279
+ const s = getScale();
280
+ if (d.type === 'rect' && d.target && 'x' in d.target) {
281
+ const a = { id, type: 'rect', x: d.target.x/s, y: d.target.y/s, width: d.target.width/s, height: d.target.height/s };
282
+ annotations.push(a);
283
+ editor.appendChild(makeRect(id, a.x, a.y, a.width, a.height));
284
+ } else if (d.type === 'arrow' && 'x' in d.from && 'x' in d.to) {
285
+ const a = { id, type: 'arrow', fromX: d.from.x/s, fromY: d.from.y/s, toX: d.to.x/s, toY: d.to.y/s };
286
+ annotations.push(a);
287
+ editor.appendChild(makeArrow(id, a.fromX, a.fromY, a.toX, a.toY));
288
+ } else if (d.type === 'label' && 'x' in d.position) {
289
+ const a = { id, type: 'label', x: d.position.x/s, y: d.position.y/s, text: d.text };
290
+ annotations.push(a);
291
+ editor.appendChild(makeLabel(id, a.x, a.y, a.text));
292
+ }
293
+ }
294
+
295
+ // --- SAVE ---
296
+ function save() {
297
+ const s = getScale();
298
+ const decorations = annotations.map(a => {
299
+ if (a.type === 'rect') {
300
+ return { type: 'rect', target: { x: Math.round(a.x*s), y: Math.round(a.y*s), width: Math.round(a.width*s), height: Math.round(a.height*s) }, style: { color: '#FF0000', strokeWidth: 2 } };
301
+ } else if (a.type === 'arrow') {
302
+ return { type: 'arrow', from: { x: Math.round(a.fromX*s), y: Math.round(a.fromY*s) }, to: { x: Math.round(a.toX*s), y: Math.round(a.toY*s) }, style: { color: '#FF0000', strokeWidth: 2 } };
303
+ } else if (a.type === 'label') {
304
+ return { type: 'label', text: a.text, position: { x: Math.round(a.x*s), y: Math.round(a.y*s) }, style: { fontSize: 14, color: '#FF0000', background: '#FFFFFF' } };
305
+ }
306
+ }).filter(Boolean);
307
+
308
+ window.__SAVED_DECORATIONS__ = decorations;
309
+ document.title = 'SAVED';
310
+ }
311
+ </script>
312
+ </body>
313
+ </html>