{"id":19013975,"url":"https://github.com/pictogrammers/pixel-editor","last_synced_at":"2025-09-06T15:32:55.535Z","repository":{"id":65692135,"uuid":"583982397","full_name":"Pictogrammers/Pixel-Editor","owner":"Pictogrammers","description":"Browser Based Pixel Editor","archived":false,"fork":false,"pushed_at":"2023-10-23T02:38:18.000Z","size":630,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-07T05:51:41.663Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Pictogrammers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-31T18:54:30.000Z","updated_at":"2023-12-19T06:09:25.000Z","dependencies_parsed_at":"2023-02-18T18:30:37.109Z","dependency_job_id":"c9bcfa64-8755-4710-a8b7-b6cbe5878fb7","html_url":"https://github.com/Pictogrammers/Pixel-Editor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Pictogrammers/Pixel-Editor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pictogrammers%2FPixel-Editor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pictogrammers%2FPixel-Editor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pictogrammers%2FPixel-Editor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pictogrammers%2FPixel-Editor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Pictogrammers","download_url":"https://codeload.github.com/Pictogrammers/Pixel-Editor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pictogrammers%2FPixel-Editor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273925650,"owners_count":25192311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T19:26:52.020Z","updated_at":"2025-09-06T15:32:55.203Z","avatar_url":"https://github.com/Pictogrammers.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pixel-Editor\n\nBrowser based Pixel Editor for creating pixel assets or fonts.\n\n- Editor\n  - Self contained React drawing canvas.\n- Application\n  - Work in Progress Features\n    - Eraser (pen erasers work on tablets)\n    - Shapes (Line, Rect, Circle)\n    - Cache state to `localStorage` to persist changes\n\n## Editor Canvas\n\nMajority of the functionality lives in the `Editor` component.\n\n\u003e Any contributions or updates to the Editor component must be self contained.\n\n### Props\n\n- `width` - Image width\n- `height` - Image height\n- `size` - Grid size\n- `onChange` - Get the path data on change.\n\n\u003e **Note:** `onChange` criteria for triggering:\n\u003e - 1 second after any concurrent drawing.\n\u003e - Instantly after undo/redo actions.\n\n### Methods\n\n- `getJson: (includeHistory: Boolean) =\u003e string`\n- `setJson: () =\u003e void`\n- `getVersion: () =\u003e number`\n- `addColor: (color: EditorColor) =\u003e void`\n- `updateColor: (index: number, color: EditorColor) =\u003e void`\n- `removeColor: (index: number, mergeIntoIndex: number) =\u003e void`\n- `moveColor: (fromIndex: number, toIndex: number) =\u003e void`\n- `getColors: () =\u003e EditorColor[]`\n- `clear: () =\u003e void`\n- `clearHistory: () =\u003e void`\n- `getHistory: () =\u003e []`\n- `setMeta: (property: string, value: string | number | Boolean ) =\u003e void`\n- `getMeta: (property: string) =\u003e string | number | Boolean`\n- `getMetaProperties: () =\u003e Object`\n- `applyTemplate: (data: number[][]) =\u003e void`\n- `flipHorizontal: () =\u003e void`\n- `flipVertical: () =\u003e void`\n- `translate: (x: number, y: number) =\u003e void`\n- `rotate: (counterClockwise?: boolean) =\u003e void`\n- `invert: () =\u003e void`\n- `undo: () =\u003e void`\n- `redo: () =\u003e void`\n- `hasUndo: () =\u003e boolean`\n- `hasRedo: () =\u003e boolean`\n- `inputModePixel: () =\u003e void`\n- `inputModeLine: () =\u003e void`\n- `inputModeRectangle: () =\u003e void`\n- `inputModeRectangleOutline: () =\u003e void`\n- `inputModeEllipse: () =\u003e void`\n- `inputModeEllipseOutline: () =\u003e void`\n\n### Usage\n\n```tsx\nimport Editor, { EditorRef } from '@pictogrammers/editor';\n\nfunction App() {\n  const editorRef = useRef\u003cEditorRef\u003e(null);\n  const width = 22;\n  const height = 22;\n  const size = 10; // Grid size\n\n  function handleChange(path: string) {\n    console.log('Path:', path);\n  }\n\n  function handleClear() {\n    editorRef.current?.clear();\n  }\n\n  return (\n    \u003cEditor ref={editorRef}\n            width={width}\n            height={height}\n            size={size}\n            onChange={handleChange}\u003e\u003c/Editor\u003e\n    \u003cbutton onClick={handleClear}\u003eClear\u003c/button\u003e\n  );\n}\n\nexport default App;\n```\n\n### Managing Data\n\nThe `data` grid stores each pixel as a reference to the colors array. A diagonal line in a 3x3 canvas would look like below.\n\n```tsx\ndata = [\n  [0, 0, 1],\n  [0, 1, 0],\n  [1, 0, 0]\n]\n```\n\nSee the helper methods above for all the quick operations for modify the data grid.\n\n### Managing Colors\n\nThe `data` grid stores each pixel as a reference to the colors array. For example `1` in the data grid would be the 2nd item in the colors array. The color object looks like below:\n\n```tsx\ntype Color = {\n  r: number;    // Red 0 to255\n  g: number;    // Green 0 to 255\n  b: number;    // Blue 0 to 255\n  a: number;    // Alpha 0 to 1\n  name: string; // Friendly name\n}\n```\n\nThe default `colors` array then looks like below:\n\n```tsx\ncolors = [\n  { r: 0, g: 0, b: 0, a: 0, name: 'transparent' },\n  { r: 0, g: 0, b: 0, a: 1, name: 'Black' }\n]\n```\n\nTo ensure the indexes in the `data` grid stays in sync with the `colors` array the helper methods below are provided.\n\n- `getColors: ()`\n  - Get an array of colors\n- `addColor: (color: EditorColor)`\n  - Add a new color to the end of the array.\n- `updateColor: (index: number, color: EditorColor)`\n  - Update the color value.\n- `removeColor: (index: number, mergeIntoIndex: number)`\n  - Removing a color requires selecting an existing color.\n  - This operation throws an error for less than 2 colors.\n- `moveColor: (fromIndex: number, toIndex: number)`\n  - Swap the position of 2 colors.\n- `mergeColor: (fromIndex: number, toIndex: number)`\n  - Merge one color into another. This is only supported with more than 2 colors.\n\n\u003e **Note:** All color operations are added to the canvas history.\n\n### Managing History\n\nAll operations that change the canvas or meta data create change records in the history.\n\n- Pixel - Single color change on the canvas.\n  - After 1 second or any other canvas operation is called.\n  - `{ type: 'pixel', value: [] }`\n- Undo - `{ type: 'undo', value: 2 }`\n- Redo\n  - Decreases the Undo `value` by 1 if it is the last history value.\n- Clear\n  - `{ type: 'clear', value: { data: [] } }`\n- Width / Height\n  - `{ type: 'width', value: { from: 22, to: 24, data: [] } }`\n  - `{ type: 'height', value: { from: 22, to: 24, data: [] } }`\n  - Note: Resizing canvas takes a snapshot of the canvas prior to resize\n- Color\n  - `{ type: 'addColor', value: EditorColor }`\n  - `{ type: 'removeColor', value: index }`\n  - `{ type: 'updateColor', value: EditorColor }`\n  - `{ type: 'moveColor', value: EditorColor }`\n  - `{ type: 'mergeColor', value: { from: 2, to: 1 } }`\n- Meta - Any change that impacts meta data.\n  - `{ type: 'meta', value: { name: 'Foo', _name: 'Bar' }}`\n\nThe application can modify the history log through the helper methods:\n\n- `undo()` - Undo\n- `redo()` - Redo\n- `hasUndo()` - Has at least 1 item in the history\n- `hasRedo()` - Last history record is `type: 'undo'`\n- `setMeta(property, value)` - Only supports adding meta data.\n  - `{ type: 'meta', value: { property: value, _property: value } }`\n  - The `_property` is the previous value or `null`\n  - Setting a `null` value removes the property.\n- `getMeta(property)`\n- `getMetaProperties()` - Properties object.\n- `getHistory()` - Retrieves entire history log.\n- `clearHistory()` - Clears the history\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpictogrammers%2Fpixel-editor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpictogrammers%2Fpixel-editor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpictogrammers%2Fpixel-editor/lists"}