waitroom 0.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/README.md +62 -0
- package/dist/chunk-3RJ542WD.js +130 -0
- package/dist/chunk-3RJ542WD.js.map +1 -0
- package/dist/chunk-4DE2IREA.cjs +9 -0
- package/dist/chunk-4DE2IREA.cjs.map +1 -0
- package/dist/chunk-5AUPIR2C.cjs +90 -0
- package/dist/chunk-5AUPIR2C.cjs.map +1 -0
- package/dist/chunk-ARXVTVP4.js +55 -0
- package/dist/chunk-ARXVTVP4.js.map +1 -0
- package/dist/chunk-C5XPYOJI.js +137 -0
- package/dist/chunk-C5XPYOJI.js.map +1 -0
- package/dist/chunk-DEQZY4AM.js +58 -0
- package/dist/chunk-DEQZY4AM.js.map +1 -0
- package/dist/chunk-FH3QBC6T.cjs +139 -0
- package/dist/chunk-FH3QBC6T.cjs.map +1 -0
- package/dist/chunk-GEBKOXLQ.cjs +255 -0
- package/dist/chunk-GEBKOXLQ.cjs.map +1 -0
- package/dist/chunk-JG5ZMB2Y.cjs +142 -0
- package/dist/chunk-JG5ZMB2Y.cjs.map +1 -0
- package/dist/chunk-MAWVAR3Q.cjs +135 -0
- package/dist/chunk-MAWVAR3Q.cjs.map +1 -0
- package/dist/chunk-MMNQMDV3.js +39 -0
- package/dist/chunk-MMNQMDV3.js.map +1 -0
- package/dist/chunk-O6CAFCTV.js +140 -0
- package/dist/chunk-O6CAFCTV.js.map +1 -0
- package/dist/chunk-P6NO27XB.cjs +74 -0
- package/dist/chunk-P6NO27XB.cjs.map +1 -0
- package/dist/chunk-PKRYY3X6.cjs +60 -0
- package/dist/chunk-PKRYY3X6.cjs.map +1 -0
- package/dist/chunk-PUR7CO53.js +72 -0
- package/dist/chunk-PUR7CO53.js.map +1 -0
- package/dist/chunk-R5V2UBE7.js +88 -0
- package/dist/chunk-R5V2UBE7.js.map +1 -0
- package/dist/chunk-SSP4S4NY.cjs +57 -0
- package/dist/chunk-SSP4S4NY.cjs.map +1 -0
- package/dist/chunk-SUJCEDVR.js +251 -0
- package/dist/chunk-SUJCEDVR.js.map +1 -0
- package/dist/chunk-V4RO47V6.cjs +41 -0
- package/dist/chunk-V4RO47V6.cjs.map +1 -0
- package/dist/chunk-V5DABI44.cjs +172 -0
- package/dist/chunk-V5DABI44.cjs.map +1 -0
- package/dist/chunk-V6TY7KAL.js +7 -0
- package/dist/chunk-V6TY7KAL.js.map +1 -0
- package/dist/chunk-VKSLYTRF.js +170 -0
- package/dist/chunk-VKSLYTRF.js.map +1 -0
- package/dist/core/index.cjs +30 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +23 -0
- package/dist/core/index.d.ts +23 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/doodle/basic-canvas.cjs +13 -0
- package/dist/doodle/basic-canvas.cjs.map +1 -0
- package/dist/doodle/basic-canvas.d.cts +5 -0
- package/dist/doodle/basic-canvas.d.ts +5 -0
- package/dist/doodle/basic-canvas.js +4 -0
- package/dist/doodle/basic-canvas.js.map +1 -0
- package/dist/doodle/index.cjs +13 -0
- package/dist/doodle/index.cjs.map +1 -0
- package/dist/doodle/index.d.cts +2 -0
- package/dist/doodle/index.d.ts +2 -0
- package/dist/doodle/index.js +4 -0
- package/dist/doodle/index.js.map +1 -0
- package/dist/engine--hGQ4LNR.d.ts +16 -0
- package/dist/engine-DdHCpfbk.d.cts +16 -0
- package/dist/facts/dev-tips.cjs +13 -0
- package/dist/facts/dev-tips.cjs.map +1 -0
- package/dist/facts/dev-tips.d.cts +5 -0
- package/dist/facts/dev-tips.d.ts +5 -0
- package/dist/facts/dev-tips.js +4 -0
- package/dist/facts/dev-tips.js.map +1 -0
- package/dist/facts/index.cjs +23 -0
- package/dist/facts/index.cjs.map +1 -0
- package/dist/facts/index.d.cts +4 -0
- package/dist/facts/index.d.ts +4 -0
- package/dist/facts/index.js +6 -0
- package/dist/facts/index.js.map +1 -0
- package/dist/facts/programming-trivia.cjs +13 -0
- package/dist/facts/programming-trivia.cjs.map +1 -0
- package/dist/facts/programming-trivia.d.cts +5 -0
- package/dist/facts/programming-trivia.d.ts +5 -0
- package/dist/facts/programming-trivia.js +4 -0
- package/dist/facts/programming-trivia.js.map +1 -0
- package/dist/facts/tech-stats.cjs +13 -0
- package/dist/facts/tech-stats.cjs.map +1 -0
- package/dist/facts/tech-stats.d.cts +5 -0
- package/dist/facts/tech-stats.d.ts +5 -0
- package/dist/facts/tech-stats.js +4 -0
- package/dist/facts/tech-stats.js.map +1 -0
- package/dist/games/click-counter.cjs +13 -0
- package/dist/games/click-counter.cjs.map +1 -0
- package/dist/games/click-counter.d.cts +5 -0
- package/dist/games/click-counter.d.ts +5 -0
- package/dist/games/click-counter.js +4 -0
- package/dist/games/click-counter.js.map +1 -0
- package/dist/games/index.cjs +23 -0
- package/dist/games/index.cjs.map +1 -0
- package/dist/games/index.d.cts +4 -0
- package/dist/games/index.d.ts +4 -0
- package/dist/games/index.js +6 -0
- package/dist/games/index.js.map +1 -0
- package/dist/games/memory.cjs +13 -0
- package/dist/games/memory.cjs.map +1 -0
- package/dist/games/memory.d.cts +5 -0
- package/dist/games/memory.d.ts +5 -0
- package/dist/games/memory.js +4 -0
- package/dist/games/memory.js.map +1 -0
- package/dist/games/snake.cjs +13 -0
- package/dist/games/snake.cjs.map +1 -0
- package/dist/games/snake.d.cts +5 -0
- package/dist/games/snake.d.ts +5 -0
- package/dist/games/snake.js +4 -0
- package/dist/games/snake.js.map +1 -0
- package/dist/index.cjs +43 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +22 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +24 -0
- package/dist/react/index.d.ts +24 -0
- package/dist/react/index.js +5 -0
- package/dist/react/index.js.map +1 -0
- package/dist/types-vBwPFyxq.d.cts +101 -0
- package/dist/types-vBwPFyxq.d.ts +101 -0
- package/package.json +64 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk4DE2IREA_cjs = require('./chunk-4DE2IREA.cjs');
|
|
4
|
+
|
|
5
|
+
// src/games/memory.ts
|
|
6
|
+
var MemoryInstance = class {
|
|
7
|
+
// 6 pairs for 3x4 grid
|
|
8
|
+
constructor(container, state) {
|
|
9
|
+
chunk4DE2IREA_cjs.__publicField(this, "container");
|
|
10
|
+
chunk4DE2IREA_cjs.__publicField(this, "state");
|
|
11
|
+
chunk4DE2IREA_cjs.__publicField(this, "cards", []);
|
|
12
|
+
chunk4DE2IREA_cjs.__publicField(this, "flippedCards", []);
|
|
13
|
+
chunk4DE2IREA_cjs.__publicField(this, "grid");
|
|
14
|
+
chunk4DE2IREA_cjs.__publicField(this, "messageDisplay");
|
|
15
|
+
chunk4DE2IREA_cjs.__publicField(this, "isLocked", false);
|
|
16
|
+
chunk4DE2IREA_cjs.__publicField(this, "emojis", ["\u{1F436}", "\u{1F431}", "\u{1F42D}", "\u{1F439}", "\u{1F430}", "\u{1F98A}"]);
|
|
17
|
+
this.container = container;
|
|
18
|
+
this.state = state;
|
|
19
|
+
this.container.style.display = "flex";
|
|
20
|
+
this.container.style.flexDirection = "column";
|
|
21
|
+
this.container.style.alignItems = "center";
|
|
22
|
+
this.container.style.justifyContent = "center";
|
|
23
|
+
this.container.style.fontFamily = "sans-serif";
|
|
24
|
+
const title = document.createElement("h3");
|
|
25
|
+
title.innerText = "Memory Match";
|
|
26
|
+
title.style.margin = "0 0 5px 0";
|
|
27
|
+
this.container.appendChild(title);
|
|
28
|
+
const helper = document.createElement("div");
|
|
29
|
+
helper.innerText = "Find matching pairs";
|
|
30
|
+
helper.style.fontSize = "0.8em";
|
|
31
|
+
helper.style.color = "#888";
|
|
32
|
+
helper.style.marginBottom = "10px";
|
|
33
|
+
this.container.appendChild(helper);
|
|
34
|
+
this.messageDisplay = document.createElement("div");
|
|
35
|
+
this.messageDisplay.style.height = "20px";
|
|
36
|
+
this.messageDisplay.style.fontSize = "14px";
|
|
37
|
+
this.messageDisplay.style.fontWeight = "bold";
|
|
38
|
+
this.messageDisplay.style.marginBottom = "5px";
|
|
39
|
+
this.container.appendChild(this.messageDisplay);
|
|
40
|
+
this.grid = document.createElement("div");
|
|
41
|
+
this.grid.style.display = "grid";
|
|
42
|
+
this.grid.style.gridTemplateColumns = "repeat(4, 1fr)";
|
|
43
|
+
this.grid.style.gap = "8px";
|
|
44
|
+
this.container.appendChild(this.grid);
|
|
45
|
+
this.initGame();
|
|
46
|
+
}
|
|
47
|
+
initGame() {
|
|
48
|
+
const deck = [...this.emojis, ...this.emojis].sort(() => Math.random() - 0.5).map((emoji, index) => ({
|
|
49
|
+
id: index,
|
|
50
|
+
value: emoji,
|
|
51
|
+
isFlipped: false,
|
|
52
|
+
isMatched: false
|
|
53
|
+
}));
|
|
54
|
+
this.cards = deck;
|
|
55
|
+
this.renderGrid();
|
|
56
|
+
}
|
|
57
|
+
renderGrid() {
|
|
58
|
+
this.grid.innerHTML = "";
|
|
59
|
+
this.cards.forEach((card) => {
|
|
60
|
+
const cardEl = document.createElement("div");
|
|
61
|
+
cardEl.style.width = "50px";
|
|
62
|
+
cardEl.style.height = "50px";
|
|
63
|
+
cardEl.style.background = card.isFlipped || card.isMatched ? "#fff" : "#22c55e";
|
|
64
|
+
cardEl.style.border = "1px solid #ccc";
|
|
65
|
+
cardEl.style.borderRadius = "8px";
|
|
66
|
+
cardEl.style.display = "flex";
|
|
67
|
+
cardEl.style.alignItems = "center";
|
|
68
|
+
cardEl.style.justifyContent = "center";
|
|
69
|
+
cardEl.style.fontSize = "24px";
|
|
70
|
+
cardEl.style.cursor = "pointer";
|
|
71
|
+
cardEl.style.transition = "transform 0.2s, background 0.2s";
|
|
72
|
+
if (card.isFlipped || card.isMatched) {
|
|
73
|
+
cardEl.innerText = card.value;
|
|
74
|
+
cardEl.style.transform = "rotateY(0deg)";
|
|
75
|
+
} else {
|
|
76
|
+
cardEl.innerText = "";
|
|
77
|
+
cardEl.style.transform = "rotateY(180deg)";
|
|
78
|
+
}
|
|
79
|
+
cardEl.onclick = () => this.handleCardClick(card);
|
|
80
|
+
this.grid.appendChild(cardEl);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
handleCardClick(card) {
|
|
84
|
+
if (this.isLocked || card.isFlipped || card.isMatched) return;
|
|
85
|
+
card.isFlipped = true;
|
|
86
|
+
this.flippedCards.push(card);
|
|
87
|
+
this.renderGrid();
|
|
88
|
+
if (this.flippedCards.length === 2) {
|
|
89
|
+
this.isLocked = true;
|
|
90
|
+
this.checkMatch();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
checkMatch() {
|
|
94
|
+
const [card1, card2] = this.flippedCards;
|
|
95
|
+
if (card1.value === card2.value) {
|
|
96
|
+
card1.isMatched = true;
|
|
97
|
+
card2.isMatched = true;
|
|
98
|
+
this.flippedCards = [];
|
|
99
|
+
this.isLocked = false;
|
|
100
|
+
this.renderGrid();
|
|
101
|
+
this.checkWin();
|
|
102
|
+
} else {
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
card1.isFlipped = false;
|
|
105
|
+
card2.isFlipped = false;
|
|
106
|
+
this.flippedCards = [];
|
|
107
|
+
this.isLocked = false;
|
|
108
|
+
this.renderGrid();
|
|
109
|
+
}, 1e3);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
checkWin() {
|
|
113
|
+
if (this.cards.every((c) => c.isMatched)) {
|
|
114
|
+
this.messageDisplay.innerText = "You Won! \u{1F389}";
|
|
115
|
+
this.messageDisplay.style.color = "green";
|
|
116
|
+
setTimeout(() => this.initGame(), 3e3);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
getState() {
|
|
120
|
+
return this.state;
|
|
121
|
+
}
|
|
122
|
+
setState(s) {
|
|
123
|
+
this.state = { ...this.state, ...s };
|
|
124
|
+
}
|
|
125
|
+
destroy() {
|
|
126
|
+
this.container.innerHTML = "";
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var MemoryGame = {
|
|
130
|
+
id: "memory",
|
|
131
|
+
name: "Memory Match",
|
|
132
|
+
description: "Find matching pairs",
|
|
133
|
+
renderMini: (c, s) => new MemoryInstance(c, s),
|
|
134
|
+
renderFull: (c, s) => new MemoryInstance(c, s)
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
exports.MemoryGame = MemoryGame;
|
|
138
|
+
//# sourceMappingURL=chunk-FH3QBC6T.cjs.map
|
|
139
|
+
//# sourceMappingURL=chunk-FH3QBC6T.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/games/memory.ts"],"names":["__publicField"],"mappings":"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","file":"chunk-FH3QBC6T.cjs","sourcesContent":["import { GamePlugin, GameInstance, GameState } from \"../core/types\";\n\n// Memory Game Logic\ninterface Card {\n id: number;\n value: string;\n isFlipped: boolean;\n isMatched: boolean;\n}\n\nclass MemoryInstance implements GameInstance {\n private container: HTMLElement;\n private state: Partial<GameState>;\n private cards: Card[] = [];\n private flippedCards: Card[] = [];\n private grid: HTMLElement;\n private messageDisplay: HTMLElement;\n private isLocked = false;\n\n private emojis = [\"🐶\", \"🐱\", \"🐭\", \"🐹\", \"🐰\", \"🦊\"]; // 6 pairs for 3x4 grid\n\n constructor(container: HTMLElement, state: Partial<GameState>) {\n this.container = container;\n this.state = state;\n\n this.container.style.display = \"flex\";\n this.container.style.flexDirection = \"column\";\n this.container.style.alignItems = \"center\";\n this.container.style.justifyContent = \"center\";\n this.container.style.fontFamily = \"sans-serif\";\n\n // Title and Helper\n const title = document.createElement(\"h3\");\n title.innerText = \"Memory Match\";\n title.style.margin = \"0 0 5px 0\";\n this.container.appendChild(title);\n\n const helper = document.createElement(\"div\");\n helper.innerText = \"Find matching pairs\";\n helper.style.fontSize = \"0.8em\";\n helper.style.color = \"#888\";\n helper.style.marginBottom = \"10px\";\n this.container.appendChild(helper);\n\n this.messageDisplay = document.createElement(\"div\");\n this.messageDisplay.style.height = \"20px\";\n this.messageDisplay.style.fontSize = \"14px\";\n this.messageDisplay.style.fontWeight = \"bold\";\n this.messageDisplay.style.marginBottom = \"5px\";\n this.container.appendChild(this.messageDisplay);\n\n this.grid = document.createElement(\"div\");\n this.grid.style.display = \"grid\";\n this.grid.style.gridTemplateColumns = \"repeat(4, 1fr)\";\n this.grid.style.gap = \"8px\";\n this.container.appendChild(this.grid);\n\n this.initGame();\n }\n\n private initGame() {\n // Create pairs\n const deck = [...this.emojis, ...this.emojis]\n .sort(() => Math.random() - 0.5)\n .map((emoji, index) => ({\n id: index,\n value: emoji,\n isFlipped: false,\n isMatched: false,\n }));\n\n this.cards = deck;\n this.renderGrid();\n }\n\n private renderGrid() {\n this.grid.innerHTML = \"\";\n this.cards.forEach((card) => {\n const cardEl = document.createElement(\"div\");\n cardEl.style.width = \"50px\";\n cardEl.style.height = \"50px\";\n cardEl.style.background =\n card.isFlipped || card.isMatched ? \"#fff\" : \"#22c55e\";\n cardEl.style.border = \"1px solid #ccc\";\n cardEl.style.borderRadius = \"8px\";\n cardEl.style.display = \"flex\";\n cardEl.style.alignItems = \"center\";\n cardEl.style.justifyContent = \"center\";\n cardEl.style.fontSize = \"24px\";\n cardEl.style.cursor = \"pointer\";\n cardEl.style.transition = \"transform 0.2s, background 0.2s\";\n\n if (card.isFlipped || card.isMatched) {\n cardEl.innerText = card.value;\n cardEl.style.transform = \"rotateY(0deg)\";\n } else {\n cardEl.innerText = \"\";\n cardEl.style.transform = \"rotateY(180deg)\";\n }\n\n cardEl.onclick = () => this.handleCardClick(card);\n this.grid.appendChild(cardEl);\n });\n }\n\n private handleCardClick(card: Card) {\n if (this.isLocked || card.isFlipped || card.isMatched) return;\n\n // Flip card\n card.isFlipped = true;\n this.flippedCards.push(card);\n this.renderGrid();\n\n // Check match\n if (this.flippedCards.length === 2) {\n this.isLocked = true;\n this.checkMatch();\n }\n }\n\n private checkMatch() {\n const [card1, card2] = this.flippedCards;\n\n if (card1.value === card2.value) {\n // Match!\n card1.isMatched = true;\n card2.isMatched = true;\n this.flippedCards = [];\n this.isLocked = false;\n this.renderGrid();\n this.checkWin();\n } else {\n // No match\n setTimeout(() => {\n card1.isFlipped = false;\n card2.isFlipped = false;\n this.flippedCards = [];\n this.isLocked = false;\n this.renderGrid();\n }, 1000);\n }\n }\n\n private checkWin() {\n if (this.cards.every((c) => c.isMatched)) {\n this.messageDisplay.innerText = \"You Won! 🎉\";\n this.messageDisplay.style.color = \"green\";\n setTimeout(() => this.initGame(), 3000); // Restart\n }\n }\n\n getState() {\n return this.state as GameState;\n }\n setState(s: Partial<GameState>) {\n this.state = { ...this.state, ...s };\n }\n destroy() {\n this.container.innerHTML = \"\";\n }\n}\n\nexport const MemoryGame: GamePlugin = {\n id: \"memory\",\n name: \"Memory Match\",\n description: \"Find matching pairs\",\n renderMini: (c, s) => new MemoryInstance(c, s),\n renderFull: (c, s) => new MemoryInstance(c, s),\n};\n"]}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkMAWVAR3Q_cjs = require('./chunk-MAWVAR3Q.cjs');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
function useLoadingInteraction(ref, config) {
|
|
8
|
+
const engineRef = react.useRef(null);
|
|
9
|
+
react.useEffect(() => {
|
|
10
|
+
if (!ref.current || !config.isLoading) {
|
|
11
|
+
if (engineRef.current) {
|
|
12
|
+
engineRef.current.destroy();
|
|
13
|
+
engineRef.current = null;
|
|
14
|
+
}
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!engineRef.current) {
|
|
18
|
+
engineRef.current = chunkMAWVAR3Q_cjs.createLoadingInteraction(ref.current, config);
|
|
19
|
+
}
|
|
20
|
+
return () => {
|
|
21
|
+
if (engineRef.current) {
|
|
22
|
+
engineRef.current.destroy();
|
|
23
|
+
engineRef.current = null;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}, [config.isLoading, config.mode, ref]);
|
|
27
|
+
return engineRef.current;
|
|
28
|
+
}
|
|
29
|
+
var icons = {
|
|
30
|
+
game: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
31
|
+
"svg",
|
|
32
|
+
{
|
|
33
|
+
width: "18",
|
|
34
|
+
height: "18",
|
|
35
|
+
viewBox: "0 0 24 24",
|
|
36
|
+
fill: "none",
|
|
37
|
+
stroke: "currentColor",
|
|
38
|
+
strokeWidth: "2",
|
|
39
|
+
strokeLinecap: "round",
|
|
40
|
+
strokeLinejoin: "round",
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "6", width: "20", height: "12", rx: "2" }),
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 12h4m-2-2v4" }),
|
|
44
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "15", y1: "11", x2: "15", y2: "11" }),
|
|
45
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "13", x2: "18", y2: "13" })
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
facts: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
50
|
+
"svg",
|
|
51
|
+
{
|
|
52
|
+
width: "18",
|
|
53
|
+
height: "18",
|
|
54
|
+
viewBox: "0 0 24 24",
|
|
55
|
+
fill: "none",
|
|
56
|
+
stroke: "currentColor",
|
|
57
|
+
strokeWidth: "2",
|
|
58
|
+
strokeLinecap: "round",
|
|
59
|
+
strokeLinejoin: "round",
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2a6 6 0 0 1 6 6c0 2.97-1 3.5-2 4.5V15h-8v-2.5c-1-1-2-1.53-2-4.5a6 6 0 0 1 6-6z" }),
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8.5 18h7" }),
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 21h4" })
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
doodle: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
68
|
+
"svg",
|
|
69
|
+
{
|
|
70
|
+
width: "18",
|
|
71
|
+
height: "18",
|
|
72
|
+
viewBox: "0 0 24 24",
|
|
73
|
+
fill: "none",
|
|
74
|
+
stroke: "currentColor",
|
|
75
|
+
strokeWidth: "2",
|
|
76
|
+
strokeLinecap: "round",
|
|
77
|
+
strokeLinejoin: "round",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 19l7-7 3 3-7 7-3-3z" }),
|
|
80
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z" }),
|
|
81
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l7.586 7.586" }),
|
|
82
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "2" })
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
none: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 16 }, children: "\u2715" })
|
|
87
|
+
};
|
|
88
|
+
var tooltips = {
|
|
89
|
+
game: "Play a Game",
|
|
90
|
+
facts: "Learn Facts",
|
|
91
|
+
doodle: "Draw Something",
|
|
92
|
+
none: "Disable"
|
|
93
|
+
};
|
|
94
|
+
var ModeSwitcher = ({
|
|
95
|
+
modes,
|
|
96
|
+
activeMode,
|
|
97
|
+
onModeChange
|
|
98
|
+
}) => {
|
|
99
|
+
const [hovered, setHovered] = react.useState(null);
|
|
100
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
101
|
+
"div",
|
|
102
|
+
{
|
|
103
|
+
style: {
|
|
104
|
+
display: "flex",
|
|
105
|
+
flexDirection: "column",
|
|
106
|
+
gap: "8px",
|
|
107
|
+
padding: "4px"
|
|
108
|
+
},
|
|
109
|
+
children: modes.map((mode) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
110
|
+
"div",
|
|
111
|
+
{
|
|
112
|
+
style: {
|
|
113
|
+
position: "relative",
|
|
114
|
+
display: "flex",
|
|
115
|
+
alignItems: "center",
|
|
116
|
+
justifyContent: "flex-end"
|
|
117
|
+
},
|
|
118
|
+
children: [
|
|
119
|
+
hovered === mode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
style: {
|
|
123
|
+
position: "absolute",
|
|
124
|
+
right: "100%",
|
|
125
|
+
marginRight: "8px",
|
|
126
|
+
background: "rgba(0,0,0,0.8)",
|
|
127
|
+
color: "#fff",
|
|
128
|
+
padding: "4px 8px",
|
|
129
|
+
borderRadius: "4px",
|
|
130
|
+
fontSize: "12px",
|
|
131
|
+
whiteSpace: "nowrap",
|
|
132
|
+
pointerEvents: "none",
|
|
133
|
+
opacity: 0,
|
|
134
|
+
animation: "fadeIn 0.2s forwards"
|
|
135
|
+
},
|
|
136
|
+
children: tooltips[mode] || mode
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
140
|
+
"button",
|
|
141
|
+
{
|
|
142
|
+
onClick: (e) => {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
onModeChange(mode);
|
|
145
|
+
},
|
|
146
|
+
onMouseEnter: () => setHovered(mode),
|
|
147
|
+
onMouseLeave: () => setHovered(null),
|
|
148
|
+
style: {
|
|
149
|
+
width: "36px",
|
|
150
|
+
height: "36px",
|
|
151
|
+
borderRadius: "50%",
|
|
152
|
+
border: "none",
|
|
153
|
+
background: activeMode === mode ? "#333" : "rgba(255,255,255,0.9)",
|
|
154
|
+
color: activeMode === mode ? "#fff" : "#555",
|
|
155
|
+
cursor: "pointer",
|
|
156
|
+
display: "flex",
|
|
157
|
+
alignItems: "center",
|
|
158
|
+
justifyContent: "center",
|
|
159
|
+
boxShadow: "0 2px 5px rgba(0,0,0,0.1)",
|
|
160
|
+
transition: "all 0.2s ease",
|
|
161
|
+
transform: activeMode === mode ? "scale(1.1)" : "scale(1)"
|
|
162
|
+
},
|
|
163
|
+
"aria-label": mode,
|
|
164
|
+
children: icons[mode] || mode[0].toUpperCase()
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
168
|
+
@keyframes fadeIn {
|
|
169
|
+
from { opacity: 0; transform: translateX(5px); }
|
|
170
|
+
to { opacity: 1; transform: translateX(0); }
|
|
171
|
+
}
|
|
172
|
+
` })
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
mode
|
|
176
|
+
))
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
var LoadingInteraction = (props) => {
|
|
181
|
+
const {
|
|
182
|
+
isLoading,
|
|
183
|
+
children,
|
|
184
|
+
availableModes = ["game", "facts", "doodle"],
|
|
185
|
+
showModeSwitcher = true,
|
|
186
|
+
width = "100%",
|
|
187
|
+
height = "300px",
|
|
188
|
+
...config
|
|
189
|
+
} = props;
|
|
190
|
+
const containerRef = react.useRef(null);
|
|
191
|
+
const [currentMode, setCurrentMode] = react.useState(
|
|
192
|
+
props.mode || availableModes[0] || "none"
|
|
193
|
+
);
|
|
194
|
+
react.useEffect(() => {
|
|
195
|
+
if (props.mode) setCurrentMode(props.mode);
|
|
196
|
+
}, [props.mode]);
|
|
197
|
+
const activeConfig = {
|
|
198
|
+
...config,
|
|
199
|
+
isLoading,
|
|
200
|
+
mode: currentMode,
|
|
201
|
+
availableModes,
|
|
202
|
+
style: props.style,
|
|
203
|
+
transitionDuration: props.transitionDuration
|
|
204
|
+
};
|
|
205
|
+
useLoadingInteraction(containerRef, activeConfig);
|
|
206
|
+
if (!isLoading) {
|
|
207
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
208
|
+
}
|
|
209
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width, height }, children: [
|
|
210
|
+
showModeSwitcher && availableModes.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
211
|
+
"div",
|
|
212
|
+
{
|
|
213
|
+
style: {
|
|
214
|
+
position: "absolute",
|
|
215
|
+
bottom: 12,
|
|
216
|
+
right: 12,
|
|
217
|
+
width: "auto",
|
|
218
|
+
zIndex: 20,
|
|
219
|
+
pointerEvents: "none"
|
|
220
|
+
// Allow clicks to pass through transparent areas
|
|
221
|
+
},
|
|
222
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { pointerEvents: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
223
|
+
ModeSwitcher,
|
|
224
|
+
{
|
|
225
|
+
modes: availableModes,
|
|
226
|
+
activeMode: currentMode,
|
|
227
|
+
onModeChange: setCurrentMode
|
|
228
|
+
}
|
|
229
|
+
) })
|
|
230
|
+
}
|
|
231
|
+
),
|
|
232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
233
|
+
"div",
|
|
234
|
+
{
|
|
235
|
+
ref: containerRef,
|
|
236
|
+
style: {
|
|
237
|
+
width: "100%",
|
|
238
|
+
height: "100%",
|
|
239
|
+
background: "#f5f5f5",
|
|
240
|
+
display: "flex",
|
|
241
|
+
alignItems: "center",
|
|
242
|
+
justifyContent: "center",
|
|
243
|
+
borderRadius: "8px",
|
|
244
|
+
overflow: "hidden"
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
)
|
|
248
|
+
] });
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
exports.LoadingInteraction = LoadingInteraction;
|
|
252
|
+
exports.ModeSwitcher = ModeSwitcher;
|
|
253
|
+
exports.useLoadingInteraction = useLoadingInteraction;
|
|
254
|
+
//# sourceMappingURL=chunk-GEBKOXLQ.cjs.map
|
|
255
|
+
//# sourceMappingURL=chunk-GEBKOXLQ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/hooks.ts","../src/react/ModeSwitcher.tsx","../src/react/LoadingInteraction.tsx"],"names":["useRef","useEffect","createLoadingInteraction","jsxs","jsx","useState","Fragment"],"mappings":"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","file":"chunk-GEBKOXLQ.cjs","sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { createLoadingInteraction, LoadingEngine } from \"../core/engine\";\nimport { InteractionConfig } from \"../core/types\";\n\nexport function useLoadingInteraction(\n ref: React.RefObject<HTMLElement>,\n config: InteractionConfig\n) {\n const engineRef = useRef<LoadingEngine | null>(null);\n\n useEffect(() => {\n if (!ref.current || !config.isLoading) {\n if (engineRef.current) {\n engineRef.current.destroy();\n engineRef.current = null;\n }\n return;\n }\n\n if (!engineRef.current) {\n engineRef.current = createLoadingInteraction(ref.current, config);\n }\n\n return () => {\n if (engineRef.current) {\n engineRef.current.destroy();\n engineRef.current = null;\n }\n };\n }, [config.isLoading, config.mode, ref]);\n\n return engineRef.current;\n}\n","import React, { useState } from \"react\";\nimport { InteractionMode } from \"../core/types\";\n\ninterface ModeSwitcherProps {\n modes: InteractionMode[];\n activeMode: InteractionMode;\n onModeChange: (mode: InteractionMode) => void;\n}\n\nconst icons: Record<string, React.ReactNode> = {\n game: (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"2\" />\n <path d=\"M6 12h4m-2-2v4\" />\n <line x1=\"15\" y1=\"11\" x2=\"15\" y2=\"11\" />\n <line x1=\"18\" y1=\"13\" x2=\"18\" y2=\"13\" />\n </svg>\n ),\n facts: (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 2a6 6 0 0 1 6 6c0 2.97-1 3.5-2 4.5V15h-8v-2.5c-1-1-2-1.53-2-4.5a6 6 0 0 1 6-6z\" />\n <path d=\"M8.5 18h7\" />\n <path d=\"M10 21h4\" />\n </svg>\n ),\n doodle: (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 19l7-7 3 3-7 7-3-3z\" />\n <path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\" />\n <path d=\"M2 2l7.586 7.586\" />\n <circle cx=\"11\" cy=\"11\" r=\"2\" />\n </svg>\n ),\n none: <span style={{ fontSize: 16 }}>✕</span>,\n};\n\nconst tooltips: Record<string, string> = {\n game: \"Play a Game\",\n facts: \"Learn Facts\",\n doodle: \"Draw Something\",\n none: \"Disable\",\n};\n\nexport const ModeSwitcher: React.FC<ModeSwitcherProps> = ({\n modes,\n activeMode,\n onModeChange,\n}) => {\n const [hovered, setHovered] = useState<InteractionMode | null>(null);\n\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"8px\",\n padding: \"4px\",\n }}\n >\n {modes.map((mode) => (\n <div\n key={mode}\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n }}\n >\n {/* Tooltip (Left side) */}\n {hovered === mode && (\n <div\n style={{\n position: \"absolute\",\n right: \"100%\",\n marginRight: \"8px\",\n background: \"rgba(0,0,0,0.8)\",\n color: \"#fff\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n fontSize: \"12px\",\n whiteSpace: \"nowrap\",\n pointerEvents: \"none\",\n opacity: 0,\n animation: \"fadeIn 0.2s forwards\",\n }}\n >\n {tooltips[mode] || mode}\n </div>\n )}\n\n {/* Icon Button */}\n <button\n onClick={(e) => {\n e.preventDefault();\n onModeChange(mode);\n }}\n onMouseEnter={() => setHovered(mode)}\n onMouseLeave={() => setHovered(null)}\n style={{\n width: \"36px\",\n height: \"36px\",\n borderRadius: \"50%\",\n border: \"none\",\n background:\n activeMode === mode ? \"#333\" : \"rgba(255,255,255,0.9)\",\n color: activeMode === mode ? \"#fff\" : \"#555\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 2px 5px rgba(0,0,0,0.1)\",\n transition: \"all 0.2s ease\",\n transform: activeMode === mode ? \"scale(1.1)\" : \"scale(1)\",\n }}\n aria-label={mode}\n >\n {icons[mode] || mode[0].toUpperCase()}\n </button>\n\n <style>{`\n @keyframes fadeIn {\n from { opacity: 0; transform: translateX(5px); }\n to { opacity: 1; transform: translateX(0); }\n }\n `}</style>\n </div>\n ))}\n </div>\n );\n};\n","import React, { useRef, useState, useEffect } from \"react\";\nimport { InteractionConfig, InteractionMode } from \"../core/types\";\nimport { useLoadingInteraction } from \"./hooks\";\nimport { ModeSwitcher } from \"./ModeSwitcher\";\n\nexport interface LoadingInteractionProps\n extends Omit<InteractionConfig, \"isLoading\"> {\n isLoading: boolean;\n children?: React.ReactNode;\n width?: string | number;\n height?: string | number;\n style?: Partial<CSSStyleDeclaration>;\n transitionDuration?: number;\n}\n\nexport const LoadingInteraction: React.FC<LoadingInteractionProps> = (\n props\n) => {\n const {\n isLoading,\n children,\n availableModes = [\"game\", \"facts\", \"doodle\"],\n showModeSwitcher = true,\n width = \"100%\",\n height = \"300px\",\n ...config\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [currentMode, setCurrentMode] = useState<InteractionMode>(\n props.mode || availableModes[0] || \"none\"\n );\n\n // Sync mode prop if changed externally\n useEffect(() => {\n if (props.mode) setCurrentMode(props.mode);\n }, [props.mode]);\n\n const activeConfig = {\n ...config,\n isLoading,\n mode: currentMode,\n availableModes,\n style: props.style,\n transitionDuration: props.transitionDuration,\n };\n\n useLoadingInteraction(containerRef, activeConfig);\n\n if (!isLoading) {\n return <>{children}</>;\n }\n\n return (\n <div style={{ position: \"relative\", width, height }}>\n {showModeSwitcher && availableModes.length > 1 && (\n <div\n style={{\n position: \"absolute\",\n bottom: 12,\n right: 12,\n width: \"auto\",\n zIndex: 20,\n pointerEvents: \"none\", // Allow clicks to pass through transparent areas\n }}\n >\n {/* Re-enable pointer events for the switcher items */}\n <div style={{ pointerEvents: \"auto\" }}>\n <ModeSwitcher\n modes={availableModes}\n activeMode={currentMode}\n onModeChange={setCurrentMode}\n />\n </div>\n </div>\n )}\n <div\n ref={containerRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n background: \"#f5f5f5\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: \"8px\",\n overflow: \"hidden\",\n }}\n />\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk4DE2IREA_cjs = require('./chunk-4DE2IREA.cjs');
|
|
4
|
+
|
|
5
|
+
// src/doodle/basic-canvas.ts
|
|
6
|
+
var CanvasInstance = class {
|
|
7
|
+
constructor(container, config) {
|
|
8
|
+
chunk4DE2IREA_cjs.__publicField(this, "container");
|
|
9
|
+
chunk4DE2IREA_cjs.__publicField(this, "canvas");
|
|
10
|
+
chunk4DE2IREA_cjs.__publicField(this, "ctx");
|
|
11
|
+
chunk4DE2IREA_cjs.__publicField(this, "config");
|
|
12
|
+
chunk4DE2IREA_cjs.__publicField(this, "isDrawing", false);
|
|
13
|
+
this.container = container;
|
|
14
|
+
this.config = config || {};
|
|
15
|
+
this.container.style.display = "flex";
|
|
16
|
+
this.container.style.flexDirection = "column";
|
|
17
|
+
this.container.style.alignItems = "center";
|
|
18
|
+
this.canvas = document.createElement("canvas");
|
|
19
|
+
this.canvas.style.border = "1px solid #ccc";
|
|
20
|
+
this.canvas.style.width = "90%";
|
|
21
|
+
this.canvas.style.flex = "1";
|
|
22
|
+
this.canvas.style.minHeight = "0";
|
|
23
|
+
this.canvas.style.background = "#fff";
|
|
24
|
+
this.container.appendChild(this.canvas);
|
|
25
|
+
this.ctx = this.canvas.getContext("2d");
|
|
26
|
+
const observer = new ResizeObserver(() => this.resize());
|
|
27
|
+
observer.observe(this.canvas);
|
|
28
|
+
setTimeout(() => this.resize(), 0);
|
|
29
|
+
this.setupEvents();
|
|
30
|
+
const clearBtn = document.createElement("button");
|
|
31
|
+
clearBtn.innerText = "Clear Canvas";
|
|
32
|
+
clearBtn.style.marginTop = "15px";
|
|
33
|
+
clearBtn.style.padding = "8px 16px";
|
|
34
|
+
clearBtn.style.cursor = "pointer";
|
|
35
|
+
clearBtn.style.border = "none";
|
|
36
|
+
clearBtn.style.borderRadius = "20px";
|
|
37
|
+
clearBtn.style.backgroundColor = "#e2e8f0";
|
|
38
|
+
clearBtn.style.color = "#475569";
|
|
39
|
+
clearBtn.style.fontWeight = "600";
|
|
40
|
+
clearBtn.style.fontSize = "0.9rem";
|
|
41
|
+
clearBtn.style.transition = "all 0.2s ease";
|
|
42
|
+
clearBtn.style.boxShadow = "0 2px 4px rgba(0,0,0,0.05)";
|
|
43
|
+
clearBtn.onclick = () => this.clear();
|
|
44
|
+
clearBtn.onmouseenter = () => {
|
|
45
|
+
clearBtn.style.backgroundColor = "#cbd5e1";
|
|
46
|
+
clearBtn.style.transform = "translateY(-1px)";
|
|
47
|
+
};
|
|
48
|
+
clearBtn.onmouseleave = () => {
|
|
49
|
+
clearBtn.style.backgroundColor = "#e2e8f0";
|
|
50
|
+
clearBtn.style.transform = "translateY(0)";
|
|
51
|
+
};
|
|
52
|
+
this.container.appendChild(clearBtn);
|
|
53
|
+
}
|
|
54
|
+
resize() {
|
|
55
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
56
|
+
if (this.canvas.width !== rect.width || this.canvas.height !== rect.height) {
|
|
57
|
+
const data = this.canvas.toDataURL();
|
|
58
|
+
this.canvas.width = rect.width;
|
|
59
|
+
this.canvas.height = rect.height;
|
|
60
|
+
this.ctx.lineCap = "round";
|
|
61
|
+
this.setBrushSize(this.config.defaultBrushSize || 3);
|
|
62
|
+
this.setBrushColor(this.config.defaultColor || "#000");
|
|
63
|
+
const img = new Image();
|
|
64
|
+
img.onload = () => this.ctx.drawImage(img, 0, 0);
|
|
65
|
+
img.src = data;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
setupEvents() {
|
|
69
|
+
this.canvas.addEventListener("mousedown", this.start.bind(this));
|
|
70
|
+
this.canvas.addEventListener("mousemove", this.draw.bind(this));
|
|
71
|
+
this.canvas.addEventListener("mouseup", this.stop.bind(this));
|
|
72
|
+
this.canvas.addEventListener("mouseout", this.stop.bind(this));
|
|
73
|
+
this.canvas.addEventListener("touchstart", (e) => {
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
const touch = e.touches[0];
|
|
76
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
77
|
+
this.start({
|
|
78
|
+
offsetX: touch.clientX - rect.left,
|
|
79
|
+
offsetY: touch.clientY - rect.top
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
this.canvas.addEventListener("touchmove", (e) => {
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
const touch = e.touches[0];
|
|
85
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
86
|
+
this.draw({
|
|
87
|
+
offsetX: touch.clientX - rect.left,
|
|
88
|
+
offsetY: touch.clientY - rect.top
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
this.canvas.addEventListener("touchend", this.stop.bind(this));
|
|
92
|
+
}
|
|
93
|
+
start(e) {
|
|
94
|
+
this.isDrawing = true;
|
|
95
|
+
this.ctx.beginPath();
|
|
96
|
+
this.ctx.moveTo(e.offsetX, e.offsetY);
|
|
97
|
+
}
|
|
98
|
+
draw(e) {
|
|
99
|
+
if (!this.isDrawing) return;
|
|
100
|
+
this.ctx.lineTo(e.offsetX, e.offsetY);
|
|
101
|
+
this.ctx.stroke();
|
|
102
|
+
}
|
|
103
|
+
stop() {
|
|
104
|
+
if (!this.isDrawing) return;
|
|
105
|
+
this.isDrawing = false;
|
|
106
|
+
this.ctx.closePath();
|
|
107
|
+
}
|
|
108
|
+
clear() {
|
|
109
|
+
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
110
|
+
}
|
|
111
|
+
undo() {
|
|
112
|
+
}
|
|
113
|
+
redo() {
|
|
114
|
+
}
|
|
115
|
+
async save() {
|
|
116
|
+
return this.canvas.toDataURL();
|
|
117
|
+
}
|
|
118
|
+
load(url) {
|
|
119
|
+
const img = new Image();
|
|
120
|
+
img.onload = () => this.ctx.drawImage(img, 0, 0);
|
|
121
|
+
img.src = url;
|
|
122
|
+
}
|
|
123
|
+
setBrushColor(color) {
|
|
124
|
+
this.ctx.strokeStyle = color;
|
|
125
|
+
}
|
|
126
|
+
setBrushSize(size) {
|
|
127
|
+
this.ctx.lineWidth = size;
|
|
128
|
+
}
|
|
129
|
+
destroy() {
|
|
130
|
+
this.container.innerHTML = "";
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var BasicDoodle = {
|
|
134
|
+
id: "basic-doodle",
|
|
135
|
+
name: "Basic Doodle",
|
|
136
|
+
renderMini: (c, cfg) => new CanvasInstance(c, cfg),
|
|
137
|
+
renderFull: (c, cfg) => new CanvasInstance(c, cfg)
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
exports.BasicDoodle = BasicDoodle;
|
|
141
|
+
//# sourceMappingURL=chunk-JG5ZMB2Y.cjs.map
|
|
142
|
+
//# sourceMappingURL=chunk-JG5ZMB2Y.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/doodle/basic-canvas.ts"],"names":["__publicField"],"mappings":";;;;;AAEA,IAAM,iBAAN,MAA+C;AAAA,EAO7C,WAAA,CAAY,WAAwB,MAAA,EAAuB;AAN3D,IAAAA,+BAAA,CAAA,IAAA,EAAQ,WAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,KAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAAA,+BAAA,CAAA,IAAA,EAAQ,WAAA,EAAY,KAAA,CAAA;AAGlB,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,MAAA,GAAS,UAAU,EAAC;AAEzB,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,OAAA,GAAU,MAAA;AAC/B,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,aAAA,GAAgB,QAAA;AACrC,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,UAAA,GAAa,QAAA;AAElC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC7C,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,MAAA,GAAS,gBAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,KAAA,GAAQ,KAAA;AAC1B,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,IAAA,GAAO,GAAA;AACzB,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,SAAA,GAAY,GAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,UAAA,GAAa,MAAA;AAE/B,IAAA,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA;AAEtC,IAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAGtC,IAAA,MAAM,WAAW,IAAI,cAAA,CAAe,MAAM,IAAA,CAAK,QAAQ,CAAA;AACvD,IAAA,QAAA,CAAS,OAAA,CAAQ,KAAK,MAAM,CAAA;AAG5B,IAAA,UAAA,CAAW,MAAM,IAAA,CAAK,MAAA,EAAO,EAAG,CAAC,CAAA;AAEjC,IAAA,IAAA,CAAK,WAAA,EAAY;AAGjB,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAChD,IAAA,QAAA,CAAS,SAAA,GAAY,cAAA;AACrB,IAAA,QAAA,CAAS,MAAM,SAAA,GAAY,MAAA;AAC3B,IAAA,QAAA,CAAS,MAAM,OAAA,GAAU,UAAA;AACzB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,SAAA;AACxB,IAAA,QAAA,CAAS,MAAM,MAAA,GAAS,MAAA;AACxB,IAAA,QAAA,CAAS,MAAM,YAAA,GAAe,MAAA;AAC9B,IAAA,QAAA,CAAS,MAAM,eAAA,GAAkB,SAAA;AACjC,IAAA,QAAA,CAAS,MAAM,KAAA,GAAQ,SAAA;AACvB,IAAA,QAAA,CAAS,MAAM,UAAA,GAAa,KAAA;AAC5B,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,QAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,UAAA,GAAa,eAAA;AAC5B,IAAA,QAAA,CAAS,MAAM,SAAA,GAAY,4BAAA;AAE3B,IAAA,QAAA,CAAS,OAAA,GAAU,MAAM,IAAA,CAAK,KAAA,EAAM;AAGpC,IAAA,QAAA,CAAS,eAAe,MAAM;AAC5B,MAAA,QAAA,CAAS,MAAM,eAAA,GAAkB,SAAA;AACjC,MAAA,QAAA,CAAS,MAAM,SAAA,GAAY,kBAAA;AAAA,IAC7B,CAAA;AACA,IAAA,QAAA,CAAS,eAAe,MAAM;AAC5B,MAAA,QAAA,CAAS,MAAM,eAAA,GAAkB,SAAA;AACjC,MAAA,QAAA,CAAS,MAAM,SAAA,GAAY,eAAA;AAAA,IAC7B,CAAA;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,YAAY,QAAQ,CAAA;AAAA,EACrC;AAAA,EAEQ,MAAA,GAAS;AACf,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,qBAAA,EAAsB;AAE/C,IAAA,IACE,IAAA,CAAK,OAAO,KAAA,KAAU,IAAA,CAAK,SAC3B,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,IAAA,CAAK,MAAA,EAC5B;AAEA,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,SAAA,EAAU;AAEnC,MAAA,IAAA,CAAK,MAAA,CAAO,QAAQ,IAAA,CAAK,KAAA;AACzB,MAAA,IAAA,CAAK,MAAA,CAAO,SAAS,IAAA,CAAK,MAAA;AAG1B,MAAA,IAAA,CAAK,IAAI,OAAA,GAAU,OAAA;AACnB,MAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,MAAA,CAAO,gBAAA,IAAoB,CAAC,CAAA;AACnD,MAAA,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,MAAA,CAAO,YAAA,IAAgB,MAAM,CAAA;AAGrD,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AACtB,MAAA,GAAA,CAAI,SAAS,MAAM,IAAA,CAAK,IAAI,SAAA,CAAU,GAAA,EAAK,GAAG,CAAC,CAAA;AAC/C,MAAA,GAAA,CAAI,GAAA,GAAM,IAAA;AAAA,IACZ;AAAA,EACF;AAAA,EAEQ,WAAA,GAAc;AACpB,IAAA,IAAA,CAAK,OAAO,gBAAA,CAAiB,WAAA,EAAa,KAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAC/D,IAAA,IAAA,CAAK,OAAO,gBAAA,CAAiB,WAAA,EAAa,KAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAC9D,IAAA,IAAA,CAAK,OAAO,gBAAA,CAAiB,SAAA,EAAW,KAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAC5D,IAAA,IAAA,CAAK,OAAO,gBAAA,CAAiB,UAAA,EAAY,KAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAG7D,IAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,YAAA,EAAc,CAAC,CAAA,KAAM;AAChD,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AACzB,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,qBAAA,EAAsB;AAC/C,MAAA,IAAA,CAAK,KAAA,CAAM;AAAA,QACT,OAAA,EAAS,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK,IAAA;AAAA,QAC9B,OAAA,EAAS,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK;AAAA,OACxB,CAAA;AAAA,IACV,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,WAAA,EAAa,CAAC,CAAA,KAAM;AAC/C,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AACzB,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,qBAAA,EAAsB;AAC/C,MAAA,IAAA,CAAK,IAAA,CAAK;AAAA,QACR,OAAA,EAAS,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK,IAAA;AAAA,QAC9B,OAAA,EAAS,KAAA,CAAM,OAAA,GAAU,IAAA,CAAK;AAAA,OACxB,CAAA;AAAA,IACV,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,OAAO,gBAAA,CAAiB,UAAA,EAAY,KAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EAC/D;AAAA,EAEQ,MAAM,CAAA,EAAe;AAC3B,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,IAAI,SAAA,EAAU;AACnB,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAAA,EACtC;AAAA,EAEQ,KAAK,CAAA,EAAe;AAC1B,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,IAAA,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACpC,IAAA,IAAA,CAAK,IAAI,MAAA,EAAO;AAAA,EAClB;AAAA,EAEQ,IAAA,GAAO;AACb,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AACjB,IAAA,IAAA,CAAK,IAAI,SAAA,EAAU;AAAA,EACrB;AAAA,EAEA,KAAA,GAAQ;AACN,IAAA,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,EAAG,CAAA,EAAG,KAAK,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EAChE;AAAA,EAEA,IAAA,GAAO;AAAA,EAAC;AAAA,EACR,IAAA,GAAO;AAAA,EAAC;AAAA,EACR,MAAM,IAAA,GAAO;AACX,IAAA,OAAO,IAAA,CAAK,OAAO,SAAA,EAAU;AAAA,EAC/B;AAAA,EACA,KAAK,GAAA,EAAa;AAChB,IAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AACtB,IAAA,GAAA,CAAI,SAAS,MAAM,IAAA,CAAK,IAAI,SAAA,CAAU,GAAA,EAAK,GAAG,CAAC,CAAA;AAC/C,IAAA,GAAA,CAAI,GAAA,GAAM,GAAA;AAAA,EACZ;AAAA,EAEA,cAAc,KAAA,EAAe;AAC3B,IAAA,IAAA,CAAK,IAAI,WAAA,GAAc,KAAA;AAAA,EACzB;AAAA,EACA,aAAa,IAAA,EAAc;AACzB,IAAA,IAAA,CAAK,IAAI,SAAA,GAAY,IAAA;AAAA,EACvB;AAAA,EAEA,OAAA,GAAU;AACR,IAAA,IAAA,CAAK,UAAU,SAAA,GAAY,EAAA;AAAA,EAC7B;AACF,CAAA;AAEO,IAAM,WAAA,GAA4B;AAAA,EACvC,EAAA,EAAI,cAAA;AAAA,EACJ,IAAA,EAAM,cAAA;AAAA,EACN,YAAY,CAAC,CAAA,EAAG,QAAQ,IAAI,cAAA,CAAe,GAAG,GAAG,CAAA;AAAA,EACjD,YAAY,CAAC,CAAA,EAAG,QAAQ,IAAI,cAAA,CAAe,GAAG,GAAG;AACnD","file":"chunk-JG5ZMB2Y.cjs","sourcesContent":["import { DoodlePlugin, DoodleInstance, DoodleConfig } from \"../core/types\";\n\nclass CanvasInstance implements DoodleInstance {\n private container: HTMLElement;\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private config: DoodleConfig;\n private isDrawing = false;\n\n constructor(container: HTMLElement, config?: DoodleConfig) {\n this.container = container;\n this.config = config || {};\n\n this.container.style.display = \"flex\";\n this.container.style.flexDirection = \"column\";\n this.container.style.alignItems = \"center\";\n\n this.canvas = document.createElement(\"canvas\");\n this.canvas.style.border = \"1px solid #ccc\";\n this.canvas.style.width = \"90%\";\n this.canvas.style.flex = \"1\"; // Fill available space\n this.canvas.style.minHeight = \"0\";\n this.canvas.style.background = \"#fff\";\n\n this.container.appendChild(this.canvas);\n\n this.ctx = this.canvas.getContext(\"2d\")!;\n\n // Resize observer\n const observer = new ResizeObserver(() => this.resize());\n observer.observe(this.canvas);\n\n // Wait for layout\n setTimeout(() => this.resize(), 0);\n\n this.setupEvents();\n\n // Clear Button\n const clearBtn = document.createElement(\"button\");\n clearBtn.innerText = \"Clear Canvas\";\n clearBtn.style.marginTop = \"15px\";\n clearBtn.style.padding = \"8px 16px\";\n clearBtn.style.cursor = \"pointer\";\n clearBtn.style.border = \"none\";\n clearBtn.style.borderRadius = \"20px\";\n clearBtn.style.backgroundColor = \"#e2e8f0\";\n clearBtn.style.color = \"#475569\";\n clearBtn.style.fontWeight = \"600\";\n clearBtn.style.fontSize = \"0.9rem\";\n clearBtn.style.transition = \"all 0.2s ease\";\n clearBtn.style.boxShadow = \"0 2px 4px rgba(0,0,0,0.05)\";\n\n clearBtn.onclick = () => this.clear();\n\n // Add hover effect\n clearBtn.onmouseenter = () => {\n clearBtn.style.backgroundColor = \"#cbd5e1\";\n clearBtn.style.transform = \"translateY(-1px)\";\n };\n clearBtn.onmouseleave = () => {\n clearBtn.style.backgroundColor = \"#e2e8f0\";\n clearBtn.style.transform = \"translateY(0)\";\n };\n\n this.container.appendChild(clearBtn);\n }\n\n private resize() {\n const rect = this.canvas.getBoundingClientRect();\n // Only resize if dimensions changed to avoid clearing\n if (\n this.canvas.width !== rect.width ||\n this.canvas.height !== rect.height\n ) {\n // Save content\n const data = this.canvas.toDataURL();\n\n this.canvas.width = rect.width;\n this.canvas.height = rect.height;\n\n // Restore styling\n this.ctx.lineCap = \"round\";\n this.setBrushSize(this.config.defaultBrushSize || 3);\n this.setBrushColor(this.config.defaultColor || \"#000\");\n\n // Restore content\n const img = new Image();\n img.onload = () => this.ctx.drawImage(img, 0, 0);\n img.src = data;\n }\n }\n\n private setupEvents() {\n this.canvas.addEventListener(\"mousedown\", this.start.bind(this));\n this.canvas.addEventListener(\"mousemove\", this.draw.bind(this));\n this.canvas.addEventListener(\"mouseup\", this.stop.bind(this));\n this.canvas.addEventListener(\"mouseout\", this.stop.bind(this));\n\n // Touch support\n this.canvas.addEventListener(\"touchstart\", (e) => {\n e.preventDefault();\n const touch = e.touches[0];\n const rect = this.canvas.getBoundingClientRect();\n this.start({\n offsetX: touch.clientX - rect.left,\n offsetY: touch.clientY - rect.top,\n } as any);\n });\n this.canvas.addEventListener(\"touchmove\", (e) => {\n e.preventDefault();\n const touch = e.touches[0];\n const rect = this.canvas.getBoundingClientRect();\n this.draw({\n offsetX: touch.clientX - rect.left,\n offsetY: touch.clientY - rect.top,\n } as any);\n });\n this.canvas.addEventListener(\"touchend\", this.stop.bind(this));\n }\n\n private start(e: MouseEvent) {\n this.isDrawing = true;\n this.ctx.beginPath();\n this.ctx.moveTo(e.offsetX, e.offsetY);\n }\n\n private draw(e: MouseEvent) {\n if (!this.isDrawing) return;\n this.ctx.lineTo(e.offsetX, e.offsetY);\n this.ctx.stroke();\n }\n\n private stop() {\n if (!this.isDrawing) return;\n this.isDrawing = false;\n this.ctx.closePath();\n }\n\n clear() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n undo() {}\n redo() {}\n async save() {\n return this.canvas.toDataURL();\n }\n load(url: string) {\n const img = new Image();\n img.onload = () => this.ctx.drawImage(img, 0, 0);\n img.src = url;\n }\n\n setBrushColor(color: string) {\n this.ctx.strokeStyle = color;\n }\n setBrushSize(size: number) {\n this.ctx.lineWidth = size;\n }\n\n destroy() {\n this.container.innerHTML = \"\";\n }\n}\n\nexport const BasicDoodle: DoodlePlugin = {\n id: \"basic-doodle\",\n name: \"Basic Doodle\",\n renderMini: (c, cfg) => new CanvasInstance(c, cfg),\n renderFull: (c, cfg) => new CanvasInstance(c, cfg),\n};\n"]}
|