{"id":46440119,"url":"https://github.com/tomickigrzegorz/circular-progress-bar","last_synced_at":"2026-05-15T22:04:45.726Z","repository":{"id":42976411,"uuid":"193725411","full_name":"tomickigrzegorz/circular-progress-bar","owner":"tomickigrzegorz","description":"⭕ A circular progress bar in svg. No dependencies. ~2KB gzip","archived":false,"fork":false,"pushed_at":"2026-01-22T03:16:21.000Z","size":1154,"stargazers_count":52,"open_issues_count":0,"forks_count":15,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-22T16:53:16.381Z","etag":null,"topics":["javascript","progress-bar","progress-circle","svg","vanilla-js"],"latest_commit_sha":null,"homepage":"https://tomickigrzegorz.github.io/circular-progress-bar/","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/tomickigrzegorz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-06-25T14:36:22.000Z","updated_at":"2026-01-22T03:16:26.000Z","dependencies_parsed_at":"2023-10-03T17:44:49.980Z","dependency_job_id":"811ae636-5f5a-45a6-9079-e56ffdc9f453","html_url":"https://github.com/tomickigrzegorz/circular-progress-bar","commit_stats":null,"previous_names":[],"tags_count":30,"template":true,"template_full_name":null,"purl":"pkg:github/tomickigrzegorz/circular-progress-bar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomickigrzegorz%2Fcircular-progress-bar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomickigrzegorz%2Fcircular-progress-bar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomickigrzegorz%2Fcircular-progress-bar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomickigrzegorz%2Fcircular-progress-bar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomickigrzegorz","download_url":"https://codeload.github.com/tomickigrzegorz/circular-progress-bar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomickigrzegorz%2Fcircular-progress-bar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30151954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T21:15:50.531Z","status":"ssl_error","status_checked_at":"2026-03-05T21:15:11.173Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["javascript","progress-bar","progress-circle","svg","vanilla-js"],"created_at":"2026-03-05T21:54:31.476Z","updated_at":"2026-05-15T22:04:45.715Z","avatar_url":"https://github.com/tomickigrzegorz.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  Circular Progress Bar\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  Simple circular progress bar. From now on, one call runs multiple circular-progress-bar.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/package-json/v/tomickigrzegorz/circular-progress-bar\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/size/tomickigrzegorz/circular-progress-bar/dist/circularProgressBar.min.js\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/tomickigrzegorz/circular-progress-bar\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"circular-progress-bar.png\"\u003e\n\u003c/p\u003e\n\n## Demo\n\nSee the demo - [example](https://tomickigrzegorz.github.io/circular-progress-bar/)\n\n## Installation\n\n#### CDN (jsDelivr)\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/tomickigrzegorz/circular-progress-bar@1.5.0/dist/circularProgressBar.min.js\"\u003e\u003c/script\u003e\n```\n\n#### npm\n\n```bash\nnpm install @tomickigrzegorz/circular-progress-bar\n# or\nyarn add @tomickigrzegorz/circular-progress-bar\n```\n\n#### ESM (bundler / Vite / Webpack)\n\n```js\nimport CircularProgressBar from \"@tomickigrzegorz/circular-progress-bar\";\n```\n\n\u003e No CSS import needed — all styles are applied programmatically via SVG attributes.\n\n#### ESM via CDN (no bundler)\n\n```html\n\u003cscript type=\"module\"\u003e\n  import CircularProgressBar from \"https://cdn.jsdelivr.net/npm/@tomickigrzegorz/circular-progress-bar/dist/circularProgressBar.esm.min.js\";\n\u003c/script\u003e\n```\n\n#### UMD (CommonJS / Node)\n\n```js\nconst CircularProgressBar = require(\"@tomickigrzegorz/circular-progress-bar\");\n```\n\n#### Local file\n\n```html\n\u003cscript src=\"./path/to/circularProgressBar.min.js\"\u003e\u003c/script\u003e\n```\n\n\n## Sample configuration\n\n1. Add a div element to the page `\u003cdiv class=\"pie\" data-pie='{ \"percent\": 80 }'\u003e\u003c/div\u003e`\n2. Build the script or download it from the `dist` folder and add `circularProgressBar.min.js` to the page, [umd, esm, iife]\n3. Call the functions `const circle = new CircularProgressBar('pie'); circle.initial();`\n\nMore extensive example:\n\n```html\n\u003cdiv class=\"pie\" data-pie='{ \"round\": true, \"percent\": 80, \"colorSlice\": \"#E91E63\", \"time\": 20 }'\u003e\u003c/div\u003e\n\u003cdiv class=\"pie\" data-pie='{ \"lineargradient\": [\"#ffff00\",\"#ff0000\"], \"percent\": 20, \"colorSlice\": \"#000\", \"colorCircle\": \"#e6e6e6\", \"strokeWidth\": 15, \"number\": false }'\u003e\u003c/div\u003e\n```\n\nArc gradient — colors follow the arc of the circle. `gradient[0]` sits at the progress start, `gradient[100%]` at the end of the visible arc, and the colors flow in the progress direction. Combines freely with `rotation`, `cut`, `inverse`, and `round`.\n\n```html\n\u003c!-- equal spacing --\u003e\n\u003cdiv class=\"pie\" data-pie='{ \"percent\": 75, \"gradient\": [\"#ff0000\",\"#ffff00\",\"#00cc00\"], \"colorCircle\": \"#e6e6e6\", \"round\": true }'\u003e\u003c/div\u003e\n\n\u003c!-- custom stop positions --\u003e\n\u003cdiv class=\"pie\" data-pie='{ \"percent\": 75, \"gradient\": [\"#ff0000\",\"#ffff00\",\"#00cc00\"], \"gradientStops\": [0,20,100], \"colorCircle\": \"#e6e6e6\" }'\u003e\u003c/div\u003e\n\n\u003c!-- hard cuts (no blending) — duplicate each color at the same position --\u003e\n\u003cdiv class=\"pie\" data-pie='{ \"percent\": 75, \"gradient\": [\"#ff0000\",\"#ff0000\",\"#00cc00\",\"#00cc00\"], \"gradientStops\": [0,50,50,100] }'\u003e\u003c/div\u003e\n\n\u003c!-- with cut + rotation + round --\u003e\n\u003cdiv class=\"pie\" data-pie='{ \"percent\": 75, \"gradient\": [\"#e91e63\",\"#9c27b0\",\"#3f51b5\"], \"colorCircle\": \"#e6e6e6\", \"cut\": 30, \"rotation\": 144, \"round\": true }'\u003e\u003c/div\u003e\n\n\u003c!-- counter-clockwise growth with round caps --\u003e\n\u003cdiv class=\"pie\" data-pie='{ \"percent\": 75, \"gradient\": [\"#ff0000\",\"#ff8800\",\"#ffff00\",\"#00cc00\",\"#0000ff\"], \"colorCircle\": \"#e6e6e6\", \"inverse\": true, \"round\": true }'\u003e\u003c/div\u003e\n```\n\nMinimal configuration:\n\n```html\n\u003cdiv class=\"pie\" data-pie='{ \"percent\": 80 }'\u003e\u003c/div\u003e\n```\n\n### Function call\n\n```javascript\n// 'pie' is class name div\nconst circle = new CircularProgressBar(\"pie\");\ncircle.initial();\n```\n\n### IntersectionObserver\nAutomatic animation start when the progress bar appears in the page view.\n\n```js\nwindow.addEventListener('DOMContentLoaded', () =\u003e {\n  // get all progress bar\n  const elements = [].slice.call(document.querySelectorAll('.pie'));\n  // call to function\n  const circle = new CircularProgressBar('pie');\n\n  // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API\n  // if IntersectionObserver is supported by the browser\n  if ('IntersectionObserver' in window) {\n    const config = {\n      root: null,\n      rootMargin: '0px',\n      threshold: 0.75,\n    };\n\n    const ovserver = new IntersectionObserver((entries, observer) =\u003e {\n      entries.map((entry) =\u003e {\n        if (entry.isIntersecting \u0026\u0026 entry.intersectionRatio \u003e= 0.75) {\n          circle.initial(entry.target);\n          observer.unobserve(entry.target);\n        }\n      });\n    }, config);\n\n    elements.map((item) =\u003e {\n      ovserver.observe(item);\n    });\n  } else {\n    // if the browser does not support IntersectionObserver\n    // we run all progress bars at once\n    elements.map((element) =\u003e {\n      circle.initial(element);\n    });\n  }\n});\n```\n\n### Update progress bar dynamically\n\nBelow there are properties that we can change dynamically\n\n```js\nconst circle = new CircularProgressBar(\"pie\");\ncircle.initial();\n\nsetTimeout(() =\u003e {\n  const options = {\n    // item number you want to update\n    // read data-pie-index from the element\n    index: 1,\n    // update props\n    percent: 30,\n    colorSlice: \"salmon\",\n    fontColor: \"salmon\",\n    fontSize: \"1.2rem\",\n    fontWeight: 600\n  };\n  circle.animationTo(options);\n}, 3000); // after 3s update\n```\n\nModification of these elements `fontColor`,` fontSize`, `fontWeight` is also available from the level of css. The svg text and tspan elements have unique classes on the basis of which we can modify them.\n\n```svg\n\u003ctext class=\"pie-text-1\" x=\"50%\" y=\"50%\" fill=\"#000\" font-size=\"1.6rem\" font-weight=\"400\" text-anchor=\"middle\" dy=\"0.35em\"\u003e\n  \u003ctspan class=\"pie-percent-1\"\u003e75\u003c/tspan\u003e\n  \u003ctspan class=\"pie-unit-1\"\u003e%\u003c/tspan\u003e\n\u003c/text\u003e\n```\n\n```css\n.pie-text-1 {\n  fill: red;\n  font-size: 2rem;\n  /* e.t.c */\n}\n```\n\n### Global configuration\n\n```html\n\u003cdiv class=\"global\" data-pie='{ \"percent\": 90 }'\u003e\u003c/div\u003e\n\u003cdiv class=\"global\" data-pie='{ \"percent\": 10 }'\u003e\u003c/div\u003e\n...\n```\n\n```js\nconst globalConfig = {\n  \"strokeBottom\": 5,\n  \"colorSlice\": \"#EC407A\",\n  \"colorCircle\": \"#f1f1f1\",\n  \"round\": true,\n  /* e.t.c */\n}\n\nconst global = new CircularProgressBar('global', globalConfig);\nglobal.initial();\n```\n\n## TypeScript\n\nThe library includes built-in TypeScript declarations — no `@types/` package needed.\n\n```ts\nimport CircularProgressBar, { type CPBOptions } from \"@tomickigrzegorz/circular-progress-bar\";\n\nconst options: CPBOptions = {\n  percent: 75,\n  colorSlice: \"#E91E63\",\n  round: true,\n};\n\nconst circle = new CircularProgressBar(\"pie\", options);\ncircle.initial();\n```\n\n## Watch/Build the app\n\nWatch the app, just call:\n\n```bash\nyarn watch\n# or\nnpm run watch\n```\n\nBuild app:\n\n```bash\nyarn build\n# or\nnpm run build\n```\n\n## Configuration of the plugin\n\n| props          |     type      |   default   | require | description                                                                                                |\n| -------------- | :-----------: | :---------: | :-----: | ---------------------------------------------------------------------------------------------------------- |\n| percent        |    number     |             |    ✔    | Represents the progress bar and animation of the animation progress expressed by a number e.g. 65%         |\n| index          |    number     |     ``      |         | Set your number `data-pie-index`, if you do not set it, it will be dynamically set depending on the order of elements |\n| colorSlice     |    string     | `'#00a1ff'` |         | Progress layer color and background [\"#ffff00\",\"brown\" \u003csup\u003e2\u003c/sup\u003e](#colors-names)                                  |\n| colorCircle    |    string     |     `''`    |         | Bottom circle color Font [\"#ffff00\",\"brown\" \u003csup\u003e2\u003c/sup\u003e](#colors-names)                                             |\n| speed          |    number     |   `1000`    |         | Frame rate animation [fps]. Let's say you want the animation to be 60fps, just add the parameter speed: 60 |\n| stroke         |    number     |    `10`     |         | Stroke width, chart thickness                                                                              |\n| strokeBottom   |    number     |    `10`     |         | If \"strokBottom\" is set, it is used to generate a background circle size                                   |\n| round          |    boolean    |   `false`   |         | Path rounding                                                                                              |\n| inverse        |    boolean    |   `false`   |         | Counterclockwise animation                                                                                 |\n| rotation       |    number     |    `-90`    |         | Chart rotation                                                                                             |\n| number         |    boolean    |   `true`    |         | Add props number and set to false to hide the number with percent                                          |\n| animationOff   |    boolean    |   `false`   |         | Turn off the progress animation                                                                            |\n| animationSmooth|    string     |     `''`    |         | Animation type setting, e.g. `500ms ease-out` - [more on transition](https://developer.mozilla.org/en-US/docs/Web/CSS/transition)                                                                            |\n| size           |    number     |    `200`    |         | Size progress bar width and height in px                                                                   |\n| cut            |    number     |     `0`     |         | Angle of the circle sector                                                                                 |\n| unit           |    string     |     `%`     |         | Different unit instead of percentage (%) inside the circle \u003csup\u003e1\u003c/sup\u003e                                    |\n| fill           |    string     |   `none`    |         | Inner circle color                                                                                         |\n| textPosition   |    string     |  `0.35em`   |         | The position of the SVG TEXT element vertically                                                            |\n| fontSize       |    string     |  `1.6rem`   |         | Font size. The font can be shown in units rem, em, px ...                                                  |\n| fontWeight     |    string     |    `400`    |         | [number, normal, bold, bolder, lighter]                                                                    |\n| fontColor      |    string     |  `'#000'`   |         | Font color [\"#ffff00\",\"brown\" \u003csup\u003e2\u003c/sup\u003e](#colors-names)                                                           |\n| lineargradient |     array     |     ``      |         | Array of colors \"lineargradient\": [\"#ffff00\",\"brown\" \u003csup\u003e2\u003c/sup\u003e](#colors-names)                                    |\n| gradient       |     array     |     ``      |         | Arc gradient — colors follow the arc of the circle. Array of 2–10 hex strings e.g. `[\"#f00\",\"#ff0\",\"#0f0\"]`         |\n| gradientStops  |     array     |     ``      |         | Color stop positions (0–100) for `gradient`. Must match `gradient` length, otherwise equal spacing is used           |\n| strokeDasharray|    string     |     ``      |         | It works only on the lowest circle and only on whole circles - [stroke-dasharray](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/)                                                  |\n\n\u003csup\u003e1\u003c/sup\u003e `unit` - you can style them. `unit` is in the tspan element of the class `pie-unit-x`. The class name is main class + `unit` + chart id. Below are the styles for our example.\n```css\n.pie-unit-9 {\n  fill: #f50057;\n  font-size: 1rem;\n}\n```\n\n\u003csup\u003e2\u003c/sup\u003e [See colors names](https://htmlcolorcodes.com/color-names/)\n\n## Adding a shadow\n```css\n[data-pie-index='2'] {\n  position: relative;\n  border-radius: 50%;\n  box-shadow: inset 0 0 25px 10px rgb(162, 202, 255);\n}\n```\n## Browser support\n\nSupports all modern browsers (Chrome, Firefox, Safari, Edge). IE is not supported.\n\n## License\n\nThis project is available under the [MIT](https://opensource.org/licenses/mit-license.php) license.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomickigrzegorz%2Fcircular-progress-bar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomickigrzegorz%2Fcircular-progress-bar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomickigrzegorz%2Fcircular-progress-bar/lists"}