{"id":22650022,"url":"https://github.com/pauliorandall/p45","last_synced_at":"2026-05-01T15:35:12.650Z","repository":{"id":214690624,"uuid":"737115223","full_name":"PaulioRandall/p45","owner":"PaulioRandall","description":"Svelte library for programmatically crafting grid based SVGs.","archived":false,"fork":false,"pushed_at":"2024-05-28T21:02:08.000Z","size":552,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"trunk","last_synced_at":"2024-05-29T11:42:20.636Z","etag":null,"topics":["grid","icons","made-to-be-plundered","svelte","svg","svg-icons","web"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/PaulioRandall.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":"2023-12-29T21:39:48.000Z","updated_at":"2024-05-30T22:31:34.045Z","dependencies_parsed_at":"2024-05-30T22:31:28.758Z","dependency_job_id":"d9558ba4-068e-450a-a4b6-b3a9835afce3","html_url":"https://github.com/PaulioRandall/p45","commit_stats":{"total_commits":77,"total_committers":1,"mean_commits":77.0,"dds":0.0,"last_synced_commit":"89eaa1ec634f595da289587617830a95cc392bf0"},"previous_names":["pauliorandall/p45"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp45","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp45/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp45/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp45/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaulioRandall","download_url":"https://codeload.github.com/PaulioRandall/p45/tar.gz/refs/heads/trunk","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246150459,"owners_count":20731419,"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","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":["grid","icons","made-to-be-plundered","svelte","svg","svg-icons","web"],"created_at":"2024-12-09T08:30:06.054Z","updated_at":"2026-05-01T15:35:12.575Z","avatar_url":"https://github.com/PaulioRandall.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Made to be Plundered](https://img.shields.io/badge/Made%20to%20be%20Plundered-royalblue)\n[![Latest version](https://img.shields.io/github/v/release/PaulioRandall/p45)](https://github.com/PaulioRandall/p45/releases)\n[![Release date](https://img.shields.io/github/release-date/PaulioRandall/p45)](https://github.com/PaulioRandall/p45/releases)\n\n# P45\n\nSvelte library for programmatically crafting grid based SVG icons.\n\n**Requires Svelte version 4.**\n\n## Made to be Plundered\n\nFork, pillage, and plunder! Do whatever as long as you adhere to the project's permissive MIT license.\n\n## Classes\n\n### `P45`\n\nThe core class supplied to P45 components. It provides the context for P45 components such as grid size and certain named nodes.\n\nIt also provides functions for parsing command and transformation lists used by components such as `\u003cShape\u003e` and `\u003cTransform\u003e`.\n\n```js\nclass P45 {\n  // Accepts size of the grid used as the unscaled width and height in pixels.\n  // Size must be between 8 and 64.\n  // Size must be divisible by 2.\n  constructor(size=24) {\n    this.size = size\n    this.center // '12' for default size\n    this.centerNode // 'M12' for default size\n    this.topLeftNode\n    this.topCenterNode\n    this.topRightNode\n    this.centerLeftNode\n    this.centerCenterNode\n    this.centerRightNode\n    this.bottomLeftNode\n    this.bottomCenterNode\n    this.bottomRightNode\n  }\n\n  // Parses nodes such as `M12` into coordinates such as `{ x: 12, y: 12 }`.\n  parseNode(node);\n\n  // Converts coordinates such as `x=12` and `y=12` into nodes such as `M12`.\n  nodeOf(x, y);\n\n  // Converts the number `n` into it's base 26 alphabetic representation.\n  numberToAlpha(n);\n\n  // Parses a string or array of strings representing\n  // draw commands for a single shape and returns a\n  // string used in SVG paths like this `\u003cpath d={result} /\u003e`.\n  parseDrawCommands(commands);\n\n  // Parses a string or array of strings representing\n  // transform commands for a single element and returns a\n  // string used for the SVG transform attribute like this\n  // `\u003cpath transform={result} /\u003e` or `\u003cg transform={result} /\u003e`.\n  parseTransformCommands(commands);\n}\n```\n\n```svelte\n\u003cscript\u003e\n\timport { P45, Icon, Shape } from 'p45'\n\n\tconst p45 = new P45()\n\u003c/script\u003e\n\n\u003cIcon {p45} width=\"300\" height=\"300\"\u003e\n\t\u003c!-- Simple triangle --\u003e\n\t\u003cShape\n\t\tdraw=\"\n      move to E20\n      line to U20\n      line to M4\n      close\n  \" /\u003e\n\u003c/Icon\u003e\n```\n\nIllustration of the above drawing but with some minor modifications so it's visible on GitHub and other platforms.\n\n![Approximate illustration of the last code snippet](static/simple-triangle.svg)\n\n### Draw Commands\n\n**`move to \u003cnode\u003e`**\n\n- _move to D3_ =\u003e `M 3 3`\n- _move to M8_ =\u003e `M 12 8`\n\n**`line to \u003cnode\u003e`**\n\n- _line to D3_ =\u003e `L 3 3`\n- _line to M8_ =\u003e `L 12 8`\n\n**`[cubic] curve to \u003cnode\u003e control with \u003cnode\u003e [and \u003cnode\u003e]`**\n\n- _curve to M8 control with D3_ =\u003e `S 3 3 12 8`\n- _curve to M8 control with D3 and F6_ =\u003e `C 3 3 6 6 12 8`\n\n**`(quad|quadratic) curve to \u003cnode\u003e [control with \u003cnode\u003e]`**\n\n- _(quad | quadratic) curve to M8_ =\u003e `T 12 8`\n- _(quad | quadratic) curve to M8 control with D3_ =\u003e `Q 3 3 12 8`\n\n**`arc to \u003cnode\u003e with radius \u003cnumber\u003e and \u003cnumber\u003e [and rotation \u003cnumber\u003e] [and is large] [and is sweeping]`**\n\n- _arc to M8 with radius 6 and 10_ =\u003e `A 6 10 0 0 0 12 8`\n- _arc to M8 with radius 6 and 10 and rotation 45_ =\u003e `A 6 10 45 0 0 12 8`\n- _arc to M8 with radius 6 and 10 and is large_ =\u003e `A 6 10 0 1 0 12 8`\n- _arc to M8 with radius 6 and 10 and is sweeping_ =\u003e `A 6 10 0 0 1 12 8`\n- _arc to M8 with radius 6 and 10 and rotation 45 and is large and is sweeping_ =\u003e `A 6 10 45 1 1 12 8`\n\n**`close`** (connects the ends of the shape together)\n\n- _close_ =\u003e `z`\n\n### Transform Commands\n\n**`move by \u003cnumber\u003e`**\n\n- _move by D3_ =\u003e `translate(3 3)`\n- _move by M8_ =\u003e `translate(12 8)`\n\n**`move \u003cdirection\u003e by \u003cnumber\u003e`**\n\n- _move up by 3_ =\u003e `translate(0 -3)`\n- _move down by 3_ =\u003e `translate(0 3)`\n- _move left by 3_ =\u003e `translate(-3 0)`\n- _move right by 3_ =\u003e `translate(3 0)`\n\n**`rotate by \u003cnumber\u003e [around \u003cnode\u003e]`**\n\n- rotate by 45\\_ =\u003e `rotate(45)`\n- rotate by 45 around M8\\_ =\u003e `rotate(45, 12, 8)`\n\n**`scale [x|y] by \u003cnumber\u003e`**\n\n- _scale by 2_ =\u003e `scale(2 2)`\n- _scale x by 2_ =\u003e `scale(2 0)`\n- _scale y by 2_ =\u003e `scale(0 2)`\n\n**`scale [x|y|width|height|horizontally|vertically] by \u003cnumber\u003e`**\n\n- _scale by 2_ =\u003e `scale(2 2)`\n- _scale x by 2_ =\u003e `scale(2 1)`\n- _scale y by 2_ =\u003e `scale(1 2)`\n\n**`flip [x|y|width|height|horizontally|vertically]`**\n\n- _flip_ =\u003e `scale(-1 -1)`\n- _flip x_ =\u003e `scale(-1 1)`\n- _flip y_ =\u003e `scale(1 -1)`\n\n**`skew [x|y|width|height|horizontally|vertically] by \u003cnumber\u003e`**\n\n- _skew by 20_ =\u003e `skewX(20) skewY(20)`\n- _skew x by 20_ =\u003e `skewX(20)`\n- _skew y by 20_ =\u003e `skewY(20)`\n\n## Components\n\n### `\u003cCircle\u003e`\n\nCreates a circle from a center origin and radius.\n\n```svelte\n\u003cscript\u003e\n  // P45 instance to use as grid and context.\n  export let p45 = getContext('p45')\n\n  // Circle center point.\n  export let origin = p45.centerNode\n\n  // Circle radius.\n  export let radius = p45.center - 1\n\u003c/script\u003e\n\n\u003c!-- Any elements allowable within a `\u003ccircle\u003e`. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cCircle\n  p45={getContext('p45')}\n  origin={p45.centerNode}\n  radius={p45.center - 1}\n\u003e\n  \u003cdiv /\u003e\n\u003c/Circle\u003e\n```\n\n### `\u003cIcon\u003e`\n\nContainer for slotted shapes that form an Icon.\n\nIt's represented by an svg element sized by the passed P45 instance.\nRaw svg child elements maybe slotted in too.\n\n```svelte\n\u003cscript\u003e\n  // An instance of the P45 class.\n  export let p45 = getContext('p45')\n\n  // The icon's title applied using the SVG title tag.\n  export let title = \"\"\n\n  // Description of the icon applied using the SVG description tag.\n  export let description = \"\"\n\n  // P45 instance used to size the icon and parse nodes.\n  setContext(\"p45\", ...)\n\u003c/script\u003e\n\n\u003c!-- SVG elments and components that form the icon. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cIcon\n  p45={getContext('p45')}\n  title=\"\"\n  description=\"\"\n\u003e\n  \u003cdiv /\u003e\n\u003c/Icon\u003e\n```\n\n### `\u003cMask\u003e`\n\nCreates a referencable mask for cutting holes in other shapes.\n\n```svelte\n\u003cscript\u003e\n  // P45 instance to use as grid and context.\n  export let p45 = getContext('p45')\n\n  // Unique ID to reference the mask.\n  export let id\n\u003c/script\u003e\n\n\u003c!-- Elments and components that form the hole in the referencing shape. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cMask\n  p45={getContext('p45')}\n  id\n\u003e\n  \u003cdiv /\u003e\n\u003c/Mask\u003e\n```\n\n### `\u003cRegularPolygon\u003e`\n\nCreates a regular polygon from an origin center point, number of edges,\nand radius to a vertex.\n\n```svelte\n\u003cscript\u003e\n  // P45 instance to use as grid and context.\n  export let p45 = getContext('p45')\n\n  // Origin to use for transforms.\n  export let origin = p45.centerNode\n\n  // Number of sides.\n  export let sides = 6\n\n  // Circle radius.\n  export let radius = p45.center - 1\n\n  // Amount to rotate counter clockwise in degrees, may be negative.\n  export let rotate = 0\n\u003c/script\u003e\n\n\u003c!-- Any elements allowable within a `\u003cpolygon\u003e`. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cRegularPolygon\n  p45={getContext('p45')}\n  origin={p45.centerNode}\n  sides={6}\n  radius={p45.center - 1}\n  rotate={0}\n\u003e\n  \u003cdiv /\u003e\n\u003c/RegularPolygon\u003e\n```\n\n### `\u003cShape\u003e`\n\nCreates a shape from three or more points.\n\n```svelte\n\u003cscript\u003e\n  // P45 instance to use as grid and context.\n  export let p45 = getContext('p45')\n\n  // Either an array off commands or a line separated list of commands.\n  export let commands = /* Simple Wallace \u0026 Gromit rocket drawing */\n\n  // ID of a mask cut out.\n  export let mask = \"\"\n\n  // Either an array off commands or a line separated list of commands.\n  export let transforms = \"\"\n\n  // Origin to use for transforms.\n  export let origin = p45.centerNode\n\u003c/script\u003e\n\n\u003c!-- Any elements allowable within a `\u003cpath\u003e`. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cShape\n  p45={getContext('p45')}\n  commands={/* Simple Wallace \u0026 Gromit rocket drawing */}\n  mask=\"\"\n  transforms=\"\"\n  origin={p45.centerNode}\n\u003e\n  \u003cdiv /\u003e\n\u003c/Shape\u003e\n```\n\n### `\u003cTransform\u003e`\n\nCreates a group for simple transformations.\n\n```svelte\n\u003cscript\u003e\n  // P45 instance to use as grid and context.\n  export let p45 = getContext('p45')\n\n  // Either an array off commands or a line separated list of commands.\n  export let transforms = \"\"\n\n  // Origin to use for transforms.\n  export let origin = p45.centerNode\n\u003c/script\u003e\n\n\u003c!-- Components and elements to transform within a `\u003cg\u003e`. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cTransform\n  p45={getContext('p45')}\n  transforms=\"\"\n  origin={p45.centerNode}\n\u003e\n  \u003cdiv /\u003e\n\u003c/Transform\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpauliorandall%2Fp45","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpauliorandall%2Fp45","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpauliorandall%2Fp45/lists"}