@nice2dev/ui-graphics 1.0.3 → 1.0.4

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.
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
3
3
  import styles from './PixelEditor.module.css.js';
4
- import { NiceModal as ko, NiceButton as Ee, NiceSelect as tn, NiceNumberInput as vi, NiceCheckbox as qi } from '../ui/dist/index.js';
4
+ import { NiceModal as _s, NiceButton as Oe, NiceSelect as nn, NiceNumberInput as Ri, NiceCheckbox as ma } from '../ui/dist/index.js';
5
5
  import { getAllParts, assembleSprite, applyIsometricProjection, getPart, generateAllDirections, render8DirSpriteSheet, getPartsByCategory, ALL_DIRECTIONS } from './spriteGeneratorCore.js';
6
6
  import { CHARACTER_PRESETS, initCharacterParts, SKIN_PALETTES, HAIR_PALETTES, CLOTHING_PALETTES } from './characterGeneratorPresets.js';
7
7
  import { BUILDING_PRESETS, assembleBuildingFromConfig, initBuildingParts, WALL_PALETTES, ROOF_PALETTES } from './buildingGeneratorPresets.js';
@@ -195,26 +195,26 @@ const NiceSpriteGeneratorPanel = ({ onSendToCanvas, onClose, }) => {
195
195
  }
196
196
  }, [tab, skinPalette, hairPalette, clothPalette, wallPalette, roofPalette, furPalette]);
197
197
  /* ── Render ── */
198
- return (jsx(ko, { open: true, onClose: onClose, title: "Sprite Generator", children: jsxs("div", { className: styles.genPanel, children: [jsxs("div", { className: styles.genHeader, children: [jsx("h3", { children: "Sprite Generator" }), jsx(Ee, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: onClose, title: "Close", children: "\u2715" })] }), jsx("div", { className: styles.genTabs, children: ['character', 'building', 'animal'].map(t => (jsxs(Ee, { className: `${styles.genTabBtn} ${tab === t ? styles.genTabBtnActive : ''}`, variant: tab === t ? 'primary' : 'ghost', size: "sm", onClick: () => setTab(t), children: [t === 'character' ? '🧑' : t === 'building' ? '🏠' : '🐾', ' ', t.charAt(0).toUpperCase() + t.slice(1)] }, t))) }), jsxs("div", { className: styles.genBody, children: [jsxs("div", { className: styles.genLeft, children: [jsxs("div", { className: styles.panelSection, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Presets" }) }), jsx("div", { className: styles.genPresetGrid, children: presets.map((preset, i) => (jsx(Ee, { className: `${styles.genPresetBtn} ${i === selectedPresetIdx ? styles.genPresetBtnActive : ''}`, variant: i === selectedPresetIdx ? 'primary' : 'ghost', size: "sm", onClick: () => applyPreset(i), title: preset.name, children: preset.name }, i))) })] }), jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: 'auto' }, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Parts" }) }), categories.map(cat => {
198
+ return (jsx(_s, { open: true, onClose: onClose, title: "Sprite Generator", children: jsxs("div", { className: styles.genPanel, children: [jsxs("div", { className: styles.genHeader, children: [jsx("h3", { children: "Sprite Generator" }), jsx(Oe, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: onClose, title: "Close", children: "\u2715" })] }), jsx("div", { className: styles.genTabs, children: ['character', 'building', 'animal'].map(t => (jsxs(Oe, { className: `${styles.genTabBtn} ${tab === t ? styles.genTabBtnActive : ''}`, variant: tab === t ? 'primary' : 'ghost', size: "sm", onClick: () => setTab(t), children: [t === 'character' ? '🧑' : t === 'building' ? '🏠' : '🐾', ' ', t.charAt(0).toUpperCase() + t.slice(1)] }, t))) }), jsxs("div", { className: styles.genBody, children: [jsxs("div", { className: styles.genLeft, children: [jsxs("div", { className: styles.panelSection, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Presets" }) }), jsx("div", { className: styles.genPresetGrid, children: presets.map((preset, i) => (jsx(Oe, { className: `${styles.genPresetBtn} ${i === selectedPresetIdx ? styles.genPresetBtnActive : ''}`, variant: i === selectedPresetIdx ? 'primary' : 'ghost', size: "sm", onClick: () => applyPreset(i), title: preset.name, children: preset.name }, i))) })] }), jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: 'auto' }, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Parts" }) }), categories.map(cat => {
199
199
  const parts = getPartsByCategory(cat);
200
200
  if (parts.length === 0)
201
201
  return null;
202
202
  return (jsxs("div", { style: { marginBottom: 6 }, children: [jsx("div", { style: { fontSize: 9, color: 'var(--gray-600)', marginBottom: 2, textTransform: 'uppercase' }, children: cat.replace(/([A-Z])/g, ' $1').trim() }), jsx("div", { className: styles.genPartGrid, children: parts.map(part => {
203
203
  const active = selectedParts.some(p => { var _a; return p.partId === part.id && ((_a = p.visible) !== null && _a !== void 0 ? _a : true); });
204
- return (jsx(Ee, { className: `${styles.miniBtn} ${active ? styles.miniBtnActive : ''}`, variant: active ? 'primary' : 'ghost', size: "sm", onClick: () => active ? removePart(part.id) : addPart(part.id), title: part.name, children: part.name.slice(0, 8) }, part.id));
204
+ return (jsx(Oe, { className: `${styles.miniBtn} ${active ? styles.miniBtnActive : ''}`, variant: active ? 'primary' : 'ghost', size: "sm", onClick: () => active ? removePart(part.id) : addPart(part.id), title: part.name, children: part.name.slice(0, 8) }, part.id));
205
205
  }) })] }, cat));
206
- })] })] }), jsxs("div", { className: styles.genCenter, children: [jsx("div", { className: styles.genPreviewWrap, children: jsx("canvas", { ref: previewRef, className: styles.genPreviewCanvas }) }), jsx("div", { className: styles.genDirGrid, children: ALL_DIRECTIONS.map(d => (jsx(Ee, { className: `${styles.miniBtn} ${direction === d ? styles.miniBtnActive : ''}`, variant: direction === d ? 'primary' : 'ghost', size: "sm", onClick: () => setDirection(d), children: d }, d))) }), jsxs("div", { className: styles.genRow, children: [jsx("label", { style: { fontSize: 10, color: 'var(--gray-600)' }, children: "Projection" }), jsx(tn, { className: styles.propSelect, value: projection, onChange: val => setProjection(val), options: [
206
+ })] })] }), jsxs("div", { className: styles.genCenter, children: [jsx("div", { className: styles.genPreviewWrap, children: jsx("canvas", { ref: previewRef, className: styles.genPreviewCanvas }) }), jsx("div", { className: styles.genDirGrid, children: ALL_DIRECTIONS.map(d => (jsx(Oe, { className: `${styles.miniBtn} ${direction === d ? styles.miniBtnActive : ''}`, variant: direction === d ? 'primary' : 'ghost', size: "sm", onClick: () => setDirection(d), children: d }, d))) }), jsxs("div", { className: styles.genRow, children: [jsx("label", { style: { fontSize: 10, color: 'var(--gray-600)' }, children: "Projection" }), jsx(nn, { className: styles.propSelect, value: projection, onChange: val => setProjection(val), options: [
207
207
  { value: 'topDown', label: 'Top-Down' },
208
208
  { value: 'sideView', label: 'Side View' },
209
209
  { value: 'iso25d', label: '2.5D Isometric' },
210
- ] })] }), jsxs("div", { className: styles.genRow, children: [jsx("label", { style: { fontSize: 10, color: 'var(--gray-600)' }, children: "Size" }), jsx(vi, { className: styles.propInput, style: { width: 48 }, min: 8, max: 256, value: canvasW, onChange: val => setCanvasW(val !== null && val !== void 0 ? val : 32) }), jsx("span", { style: { fontSize: 10, color: 'var(--gray-600)' }, children: "\u00D7" }), jsx(vi, { className: styles.propInput, style: { width: 48 }, min: 8, max: 256, value: canvasH, onChange: val => setCanvasH(val !== null && val !== void 0 ? val : 32) })] }), jsx(qi, { checked: generate8Dir, onChange: checked => setGenerate8Dir(checked), label: "Generate 8-direction sheet", className: styles.checkLabel })] }), jsxs("div", { className: styles.genRight, children: [jsxs("div", { className: styles.panelSection, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Colors" }) }), paletteGroups.map(group => {
210
+ ] })] }), jsxs("div", { className: styles.genRow, children: [jsx("label", { style: { fontSize: 10, color: 'var(--gray-600)' }, children: "Size" }), jsx(Ri, { className: styles.propInput, style: { width: 48 }, min: 8, max: 256, value: canvasW, onChange: val => setCanvasW(val !== null && val !== void 0 ? val : 32) }), jsx("span", { style: { fontSize: 10, color: 'var(--gray-600)' }, children: "\u00D7" }), jsx(Ri, { className: styles.propInput, style: { width: 48 }, min: 8, max: 256, value: canvasH, onChange: val => setCanvasH(val !== null && val !== void 0 ? val : 32) })] }), jsx(ma, { checked: generate8Dir, onChange: checked => setGenerate8Dir(checked), label: "Generate 8-direction sheet", className: styles.checkLabel })] }), jsxs("div", { className: styles.genRight, children: [jsxs("div", { className: styles.panelSection, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Colors" }) }), paletteGroups.map(group => {
211
211
  var _a;
212
- return (jsxs("div", { style: { marginBottom: 6 }, children: [jsx("div", { style: { fontSize: 9, color: 'var(--gray-600)', marginBottom: 2 }, children: group.label }), jsx(tn, { className: styles.propSelect, value: group.value, onChange: val => group.set(val), options: group.options.map(opt => ({ value: opt.id, label: opt.name })) }), jsx("div", { className: styles.genColorSwatches, children: (_a = group.options.find(o => o.id === group.value)) === null || _a === void 0 ? void 0 : _a.colors.map((c, i) => (jsx("div", { className: styles.genColorSwatch, style: { backgroundColor: c }, title: c }, i))) })] }, group.label));
212
+ return (jsxs("div", { style: { marginBottom: 6 }, children: [jsx("div", { style: { fontSize: 9, color: 'var(--gray-600)', marginBottom: 2 }, children: group.label }), jsx(nn, { className: styles.propSelect, value: group.value, onChange: val => group.set(val), options: group.options.map(opt => ({ value: opt.id, label: opt.name })) }), jsx("div", { className: styles.genColorSwatches, children: (_a = group.options.find(o => o.id === group.value)) === null || _a === void 0 ? void 0 : _a.colors.map((c, i) => (jsx("div", { className: styles.genColorSwatch, style: { backgroundColor: c }, title: c }, i))) })] }, group.label));
213
213
  })] }), jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: 'auto' }, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: "Assembly" }) }), selectedParts.map((ap, i) => {
214
214
  var _a, _b, _c, _d;
215
215
  const part = partsMapRef.current.get(ap.partId);
216
- return (jsxs("div", { className: styles.genAssemblyItem, children: [jsx(Ee, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: () => togglePart(ap.partId), title: ((_a = ap.visible) !== null && _a !== void 0 ? _a : true) ? 'Hide' : 'Show', children: ((_b = ap.visible) !== null && _b !== void 0 ? _b : true) ? '👁' : '─' }), jsx("span", { className: styles.genAssemblyName, children: (_c = part === null || part === void 0 ? void 0 : part.name) !== null && _c !== void 0 ? _c : ap.partId }), jsxs("span", { style: { fontSize: 9, color: 'var(--gray-700)' }, children: ["z:", (_d = part === null || part === void 0 ? void 0 : part.zOrder) !== null && _d !== void 0 ? _d : 0] }), jsx(Ee, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: () => removePart(ap.partId), title: "Remove", children: "\u2715" })] }, ap.partId));
217
- })] })] })] }), jsxs("div", { className: styles.genFooter, children: [jsx(Ee, { className: styles.btnSecondary, variant: "ghost", onClick: onClose, children: "Cancel" }), jsx(Ee, { className: styles.btnPrimary, variant: "primary", onClick: handleSendToCanvas, children: "\uD83D\uDCCB Send to Canvas" })] })] }) }));
216
+ return (jsxs("div", { className: styles.genAssemblyItem, children: [jsx(Oe, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: () => togglePart(ap.partId), title: ((_a = ap.visible) !== null && _a !== void 0 ? _a : true) ? 'Hide' : 'Show', children: ((_b = ap.visible) !== null && _b !== void 0 ? _b : true) ? '👁' : '─' }), jsx("span", { className: styles.genAssemblyName, children: (_c = part === null || part === void 0 ? void 0 : part.name) !== null && _c !== void 0 ? _c : ap.partId }), jsxs("span", { style: { fontSize: 9, color: 'var(--gray-700)' }, children: ["z:", (_d = part === null || part === void 0 ? void 0 : part.zOrder) !== null && _d !== void 0 ? _d : 0] }), jsx(Oe, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: () => removePart(ap.partId), title: "Remove", children: "\u2715" })] }, ap.partId));
217
+ })] })] })] }), jsxs("div", { className: styles.genFooter, children: [jsx(Oe, { className: styles.btnSecondary, variant: "ghost", onClick: onClose, children: "Cancel" }), jsx(Oe, { className: styles.btnPrimary, variant: "primary", onClick: handleSendToCanvas, children: "\uD83D\uDCCB Send to Canvas" })] })] }) }));
218
218
  };
219
219
  NiceSpriteGeneratorPanel.displayName = 'NiceSpriteGeneratorPanel';
220
220
 
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Pixel Art Editor Pro — Aseprite-class features: Indexed color,
3
+ * onion skinning, animation tags, tilemap, sprite slicing,
4
+ * reference layer, symmetry, pixel-perfect, dithering, outline FX,
5
+ * palette generation, retro constraints, isometric, autotile, export.
6
+ *
7
+ * PRO-4.3 — 20 items
8
+ *
9
+ * @module @nice2dev/ui-graphics/pixel/pixel-pro
10
+ */
11
+ const RETRO_PRESETS = {
12
+ nes: {
13
+ console: 'nes',
14
+ maxColors: 4,
15
+ maxPalettes: 8,
16
+ width: 256,
17
+ height: 240,
18
+ spriteWidth: 8,
19
+ spriteHeight: 16,
20
+ maxSprites: 64,
21
+ },
22
+ snes: {
23
+ console: 'snes',
24
+ maxColors: 16,
25
+ maxPalettes: 8,
26
+ width: 256,
27
+ height: 224,
28
+ spriteWidth: 64,
29
+ spriteHeight: 64,
30
+ maxSprites: 128,
31
+ },
32
+ 'game-boy': {
33
+ console: 'game-boy',
34
+ maxColors: 4,
35
+ maxPalettes: 2,
36
+ width: 160,
37
+ height: 144,
38
+ spriteWidth: 8,
39
+ spriteHeight: 16,
40
+ maxSprites: 40,
41
+ },
42
+ c64: {
43
+ console: 'c64',
44
+ maxColors: 16,
45
+ maxPalettes: 1,
46
+ width: 320,
47
+ height: 200,
48
+ spriteWidth: 24,
49
+ spriteHeight: 21,
50
+ maxSprites: 8,
51
+ },
52
+ 'pico-8': {
53
+ console: 'pico-8',
54
+ maxColors: 16,
55
+ maxPalettes: 1,
56
+ width: 128,
57
+ height: 128,
58
+ spriteWidth: 8,
59
+ spriteHeight: 8,
60
+ maxSprites: 128,
61
+ },
62
+ };
63
+
64
+ export { RETRO_PRESETS };
65
+ //# sourceMappingURL=pixel-pro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel-pro.js","sources":["../../../src/pixel/pixel-pro.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;AASG;AA2OI,MAAM,aAAa,GAAqC;AAC7D,IAAA,GAAG,EAAE;AACH,QAAA,OAAO,EAAE,KAAK;AACd,QAAA,SAAS,EAAE,CAAC;AACZ,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,YAAY,EAAE,EAAE;AAChB,QAAA,UAAU,EAAE,EAAE;AACf,KAAA;AACD,IAAA,IAAI,EAAE;AACJ,QAAA,OAAO,EAAE,MAAM;AACf,QAAA,SAAS,EAAE,EAAE;AACb,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,WAAW,EAAE,EAAE;AACf,QAAA,YAAY,EAAE,EAAE;AAChB,QAAA,UAAU,EAAE,GAAG;AAChB,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,SAAS,EAAE,CAAC;AACZ,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,YAAY,EAAE,EAAE;AAChB,QAAA,UAAU,EAAE,EAAE;AACf,KAAA;AACD,IAAA,GAAG,EAAE;AACH,QAAA,OAAO,EAAE,KAAK;AACd,QAAA,SAAS,EAAE,EAAE;AACb,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,WAAW,EAAE,EAAE;AACf,QAAA,YAAY,EAAE,EAAE;AAChB,QAAA,UAAU,EAAE,CAAC;AACd,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,OAAO,EAAE,QAAQ;AACjB,QAAA,SAAS,EAAE,EAAE;AACb,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,WAAW,EAAE,CAAC;AACd,QAAA,YAAY,EAAE,CAAC;AACf,QAAA,UAAU,EAAE,GAAG;AAChB,KAAA;;;;;"}