├── .changeset ├── README.md └── config.json ├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── feature_request.yml │ └── question_request.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── gh-pages.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc.cjs ├── .vscode └── extensions.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples ├── basic │ ├── index.html │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── style.css │ │ └── vite-env.d.ts │ └── tsconfig.json ├── with-angular │ ├── .browserslistrc │ ├── angular.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.ts │ │ │ └── app.module.ts │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ └── styles.css │ ├── tsconfig.app.json │ └── tsconfig.json ├── with-preact │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.tsx │ │ ├── index.tsx │ │ ├── preact.d.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── with-react │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.tsx │ │ ├── index.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── with-solid │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.tsx │ │ ├── index.tsx │ │ └── vite-end.d.ts │ ├── tsconfig.json │ └── vite.config.ts ├── with-svelte │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.svelte │ │ ├── index.ts │ │ └── shim.d.ts │ ├── svelte.config.js │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── with-vue │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.vue │ │ ├── index.ts │ │ └── shim.d.ts │ ├── tsconfig.json │ └── vite.config.js └── with-web-components │ ├── index.html │ ├── package.json │ ├── src │ └── index.ts │ └── tsconfig.json ├── package.json ├── packages ├── angular │ ├── README.md │ ├── angular.json │ ├── package.json │ ├── projects │ │ └── ng-fireworks │ │ │ ├── .browserslistrc │ │ │ ├── ng-package.json │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── lib │ │ │ │ ├── ng-fireworks.directive.ts │ │ │ │ └── ng-fireworks.module.ts │ │ │ └── public-api.ts │ │ │ ├── tsconfig.lib.json │ │ │ └── tsconfig.lib.prod.json │ └── tsconfig.json ├── fireworks-js │ ├── README.md │ ├── package.json │ ├── src │ │ ├── explosion.ts │ │ ├── fireworks.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── mouse.ts │ │ ├── options.ts │ │ ├── raf.ts │ │ ├── resize.ts │ │ ├── sound.ts │ │ ├── trace.ts │ │ └── types.ts │ ├── tsconfig.json │ └── vite.config.ts ├── preact │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.tsx │ │ └── preact.d.ts │ ├── tsconfig.json │ └── vite.config.ts ├── react │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.tsx │ ├── tsconfig.json │ └── vite.config.ts ├── solid │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.tsx │ ├── tsconfig.json │ └── vite.config.ts ├── svelte │ ├── README.md │ ├── package.json │ ├── src │ │ ├── app.d.ts │ │ ├── app.html │ │ ├── lib │ │ │ ├── fireworks.svelte │ │ │ └── index.ts │ │ └── routes │ │ │ └── +page.svelte │ ├── static │ │ └── favicon.png │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── vue │ ├── README.md │ ├── package.json │ ├── src │ │ ├── fireworks.vue │ │ ├── index.ts │ │ └── shim.d.ts │ ├── tsconfig.json │ └── vite.config.ts └── web │ ├── README.md │ ├── package.json │ ├── src │ └── index.ts │ ├── tsconfig.json │ └── vite.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── turbo.json └── website ├── index.html ├── package.json ├── public ├── CNAME ├── images │ ├── fireworks_banner.gif │ ├── fireworks_emoji.gif │ └── fireworks_emoji.png ├── index.css └── sounds │ ├── explosion0.mp3 │ ├── explosion1.mp3 │ └── explosion2.mp3 ├── src ├── config.ts └── index.ts └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "master", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [ 11 | "website", 12 | "basic", 13 | "with-angular", 14 | "with-preact", 15 | "with-react", 16 | "with-solid", 17 | "with-svelte", 18 | "with-vue", 19 | "with-web-components", 20 | "@fireworks-js/*" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Bug Report 2 | description: Create a report to help us improve. 3 | labels: bug 4 | assignees: crashmax-dev 5 | 6 | body: 7 | - type: textarea 8 | id: description 9 | attributes: 10 | label: Description 11 | description: A clear and concise description of what the bug is. 12 | validations: 13 | required: true 14 | 15 | - type: dropdown 16 | id: package 17 | attributes: 18 | label: Which package are you using? 19 | multiple: true 20 | options: 21 | - "fireworks-js" 22 | - "@fireworks-js/react" 23 | - "@fireworks-js/preact" 24 | - "@fireworks-js/solid" 25 | - "@fireworks-js/vue" 26 | - "@fireworks-js/svelte" 27 | - "@fireworks-js/angular" 28 | - "@fireworks-js/web" 29 | validations: 30 | required: true 31 | 32 | - type: input 33 | id: version 34 | attributes: 35 | label: fireworks-js version 36 | placeholder: 2.x.x 37 | validations: 38 | required: true 39 | 40 | - type: input 41 | id: browser 42 | attributes: 43 | label: Browser 44 | placeholder: Version 103.0.5060.114 (Official Build) (64-bit) 45 | validations: 46 | required: true 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 Feature Request 2 | description: Submit a proposal for a new feature. 3 | labels: enhancement 4 | assignees: crashmax-dev 5 | 6 | body: 7 | - type: textarea 8 | id: proposal 9 | attributes: 10 | label: Feature Proposal 11 | description: A clear and concise description of what the feature is. 12 | validations: 13 | required: true 14 | 15 | - type: textarea 16 | id: motivation 17 | attributes: 18 | label: Motivation 19 | description: The motivation for the proposal. 20 | 21 | - type: textarea 22 | id: example 23 | attributes: 24 | label: Example 25 | description: | 26 | An example for how this feature would be used. 27 | Make sure you place example code inside a [code (```) block](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks) to avoid linking unrelated issues. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question_request.yml: -------------------------------------------------------------------------------- 1 | name: ❔ Question Request 2 | description: If you have questions. 3 | labels: question 4 | assignees: crashmax-dev 5 | 6 | body: 7 | - type: textarea 8 | id: text 9 | attributes: 10 | label: Issue 11 | description: | 12 | Give as much detail as you can to help us understand. 13 | Make sure you place example code inside a [code (```) block](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks) to avoid linking unrelated issues. 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Checklist 2 | 3 | - [ ] run `pnpm format` 4 | - [ ] documentation is changed or added 5 | - [ ] commit message and code follows the [Developer's Certification of Origin](https://github.com/crashmax-dev/fireworks-js/blob/master/CONTRIBUTING.md#developers-certificate-of-origin-11) 6 | and the [Code of conduct](https://github.com/crashmax-dev/fireworks-js/blob/master/CODE_OF_CONDUCT.md) 7 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: github-pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | cache-and-install: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v3 14 | 15 | - name: Cache PNPM 16 | uses: actions/cache@v3 17 | with: 18 | path: ~/.pnpm-store 19 | key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }} 20 | restore-keys: | 21 | ${{ runner.os }}-node- 22 | 23 | - name: Setup Node 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: 16 27 | 28 | - name: Installing packages 29 | uses: pnpm/action-setup@v2.2.2 30 | with: 31 | version: 7.x.x 32 | run_install: | 33 | - args: [--frozen-lockfile] 34 | 35 | - name: Build website 36 | run: pnpm build:website 37 | 38 | - name: Deploy to GitHub Pages 39 | uses: JamesIves/github-pages-deploy-action@4.1.5 40 | with: 41 | branch: gh-pages 42 | folder: ./website/dist 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/dist 3 | **/.svelte-kit 4 | **/.angular 5 | **/.turbo 6 | **/package 7 | *.tgz 8 | *.log 9 | .DS_Store 10 | Thumbs.db 11 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers=true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | build 4 | logs 5 | coverage 6 | .next 7 | .turbo 8 | .github 9 | .angular 10 | .svelte-kit 11 | .vscode 12 | *.log* 13 | *.log 14 | *.lock 15 | *.yaml 16 | *.yml 17 | *.sh 18 | *.svg 19 | *rc.* 20 | *.htm 21 | *.html 22 | *.json 23 | *.md 24 | .*ignore 25 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require('@crashmax/prettier-config') 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "vue.volar", 4 | "angular.ng-template", 5 | "svelte.svelte-vscode", 6 | "esbenp.prettier-vscode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual 10 | identity and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or advances of 31 | any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email address, 35 | without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at help@crashmax.ru. 63 | All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series of 85 | actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or permanent 92 | ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within the 112 | community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.1, available at 118 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 119 | 120 | Community Impact Guidelines were inspired by 121 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 122 | 123 | For answers to common questions about this code of conduct, see the FAQ at 124 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 125 | [https://www.contributor-covenant.org/translations][translations]. 126 | 127 | [homepage]: https://www.contributor-covenant.org 128 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 129 | [Mozilla CoC]: https://github.com/mozilla/diversity 130 | [FAQ]: https://www.contributor-covenant.org/faq 131 | [translations]: https://www.contributor-covenant.org/translations 132 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Rules 2 | 3 | There are a few basic ground-rules for contributors: 4 | 5 | 1. **No `--force` pushes** on `master` or modifying the Git history in any way 6 | after a PR has been merged. 7 | 2. **Non-master branches** ought to be used for ongoing work. 8 | 3. Internal pull-requests to solicit feedback are *encouraged* for any other 9 | non-trivial contribution but left to the discretion of the contributor. 10 | 4. Contributors should attempt to adhere to the prevailing code-style. 11 | 5. Do not bump version numbers in pull requests. 12 | 13 | ### fireworks-js v1 14 | 15 | Code for fireworks-js **v1** is in [branch 16 | v1](https://github.com/crashmax-dev/fireworks-js/tree/v1), so all fireworks-js v1 related 17 | changes should be based on **`branch v1`**. 18 | 19 | ### fireworks-js v2 20 | 21 | Code for fireworks-js **v2** is in [branch 22 | master](https://github.com/crashmax-dev/fireworks-js/tree/master), so all fireworks-js v2 related 23 | changes should be based on **`branch master`**. 24 | 25 | ## Changes to this arrangement 26 | 27 | This is an experiment and feedback is welcome! This document may also be subject 28 | to pull-requests or changes by contributors where you believe you have something 29 | valuable to add or change. 30 | 31 | ----------------------------------------- 32 | 33 | ## Developer's Certificate of Origin 1.1 34 | 35 | By making a contribution to this project, I certify that: 36 | 37 | * (a) The contribution was created in whole or in part by me and I have the 38 | right to submit it under the open source license indicated in the file; or 39 | 40 | * (b) The contribution is based upon previous work that, to the best of my 41 | knowledge, is covered under an appropriate open source license and I have the 42 | right under that license to submit that work with modifications, whether 43 | created in whole or in part by me, under the same open source license (unless 44 | I am permitted to submit under a different license), as indicated in the file; 45 | or 46 | 47 | * (c) The contribution was provided directly to me by some other person who 48 | certified (a), (b) or (c) and I have not modified it. 49 | 50 | * (d) I understand and agree that this project and the contribution are public 51 | and that a record of the contribution (including all personal information I 52 | submit with it, including my sign-off) is maintained indefinitely and may be 53 | redistributed consistent with this project or the open source license(s) 54 | involved. 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2023 Vitalij Ryndin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://fireworks.js.org/images/fireworks_banner.gif)](https://fireworks.js.org) 2 | 3 |

4 | A simple fireworks library! | fireworks.js.org 5 |

6 | 7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | GitHub Workflow Status 16 | 17 | 18 | GitHub 19 | 20 | 21 | npm 22 | 23 | 24 | npm 25 | 26 | 27 | npm bundle size 28 | 29 |

30 | 31 | --- 32 | 33 | ## Table of Contents 34 | 35 | > **Warning**\ 36 | > This readme refers to upcoming v2 version, [read here](https://github.com/crashmax-dev/fireworks-js/tree/v1) for v1 documentation. 37 | 38 | - [Features](#features) 39 | - [Browsers support](#browsers-support) 40 | - [Demo](#demo) 41 | - [Installation](#installation) 42 | - [CDN](#cdn) 43 | - [Usage](#usage) 44 | - [fireworks-js](#fireworks-js) 45 | - [@fireworks-js/react](#fireworks-jsreact) 46 | - [@fireworks-js/preact](#fireworks-jspreact) 47 | - [@fireworks-js/solid](#fireworks-jssolid) 48 | - [@fireworks-js/vue](#fireworks-jsvue) 49 | - [@fireworks-js/svelte](#fireworks-jssvelte) 50 | - [@fireworks-js/angular](#fireworks-jsangular) 51 | - [@fireworks-js/web](#fireworks-jsweb) 52 | - [Documentation](#documentation) 53 | - [Options](#options) 54 | - [API](#api) 55 | - [Community](#community) 56 | 57 | ## Features 58 | 59 | - 🔥 Zero [dependencies](https://www.npmjs.com/package/fireworks-js?activeTab=dependencies) 60 | - ⚙️ Flexible [configuration](#options) 61 | - 📦 Lightweight ([~3.0kB gzipped](https://bundlephobia.com/package/fireworks-js)) 62 | - 📜 Supports [TypeScript](https://www.typescriptlang.org) type definition 63 | 64 | ## Browsers support 65 | 66 | | [IE / Edge](http://godban.github.io/browsers-support-badges/)
Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | [iOS Safari](http://godban.github.io/browsers-support-badges/)
iOS Safari | [Opera](http://godban.github.io/browsers-support-badges/)
Opera | [Yandex](http://godban.github.io/browsers-support-badges/)
Yandex | 67 | | --------- | --------- | --------- | --------- | --------- | --------- | --------- | 68 | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ 69 | 70 | ## Demo 71 | 72 | You can play with `fireworks-js` at [fireworks.js.org](https://fireworks.js.org) or [codesandbox.io](https://codesandbox.io/s/fireworks-js-react-bjeoqy?file=/src/App.tsx) 73 | 74 | ## Installation 75 | 76 | ```sh 77 | npm install fireworks-js 78 | ``` 79 | 80 | ```sh 81 | yarn add fireworks-js 82 | ``` 83 | 84 | ```sh 85 | pnpm add fireworks-js 86 | ``` 87 | 88 | | Package | Status | Description | 89 | | ------- | ------ | ----------- | 90 | | [fireworks-js](#fireworks-js) | [![](https://img.shields.io/npm/v/fireworks-js)](https://npm.im/fireworks-js) | Vanilla JS | 91 | | [@fireworks-js/react](#fireworks-jsreact) | [![](https://img.shields.io/npm/v/@fireworks-js/react.svg)](https://npm.im/@fireworks-js/react) | React component | 92 | | [@fireworks-js/preact](#fireworks-jspreact) | [![](https://img.shields.io/npm/v/@fireworks-js/preact.svg)](https://npm.im/@fireworks-js/preact) | Preact component | 93 | | [@fireworks-js/solid](#fireworks-jssolid) | [![](https://img.shields.io/npm/v/@fireworks-js/solid.svg)](https://npm.im/@fireworks-js/solid) | Solid component | 94 | | [@fireworks-js/vue](#fireworks-jsvue) | [![](https://img.shields.io/npm/v/@fireworks-js/vue.svg)](https://npm.im/@fireworks-js/vue) | Vue 3 component | 95 | | [@fireworks-js/svelte](#fireworks-jssvelte) | [![](https://img.shields.io/npm/v/@fireworks-js/svelte.svg)](https://npm.im/@fireworks-js/svelte) | Svelte component | 96 | | [@fireworks-js/angular](#fireworks-jsangular) | [![](https://img.shields.io/npm/v/@fireworks-js/angular.svg)](https://npm.im/@fireworks-js/angular) | Angular component | 97 | | [@fireworks-js/web](#fireworks-jsweb) | [![](https://img.shields.io/npm/v/@fireworks-js/web.svg)](https://npm.im/@fireworks-js/web) | Web components | 98 | 99 | # CDN 100 | 101 | ```html 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 114 | ``` 115 | 116 | ## Usage 117 | 118 | #### [`fireworks-js`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/basic) 119 | 120 | ```js 121 | import { Fireworks } from 'fireworks-js' 122 | 123 | const container = document.querySelector('.container') 124 | const fireworks = new Fireworks(container, { /* options */ }) 125 | fireworks.start() 126 | ``` 127 | 128 | [![Edit @fireworks-js/react](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/blissful-sanderson-dkvnx4) 129 | 130 | #### [`@fireworks-js/react`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-react) 131 | 132 | ```sh 133 | npm install @fireworks-js/react 134 | ``` 135 | 136 | [![Edit @fireworks-js/react](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/fireworks-js-react-bjeoqy?fontsize=14&hidenavigation=1&theme=dark) 137 | 138 | #### [`@fireworks-js/preact`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-preact) 139 | 140 | ```sh 141 | npm install @fireworks-js/preact 142 | ``` 143 | 144 | #### [`@fireworks-js/solid`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-solid) 145 | 146 | ```sh 147 | npm install @fireworks-js/solid 148 | ``` 149 | 150 | #### [`@fireworks-js/vue`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-vue) 151 | 152 | ```sh 153 | npm install @fireworks-js/vue 154 | ``` 155 | 156 | #### [`@fireworks-js/svelte`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-svelte) 157 | 158 | ```sh 159 | npm install @fireworks-js/svelte 160 | ``` 161 | 162 | #### [`@fireworks-js/angular`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-angular) 163 | 164 | ```sh 165 | npm install @fireworks-js/angular 166 | ``` 167 | 168 | #### [`@fireworks-js/web`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-web-components) 169 | 170 | ```sh 171 | npm install @fireworks-js/web 172 | ``` 173 | 174 | ## Documentation 175 | 176 | ### Options 177 | 178 | > **Note**\ 179 | > The options is optional, as are each of its properties. 180 | 181 | | Property | Type | Default | 182 | | ------------------ | ------------------- | ----------------------------------------------------------------------------- | 183 | | `hue` | object | [hue](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L49-L52) | 184 | | `rocketsPoint` | object | [rocketsPoint](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L54-L57) | 185 | | `mouse` | object | [mouse](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L70-L74) | 186 | | `boundaries` | object | [boundaries](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L104-L110) | 187 | | `sound` | object | [sound](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L91-L102) | 188 | | `delay` | object | [delay](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L76-L79) | 189 | | `brightness` | object | [brightness](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L81-L84) | 190 | | `decay` | object | [decay](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L86-L89) | 191 | | `lineWidth` | object | [lineWidth](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L59-L68) | 192 | | `lineStyle` | string | round | 193 | | `explosion` | number | 5 | 194 | | `opacity` | number | 0.5 | 195 | | `acceleration` | number | 1.05 | 196 | | `friction` | number | 0.95 | 197 | | `gravity` | number | 1.5 | 198 | | `particles` | number | 50 | 199 | | `traceLength` | number | 3 | 200 | | `flickering` | number | 50 | 201 | | `intensity` | number | 30 | 202 | | `traceSpeed` | number | 10 | 203 | | `intensity` | number | 30 | 204 | | `autoresize` | boolean | true | 205 | 206 | The `hue`, `delay`, `decay`, `brightness`, `lineWidth.explosion`, `lineWidth.trace`, `sound.volume` and `rocketsPoint` options accept an object: 207 | 208 | | Property | Type | 209 | | -------- | ------- | 210 | | `min` | number | 211 | | `max` | number | 212 | 213 | > **Note**\ 214 | > The `min` and `max` properties are used to randomly select values from the range. 215 | 216 | The `mouse` options accept an object: 217 | 218 | | Property | Type | Default | 219 | | -------- | ------- | ------- | 220 | | `click` | boolean | false | 221 | | `move` | boolean | false | 222 | | `max` | number | 1 | 223 | 224 | > **Note**\ 225 | > The `max` property has no effect if `click` is false. 226 | 227 | The `sound` options accept an object: 228 | 229 | | Property | Type | Default | 230 | | ---------- | --------- | ------------------- | 231 | | `enabled` | boolean | false | 232 | | `files` | string[] | [files](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L93-L97) | 233 | | `volume` | object | [volume](https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L98-L101) | 234 | 235 | ```js 236 | const fireworks = new Fireworks(container, { 237 | autoresize: true, 238 | opacity: 0.5, 239 | acceleration: 1.05, 240 | friction: 0.97, 241 | gravity: 1.5, 242 | particles: 50, 243 | traceLength: 3, 244 | traceSpeed: 10, 245 | explosion: 5, 246 | intensity: 30, 247 | flickering: 50, 248 | lineStyle: 'round', 249 | hue: { 250 | min: 0, 251 | max: 360 252 | }, 253 | delay: { 254 | min: 30, 255 | max: 60 256 | }, 257 | rocketsPoint: { 258 | min: 50, 259 | max: 50 260 | }, 261 | lineWidth: { 262 | explosion: { 263 | min: 1, 264 | max: 3 265 | }, 266 | trace: { 267 | min: 1, 268 | max: 2 269 | } 270 | }, 271 | brightness: { 272 | min: 50, 273 | max: 80 274 | }, 275 | decay: { 276 | min: 0.015, 277 | max: 0.03 278 | }, 279 | mouse: { 280 | click: false, 281 | move: false, 282 | max: 1 283 | } 284 | }) 285 | ``` 286 | 287 | ### API 288 | 289 | #### `.start()` 290 | Start fireworks. 291 | 292 | #### `.launch(count)` 293 | Launching a specified number of fireworks.\ 294 | Type: `number`\ 295 | Default `1` 296 | 297 | #### `.stop(dispose)` 298 | Stop fireworks.\ 299 | Type: `boolean`\ 300 | Default: `false` 301 | 302 | #### `.waitStop(dispose)` 303 | Asynchronous stopping of the fireworks.\ 304 | Type: `boolean`\ 305 | Default: `false` 306 | 307 | #### `.pause()` 308 | Start/stop fireworks. 309 | 310 | #### `.clear()` 311 | Cleaning the canvas from fireworks. 312 | 313 | #### `.currentOptions` 314 | Getting current fireworks options. 315 | 316 | #### `.updateOptions(options)` 317 | Force update fireworks options.\ 318 | Type: [`options`](https://github.com/crashmax-dev/fireworks-js/blob/6819ec8456ecb97140a8e1f41959ca2da5c17ddf/packages/fireworks-js/src/types.ts#L3-L25) 319 | 320 | #### `.updateSize(sizes)` 321 | Force update canvas size.\ 322 | Type: [`sizes`](https://github.com/crashmax-dev/fireworks-js/blob/6819ec8456ecb97140a8e1f41959ca2da5c17ddf/packages/fireworks-js/src/types.ts#L58-L61) 323 | 324 | #### `.updateBoundaries(boundaries)` 325 | Force update canvas boundaries.\ 326 | Type: [`boundaries`](https://github.com/crashmax-dev/fireworks-js/blob/6819ec8456ecb97140a8e1f41959ca2da5c17ddf/packages/fireworks-js/src/types.ts#L35-L40) 327 | 328 | ## Community 329 | 330 | ### Star History 331 | 332 | [![Star History Chart](https://api.star-history.com/svg?repos=crashmax-dev/fireworks-js&type=Date)](https://star-history.com/#crashmax-dev/fireworks-js&Date) 333 | 334 | ### Author 335 | - [crashmax](https://github.com/crashmax-dev) 336 | 337 | ### License 338 | - [MIT](https://github.com/crashmax-dev/fireworks-js/blob/master/LICENSE) 339 | -------------------------------------------------------------------------------- /examples/basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fireworks-js 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@zero-dependency/dom": "^0.10.0", 12 | "fireworks-js": "workspace:*" 13 | }, 14 | "devDependencies": { 15 | "typescript": "^4.8.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/basic/src/index.ts: -------------------------------------------------------------------------------- 1 | import { el } from '@zero-dependency/dom' 2 | import { Fireworks } from 'fireworks-js' 3 | import './style.css' 4 | 5 | const app = document.querySelector('#app')! 6 | const fireworks = new Fireworks(app, { 7 | autoresize: true, 8 | boundaries: { 9 | width: app.clientWidth, 10 | height: app.clientHeight 11 | } 12 | }) 13 | 14 | // const resizeObserver = new ResizeObserver((entries) => { 15 | // console.log(entries) 16 | // }) 17 | 18 | // resizeObserver.observe(app) 19 | 20 | fireworks.start() 21 | 22 | const start = el( 23 | 'button', 24 | { 25 | onclick: () => { 26 | fireworks.start() 27 | } 28 | }, 29 | 'Start' 30 | ) 31 | 32 | const stop = el( 33 | 'button', 34 | { 35 | onclick: () => { 36 | fireworks.waitStop() 37 | } 38 | }, 39 | 'Stop' 40 | ) 41 | 42 | const launch = el( 43 | 'button', 44 | { 45 | onclick: () => { 46 | fireworks.launch(Number(count.value)) 47 | } 48 | }, 49 | 'Launch' 50 | ) 51 | 52 | const count = el('input', { 53 | value: '1', 54 | min: '1', 55 | max: '15', 56 | type: 'number', 57 | placeholder: 'count', 58 | style: { 59 | width: '2rem' 60 | } 61 | }) 62 | 63 | const buttons = el( 64 | 'div', 65 | { 66 | style: { 67 | position: 'absolute', 68 | display: 'flex', 69 | gap: '4px' 70 | } 71 | }, 72 | start, 73 | stop, 74 | launch, 75 | count 76 | ) 77 | 78 | document.body.appendChild(buttons) 79 | -------------------------------------------------------------------------------- /examples/basic/src/style.css: -------------------------------------------------------------------------------- 1 | #app { 2 | top: 0; 3 | left: 0; 4 | width: 100%; 5 | height: 100%; 6 | position: fixed; 7 | background: #000; 8 | } 9 | -------------------------------------------------------------------------------- /examples/basic/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": [ 7 | "ESNext", 8 | "DOM" 9 | ], 10 | "moduleResolution": "Node", 11 | "strict": true, 12 | "sourceMap": true, 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "esModuleInterop": true, 16 | "noEmit": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noImplicitReturns": true, 20 | "skipLibCheck": true 21 | }, 22 | "include": [ 23 | "src" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /examples/with-angular/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | -------------------------------------------------------------------------------- /examples/with-angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "with-angular": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/with-angular", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "tsconfig.app.json", 21 | "assets": [ 22 | "src/favicon.ico", 23 | "src/assets" 24 | ], 25 | "styles": [ 26 | "src/styles.css" 27 | ], 28 | "scripts": [] 29 | }, 30 | "configurations": { 31 | "production": { 32 | "budgets": [ 33 | { 34 | "type": "initial", 35 | "maximumWarning": "500kb", 36 | "maximumError": "1mb" 37 | }, 38 | { 39 | "type": "anyComponentStyle", 40 | "maximumWarning": "2kb", 41 | "maximumError": "4kb" 42 | } 43 | ], 44 | "fileReplacements": [ 45 | { 46 | "replace": "src/environments/environment.ts", 47 | "with": "src/environments/environment.prod.ts" 48 | } 49 | ], 50 | "outputHashing": "all" 51 | }, 52 | "development": { 53 | "buildOptimizer": false, 54 | "optimization": false, 55 | "vendorChunk": true, 56 | "extractLicenses": false, 57 | "sourceMap": true, 58 | "namedChunks": true 59 | } 60 | }, 61 | "defaultConfiguration": "production" 62 | }, 63 | "serve": { 64 | "builder": "@angular-devkit/build-angular:dev-server", 65 | "configurations": { 66 | "production": { 67 | "browserTarget": "with-angular:build:production" 68 | }, 69 | "development": { 70 | "browserTarget": "with-angular:build:development" 71 | } 72 | }, 73 | "defaultConfiguration": "development" 74 | }, 75 | "extract-i18n": { 76 | "builder": "@angular-devkit/build-angular:extract-i18n", 77 | "options": { 78 | "browserTarget": "with-angular:build" 79 | } 80 | } 81 | } 82 | } 83 | }, 84 | "cli": { 85 | "analytics": false 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /examples/with-angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-angular", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "ng": "ng", 7 | "dev": "ng serve", 8 | "build": "ng build", 9 | "watch": "ng build --watch --configuration development" 10 | }, 11 | "dependencies": { 12 | "@angular/animations": "^14.0.0", 13 | "@angular/common": "^14.0.0", 14 | "@angular/compiler": "^14.0.0", 15 | "@angular/core": "^14.0.0", 16 | "@angular/forms": "^14.0.0", 17 | "@angular/platform-browser": "^14.0.0", 18 | "@angular/platform-browser-dynamic": "^14.0.0", 19 | "@angular/router": "^14.0.0", 20 | "@fireworks-js/angular": "workspace:*", 21 | "rxjs": "~7.5.0", 22 | "tslib": "^2.2.1", 23 | "zone.js": "~0.11.4" 24 | }, 25 | "devDependencies": { 26 | "@angular-devkit/build-angular": "^14.0.5", 27 | "@angular/cli": "~14.2.4", 28 | "@angular/compiler-cli": "^14.0.0", 29 | "@types/jasmine": "~4.3.0", 30 | "jasmine-core": "~4.4.0", 31 | "typescript": "~4.8.4" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/with-angular/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .fireworks { 2 | top: 0; 3 | left: 0; 4 | width: 100%; 5 | height: 100%; 6 | position: fixed; 7 | background: #000; 8 | } 9 | -------------------------------------------------------------------------------- /examples/with-angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 6 | -------------------------------------------------------------------------------- /examples/with-angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild } from '@angular/core' 2 | import type { 3 | FireworksDirective, 4 | FireworksOptions 5 | } from '@fireworks-js/angular' 6 | 7 | @Component({ 8 | selector: 'app-root', 9 | templateUrl: './app.component.html', 10 | styleUrls: ['./app.component.css'] 11 | }) 12 | export class AppComponent { 13 | enabled = true 14 | options: FireworksOptions = { 15 | opacity: 0.5 16 | } 17 | 18 | @ViewChild('fireworks') fireworks?: FireworksDirective 19 | 20 | toggleFireworks(): void { 21 | this.enabled = !this.enabled 22 | } 23 | 24 | waitStop(): void { 25 | this.fireworks?.waitStop() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/with-angular/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core' 2 | import { BrowserModule } from '@angular/platform-browser' 3 | import { NgFireworksModule } from '@fireworks-js/angular' 4 | import { AppComponent } from './app.component' 5 | 6 | @NgModule({ 7 | declarations: [AppComponent], 8 | imports: [BrowserModule, NgFireworksModule], 9 | providers: [], 10 | bootstrap: [AppComponent] 11 | }) 12 | export class AppModule {} 13 | -------------------------------------------------------------------------------- /examples/with-angular/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | } 4 | -------------------------------------------------------------------------------- /examples/with-angular/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | } 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /examples/with-angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/examples/with-angular/src/favicon.ico -------------------------------------------------------------------------------- /examples/with-angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | @fireworks-js/angular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/with-angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core' 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' 3 | import { AppModule } from './app/app.module' 4 | import { environment } from './environments/environment' 5 | 6 | if (environment.production) { 7 | enableProdMode() 8 | } 9 | 10 | platformBrowserDynamic() 11 | .bootstrapModule(AppModule) 12 | .catch((err) => console.error(err)) 13 | -------------------------------------------------------------------------------- /examples/with-angular/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including 12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** 22 | * By default, zone.js will patch all possible macroTask and DomEvents 23 | * user can disable parts of macroTask/DomEvents patch by setting following flags 24 | * because those flags need to be set before `zone.js` being loaded, and webpack 25 | * will put import in the top of bundle, so user need to create a separate file 26 | * in this directory (for example: zone-flags.ts), and put the following flags 27 | * into that file, and then add the following code before importing zone.js. 28 | * import './zone-flags'; 29 | * 30 | * The flags allowed in zone-flags.ts are listed here. 31 | * 32 | * The following flags will work for all browsers. 33 | * 34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 37 | * 38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 40 | * 41 | * (window as any).__Zone_enable_cross_context_check = true; 42 | * 43 | */ 44 | 45 | /*************************************************************************************************** 46 | * Zone JS is required by default for Angular itself. 47 | */ 48 | import 'zone.js' 49 | 50 | // Included with Angular CLI. 51 | 52 | /*************************************************************************************************** 53 | * APPLICATION IMPORTS 54 | */ 55 | -------------------------------------------------------------------------------- /examples/with-angular/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /examples/with-angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/with-angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "es2020", 20 | "module": "es2020", 21 | "lib": [ 22 | "es2020", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/with-preact/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/preact 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/with-preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-preact", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@fireworks-js/preact": "workspace:*", 12 | "preact": "10.11.0" 13 | }, 14 | "devDependencies": { 15 | "@preact/preset-vite": "2.4.0", 16 | "typescript": "4.8.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/with-preact/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Fireworks } from '@fireworks-js/preact' 2 | import { useRef } from 'preact/hooks' 3 | import type { FireworksHandlers } from '@fireworks-js/preact' 4 | 5 | export function App() { 6 | const ref = useRef(null) 7 | 8 | const toggleFireworks = () => { 9 | if (!ref.current) return 10 | if (ref.current.isRunning) { 11 | ref.current.stop() 12 | } else { 13 | ref.current.start() 14 | } 15 | } 16 | 17 | return ( 18 | <> 19 |
22 | 23 | 24 |
25 | 38 | 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /examples/with-preact/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { render } from 'preact' 2 | import React from 'preact/compat' 3 | import { App } from './App' 4 | 5 | const app = document.getElementById('app')! 6 | render( 7 | 8 | 9 | , 10 | app 11 | ) 12 | -------------------------------------------------------------------------------- /examples/with-preact/src/preact.d.ts: -------------------------------------------------------------------------------- 1 | import JSX = preact.JSX 2 | -------------------------------------------------------------------------------- /examples/with-preact/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/with-preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": [ 6 | "DOM", 7 | "DOM.Iterable", 8 | "ESNext" 9 | ], 10 | "allowJs": false, 11 | "skipLibCheck": true, 12 | "esModuleInterop": false, 13 | "allowSyntheticDefaultImports": true, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "module": "ESNext", 17 | "moduleResolution": "Node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "preserve", 22 | "jsxFactory": "h", 23 | "jsxFragmentFactory": "Fragment" 24 | }, 25 | "include": [ 26 | "src" 27 | ], 28 | "references": [ 29 | { 30 | "path": "./tsconfig.node.json" 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /examples/with-preact/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": [ 8 | "vite.config.ts" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/with-preact/vite.config.ts: -------------------------------------------------------------------------------- 1 | import preact from '@preact/preset-vite' 2 | import { defineConfig } from 'vite' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [preact()] 7 | }) 8 | -------------------------------------------------------------------------------- /examples/with-react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/react 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/with-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@fireworks-js/react": "workspace:*", 12 | "react": "18.2.0", 13 | "react-dom": "18.2.0" 14 | }, 15 | "devDependencies": { 16 | "@types/react": "18.0.21", 17 | "@types/react-dom": "18.0.6", 18 | "@vitejs/plugin-react": "2.1.0", 19 | "typescript": "4.8.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/with-react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useRef } from 'react' 2 | import { Fireworks } from '@fireworks-js/react' 3 | import type { FireworksHandlers } from '@fireworks-js/react' 4 | 5 | export function App() { 6 | const ref = useRef(null) 7 | 8 | const toggle = () => { 9 | if (!ref.current) return 10 | if (ref.current.isRunning) { 11 | ref.current.stop() 12 | } else { 13 | ref.current.start() 14 | } 15 | } 16 | 17 | return ( 18 | <> 19 |
22 | 23 | 24 |
25 | 37 | 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /examples/with-react/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import { App } from './App' 4 | 5 | const app = document.querySelector('#app')! 6 | createRoot(app).render( 7 | 8 | 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /examples/with-react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/with-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": [ 6 | "DOM", 7 | "DOM.Iterable", 8 | "ESNext" 9 | ], 10 | "allowJs": false, 11 | "skipLibCheck": true, 12 | "esModuleInterop": false, 13 | "allowSyntheticDefaultImports": true, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "module": "ESNext", 17 | "moduleResolution": "Node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ], 26 | "references": [ 27 | { 28 | "path": "./tsconfig.node.json" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /examples/with-react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": [ 8 | "vite.config.ts" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/with-react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react' 2 | import { defineConfig } from 'vite' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()] 7 | }) 8 | -------------------------------------------------------------------------------- /examples/with-solid/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/solid 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/with-solid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-solid", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@fireworks-js/solid": "workspace:*", 12 | "solid-js": "1.5.7" 13 | }, 14 | "devDependencies": { 15 | "typescript": "4.8.4", 16 | "vite-plugin-solid": "2.3.9" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/with-solid/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Fireworks, FireworksHandlers } from '@fireworks-js/solid' 2 | import { createSignal, Show } from 'solid-js' 3 | 4 | export function App() { 5 | const [enabled, setEnabled] = createSignal(true) 6 | let fireworks: FireworksHandlers 7 | 8 | // https://github.com/solidjs/solid/issues/116#issuecomment-583247897 9 | setTimeout(() => console.log(fireworks)) 10 | 11 | const toggleFireworks = () => { 12 | if (fireworks.isRunning) { 13 | fireworks.waitStop() 14 | } else { 15 | fireworks.start() 16 | } 17 | } 18 | 19 | return ( 20 | <> 21 |
29 | 32 | 33 |
34 | 35 | (fireworks = ref)} 37 | options={{ opacity: 0.5 }} 38 | style={{ 39 | top: 0, 40 | left: 0, 41 | width: '100%', 42 | height: '100%', 43 | position: 'fixed', 44 | background: '#000' 45 | }} 46 | /> 47 | 48 | 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /examples/with-solid/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { render } from 'solid-js/web' 2 | import { App } from './App' 3 | 4 | const app = document.querySelector('#app')! 5 | render(() => , app) 6 | -------------------------------------------------------------------------------- /examples/with-solid/src/vite-end.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/with-solid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "jsxImportSource": "solid-js", 11 | "noEmit": true, 12 | "isolatedModules": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/with-solid/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import solidPlugin from 'vite-plugin-solid' 3 | 4 | export default defineConfig({ 5 | plugins: [solidPlugin()], 6 | build: { 7 | target: 'esnext', 8 | polyfillDynamicImport: false 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /examples/with-svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/svelte 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/with-svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-svelte", 3 | "type": "module", 4 | "private": true, 5 | "version": "0.0.0", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "check": "svelte-check --tsconfig ./tsconfig.json" 11 | }, 12 | "dependencies": { 13 | "@fireworks-js/svelte": "workspace:*", 14 | "svelte": "3.50.1" 15 | }, 16 | "devDependencies": { 17 | "@sveltejs/vite-plugin-svelte": "1.0.8", 18 | "@tsconfig/svelte": "3.0.0", 19 | "svelte-check": "2.9.1", 20 | "svelte-preprocess": "4.10.7", 21 | "typescript": "4.8.4" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/with-svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 | 26 | 27 |
28 |
29 | 32 |
33 | {#if mounted} 34 | 39 | {/if} 40 |
41 | 42 | 59 | -------------------------------------------------------------------------------- /examples/with-svelte/src/index.ts: -------------------------------------------------------------------------------- 1 | import App from './App.svelte' 2 | 3 | const app = new App({ 4 | target: document.getElementById('app') 5 | }) 6 | 7 | export default app 8 | -------------------------------------------------------------------------------- /examples/with-svelte/src/shim.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /examples/with-svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from 'svelte-preprocess' 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | } 8 | -------------------------------------------------------------------------------- /examples/with-svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "resolveJsonModule": true, 8 | "baseUrl": ".", 9 | "isolatedModules": true 10 | }, 11 | "include": [ 12 | "src/**/*.d.ts", 13 | "src/**/*.ts", 14 | "src/**/*.js", 15 | "src/**/*.svelte" 16 | ], 17 | "references": [ 18 | { 19 | "path": "./tsconfig.node.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /examples/with-svelte/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": [ 8 | "vite.config.ts" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/with-svelte/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { svelte } from '@sveltejs/vite-plugin-svelte' 2 | import { defineConfig } from 'vite' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [svelte()] 7 | }) 8 | -------------------------------------------------------------------------------- /examples/with-vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/vue 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/with-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-vue", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build" 8 | }, 9 | "dependencies": { 10 | "@fireworks-js/vue": "workspace:*", 11 | "vue": "3.2.40" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-vue": "3.1.2", 15 | "typescript": "4.8.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/with-vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 42 | 43 | 55 | -------------------------------------------------------------------------------- /examples/with-vue/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /examples/with-vue/src/shim.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /examples/with-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "moduleResolution": "node" 6 | }, 7 | "include": [ 8 | "src/**/*" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/with-vue/vite.config.js: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import { defineConfig } from 'vite' 3 | 4 | export default defineConfig({ 5 | plugins: [vue()] 6 | }) 7 | -------------------------------------------------------------------------------- /examples/with-web-components/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/web 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/with-web-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-web-components", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@fireworks-js/web": "workspace:*" 12 | }, 13 | "devDependencies": { 14 | "typescript": "4.8.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/with-web-components/src/index.ts: -------------------------------------------------------------------------------- 1 | import '@fireworks-js/web' 2 | -------------------------------------------------------------------------------- /examples/with-web-components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": [ 7 | "ESNext", 8 | "DOM" 9 | ], 10 | "moduleResolution": "Node", 11 | "strict": true, 12 | "sourceMap": true, 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "esModuleInterop": true, 16 | "noEmit": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noImplicitReturns": true, 20 | "skipLibCheck": true 21 | }, 22 | "include": [ 23 | "src" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/monorepo", 3 | "version": "2.10.7", 4 | "private": true, 5 | "type": "module", 6 | "description": "A simple fireworks library!", 7 | "homepage": "https://fireworks.js.org", 8 | "packageManager": "pnpm@8.0.0", 9 | "workspaces": [ 10 | "packages/*", 11 | "examples/*", 12 | "website" 13 | ], 14 | "scripts": { 15 | "dev": "turbo run dev --filter=./packages/*", 16 | "build": "turbo run build --filter=./packages/*", 17 | "dev:website": "turbo run dev --filter=./website", 18 | "build:website": "turbo run build --filter=./website", 19 | "dev:examples": "turbo run dev --filter=./examples/*", 20 | "build:examples": "turbo run build --filter=./examples/*", 21 | "format": "prettier --write --ignore-unknown **", 22 | "changesets": "changeset" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 27 | }, 28 | "keywords": [ 29 | "react", 30 | "preact", 31 | "solid", 32 | "vue", 33 | "angular", 34 | "svelte", 35 | "web-components", 36 | "canvas", 37 | "fireworks", 38 | "animation" 39 | ], 40 | "author": { 41 | "name": "Vitalij Ryndin", 42 | "email": "sys@crashmax.ru", 43 | "url": "https://crashmax.ru" 44 | }, 45 | "license": "MIT", 46 | "bugs": { 47 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 48 | }, 49 | "devDependencies": { 50 | "@changesets/cli": "2.26.2", 51 | "@crashmax/prettier-config": "2.2.1", 52 | "@crashmax/tsconfig": "1.0.2", 53 | "@types/node": "18.11.9", 54 | "del-cli": "5.0.0", 55 | "tsx": "3.11.0", 56 | "turbo": "1.6.3", 57 | "typescript": "4.8.4", 58 | "vite": "3.2.2", 59 | "vite-plugin-banner": "0.6.1", 60 | "vite-plugin-dts": "1.6.6" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /packages/angular/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/angular 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "ng-fireworks": { 7 | "projectType": "library", 8 | "root": "projects/ng-fireworks", 9 | "sourceRoot": "projects/ng-fireworks/src", 10 | "prefix": "lib", 11 | "architect": { 12 | "build": { 13 | "builder": "@angular-devkit/build-angular:ng-packagr", 14 | "options": { 15 | "project": "projects/ng-fireworks/ng-package.json" 16 | }, 17 | "configurations": { 18 | "production": { 19 | "tsConfig": "projects/ng-fireworks/tsconfig.lib.prod.json" 20 | }, 21 | "development": { 22 | "tsConfig": "projects/ng-fireworks/tsconfig.lib.json" 23 | } 24 | }, 25 | "defaultConfiguration": "production" 26 | } 27 | } 28 | } 29 | }, 30 | "cli": { 31 | "analytics": false 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/angular", 3 | "private": true, 4 | "version": "2.10.7", 5 | "typings": "./dist/ng-fireworks/index.d.ts", 6 | "exports": { 7 | "./package.json": { 8 | "default": "./dist/ng-fireworks/package.json" 9 | }, 10 | ".": { 11 | "types": "./dist/ng-fireworks/index.d.ts", 12 | "esm2020": "./dist/ng-fireworks/esm2020/fireworks-js-angular.mjs", 13 | "es2020": "./dist/ng-fireworks/fesm2020/fireworks-js-angular.mjs", 14 | "es2015": "./dist/ng-fireworks/fesm2015/fireworks-js-angular.mjs", 15 | "node": "./dist/ng-fireworks/fesm2015/fireworks-js-angular.mjs", 16 | "default": "./dist/ng-fireworks/fesm2020/fireworks-js-angular.mjs" 17 | } 18 | }, 19 | "scripts": { 20 | "ng": "ng", 21 | "start": "ng serve", 22 | "build": "ng build", 23 | "watch": "ng build --watch --configuration development" 24 | }, 25 | "dependencies": { 26 | "@angular/animations": "^14.1.2", 27 | "@angular/common": "^14.1.2", 28 | "@angular/compiler": "^14.1.2", 29 | "@angular/core": "^14.1.2", 30 | "@angular/forms": "^14.1.2", 31 | "@angular/platform-browser": "^14.1.2", 32 | "@angular/platform-browser-dynamic": "^14.1.2", 33 | "@angular/router": "^14.1.2", 34 | "fireworks-js": "workspace:2.10.7", 35 | "rxjs": "~7.5.6", 36 | "tslib": "2.4.0", 37 | "zone.js": "~0.11.8" 38 | }, 39 | "devDependencies": { 40 | "@angular-devkit/build-angular": "^14.1.2", 41 | "@angular/cli": "~14.0.7", 42 | "@angular/compiler-cli": "^14.1.2", 43 | "@types/jasmine": "~4.0.3", 44 | "jasmine-core": "~4.1.1", 45 | "ng-packagr": "^14.1.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/ng-fireworks", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | }, 7 | "allowedNonPeerDependencies": [ 8 | "fireworks-js" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/angular", 3 | "version": "2.10.7", 4 | "description": "A simple fireworks library!", 5 | "homepage": "https://fireworks.js.org", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 9 | }, 10 | "keywords": [ 11 | "angular", 12 | "canvas", 13 | "fireworks", 14 | "animation" 15 | ], 16 | "author": { 17 | "name": "Vitalij Ryndin", 18 | "email": "sys@crashmax.ru", 19 | "url": "https://crashmax.ru" 20 | }, 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 24 | }, 25 | "peerDependencies": { 26 | "@angular/common": "^12.0.0", 27 | "@angular/core": "^12.0.0" 28 | }, 29 | "dependencies": { 30 | "fireworks-js": "workspace:2.10.7", 31 | "tslib": "2.5.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/src/lib/ng-fireworks.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Input } from '@angular/core' 2 | import { Fireworks } from 'fireworks-js' 3 | import type { FireworksOptions } from 'fireworks-js' 4 | 5 | @Directive({ 6 | selector: '[ngFireworks], ng-fireworks', 7 | exportAs: 'ngFireworks' 8 | }) 9 | export class FireworksDirective extends Fireworks { 10 | constructor(elRef: ElementRef) { 11 | super(elRef.nativeElement) 12 | } 13 | 14 | @Input() options!: FireworksOptions 15 | 16 | private ngOnInit() { 17 | this.updateOptions(this.options) 18 | this.updateSize() 19 | this.start() 20 | } 21 | 22 | private ngOnDestroy(): void { 23 | this.stop() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/src/lib/ng-fireworks.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core' 2 | import { FireworksDirective } from './ng-fireworks.directive' 3 | 4 | export type { FireworksOptions } from 'fireworks-js' 5 | 6 | @NgModule({ 7 | declarations: [FireworksDirective], 8 | exports: [FireworksDirective] 9 | }) 10 | export class NgFireworksModule {} 11 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/src/public-api.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/ng-fireworks.directive' 2 | export * from './lib/ng-fireworks.module' 3 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/lib", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "inlineSources": true, 9 | "types": [] 10 | }, 11 | "exclude": [ 12 | "src/test.ts", 13 | "**/*.spec.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/angular/projects/ng-fireworks/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.lib.json", 4 | "compilerOptions": { 5 | "declarationMap": false 6 | }, 7 | "angularCompilerOptions": { 8 | "compilationMode": "partial" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "paths": { 15 | "ng-fireworks": [ 16 | "dist/ng-fireworks" 17 | ] 18 | }, 19 | "declaration": false, 20 | "downlevelIteration": true, 21 | "experimentalDecorators": true, 22 | "moduleResolution": "node", 23 | "importHelpers": true, 24 | "target": "es2020", 25 | "module": "es2020", 26 | "lib": [ 27 | "es2020", 28 | "dom" 29 | ] 30 | }, 31 | "angularCompilerOptions": { 32 | "enableI18nLegacyMessageIdFormat": false, 33 | "strictInjectionParameters": true, 34 | "strictInputAccessModifiers": true, 35 | "strictTemplates": true 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/fireworks-js/README.md: -------------------------------------------------------------------------------- 1 | # fireworks-js 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/fireworks-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fireworks-js", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "main": "./dist/index.cjs.js", 9 | "jsdelivr": "./dist/index.umd.js", 10 | "unpkg": "./dist/index.umd.js", 11 | "module": "./dist/index.es.js", 12 | "exports": { 13 | "require": "./dist/index.cjs.js", 14 | "import": "./dist/index.es.js", 15 | "types": "./dist/index.d.ts" 16 | }, 17 | "files": [ 18 | "dist" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 23 | }, 24 | "keywords": [ 25 | "canvas", 26 | "fireworks", 27 | "animation" 28 | ], 29 | "author": { 30 | "name": "Vitalij Ryndin", 31 | "email": "sys@crashmax.ru", 32 | "url": "https://crashmax.ru" 33 | }, 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 37 | }, 38 | "scripts": { 39 | "dev": "vite build --watch", 40 | "build": "vite build", 41 | "prepublishOnly": "pnpm build" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/explosion.ts: -------------------------------------------------------------------------------- 1 | import { hsla, randomFloat, randomInt } from './helpers.js' 2 | import type { FireworksTypes } from './types.js' 3 | 4 | export class Explosion { 5 | private x: number 6 | private y: number 7 | private ctx: CanvasRenderingContext2D 8 | private hue: number 9 | private friction: number 10 | private gravity: number 11 | private flickering: boolean 12 | private lineWidth: number 13 | private explosionLength: number 14 | 15 | private angle: number 16 | private speed: number 17 | private brightness: number 18 | private coordinates: [number, number][] = [] 19 | private decay: number 20 | private alpha = 1 21 | 22 | constructor({ 23 | x, 24 | y, 25 | ctx, 26 | hue, 27 | decay, 28 | gravity, 29 | friction, 30 | brightness, 31 | flickering, 32 | lineWidth, 33 | explosionLength 34 | }: FireworksTypes.Explosion) { 35 | this.x = x 36 | this.y = y 37 | this.ctx = ctx 38 | this.hue = hue 39 | this.gravity = gravity 40 | this.friction = friction 41 | this.flickering = flickering 42 | this.lineWidth = lineWidth 43 | this.explosionLength = explosionLength 44 | this.angle = randomFloat(0, Math.PI * 2) 45 | this.speed = randomInt(1, 10) 46 | this.brightness = randomInt(brightness.min, brightness.max) 47 | this.decay = randomFloat(decay.min, decay.max) 48 | 49 | while (this.explosionLength--) { 50 | this.coordinates.push([x, y]) 51 | } 52 | } 53 | 54 | update(callback: () => void): void { 55 | this.coordinates.pop() 56 | this.coordinates.unshift([this.x, this.y]) 57 | this.speed *= this.friction 58 | this.x += Math.cos(this.angle) * this.speed 59 | this.y += Math.sin(this.angle) * this.speed + this.gravity 60 | this.alpha -= this.decay 61 | 62 | if (this.alpha <= this.decay) { 63 | callback() 64 | } 65 | } 66 | 67 | draw(): void { 68 | const lastIndex = this.coordinates.length - 1 69 | 70 | this.ctx.beginPath() 71 | this.ctx.lineWidth = this.lineWidth 72 | this.ctx.fillStyle = hsla(this.hue, this.brightness, this.alpha) 73 | this.ctx.moveTo( 74 | this.coordinates[lastIndex]![0], 75 | this.coordinates[lastIndex]![1] 76 | ) 77 | this.ctx.lineTo(this.x, this.y) 78 | this.ctx.strokeStyle = hsla( 79 | this.hue, 80 | this.flickering ? randomFloat(0, this.brightness) : this.brightness, 81 | this.alpha 82 | ) 83 | this.ctx.stroke() 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/fireworks.ts: -------------------------------------------------------------------------------- 1 | import { Explosion } from './explosion.js' 2 | import { floor, randomFloat, randomInt } from './helpers.js' 3 | import { Mouse } from './mouse.js' 4 | import { Options } from './options.js' 5 | import { RequestAnimationFrame } from './raf.js' 6 | import { Resize } from './resize.js' 7 | import { Sound } from './sound.js' 8 | import { Trace } from './trace.js' 9 | import type { FireworksOptions, FireworksTypes } from './types.js' 10 | 11 | declare const __VERSION__: string 12 | 13 | export class Fireworks { 14 | private target: Element | HTMLCanvasElement 15 | private container: Element 16 | private canvas: HTMLCanvasElement 17 | private ctx: CanvasRenderingContext2D 18 | private width: number 19 | private height: number 20 | private traces: Trace[] = [] 21 | private explosions: Explosion[] = [] 22 | private waitStopRaf: (() => void) | null 23 | private running = false 24 | 25 | private readonly opts: Options 26 | private readonly sound: Sound 27 | private readonly resize: Resize 28 | private readonly mouse: Mouse 29 | private readonly raf: RequestAnimationFrame 30 | 31 | constructor( 32 | container: Element | HTMLCanvasElement, 33 | options: FireworksOptions = {} 34 | ) { 35 | this.target = container 36 | this.container = container 37 | 38 | this.opts = new Options() 39 | 40 | this.createCanvas(this.target) 41 | this.updateOptions(options) 42 | 43 | this.sound = new Sound(this.opts) 44 | this.resize = new Resize( 45 | this.opts, 46 | this.updateSize.bind(this), 47 | this.container 48 | ) 49 | this.mouse = new Mouse(this.opts, this.canvas) 50 | this.raf = new RequestAnimationFrame(this.opts, this.render.bind(this)) 51 | } 52 | 53 | get isRunning(): boolean { 54 | return this.running 55 | } 56 | 57 | get version(): string { 58 | return __VERSION__ 59 | } 60 | 61 | get currentOptions(): Options { 62 | return this.opts 63 | } 64 | 65 | start(): void { 66 | if (this.running) return 67 | 68 | if (!this.canvas.isConnected) { 69 | this.createCanvas(this.target) 70 | } 71 | 72 | this.running = true 73 | this.resize.mount() 74 | this.mouse.mount() 75 | this.raf.mount() 76 | } 77 | 78 | stop(dispose = false): void { 79 | if (!this.running) return 80 | 81 | this.running = false 82 | this.resize.unmount() 83 | this.mouse.unmount() 84 | this.raf.unmount() 85 | this.clear() 86 | 87 | if (dispose) { 88 | this.canvas.remove() 89 | } 90 | } 91 | 92 | async waitStop(dispose?: boolean): Promise { 93 | if (!this.running) return 94 | 95 | return new Promise((resolve) => { 96 | this.waitStopRaf = () => { 97 | if (!this.waitStopRaf) return 98 | requestAnimationFrame(this.waitStopRaf) 99 | if (!this.traces.length && !this.explosions.length) { 100 | this.waitStopRaf = null 101 | this.stop(dispose) 102 | resolve() 103 | } 104 | } 105 | 106 | this.waitStopRaf() 107 | }) 108 | } 109 | 110 | pause(): void { 111 | this.running = !this.running 112 | if (this.running) { 113 | this.raf.mount() 114 | } else { 115 | this.raf.unmount() 116 | } 117 | } 118 | 119 | clear(): void { 120 | if (!this.ctx) return 121 | 122 | this.traces = [] 123 | this.explosions = [] 124 | this.ctx.clearRect(0, 0, this.width, this.height) 125 | } 126 | 127 | launch(count = 1): void { 128 | for (let i = 0; i < count; i++) { 129 | this.createTrace() 130 | } 131 | 132 | if (!this.waitStopRaf) { 133 | this.start() 134 | this.waitStop() 135 | } 136 | } 137 | 138 | updateOptions(options: FireworksOptions): void { 139 | this.opts.update(options) 140 | } 141 | 142 | updateSize({ 143 | width = this.container.clientWidth, 144 | height = this.container.clientHeight 145 | }: Partial = {}): void { 146 | this.width = width 147 | this.height = height 148 | 149 | this.canvas.width = width 150 | this.canvas.height = height 151 | 152 | this.updateBoundaries({ 153 | ...this.opts.boundaries, 154 | width, 155 | height 156 | }) 157 | } 158 | 159 | updateBoundaries(boundaries: Partial): void { 160 | this.updateOptions({ boundaries }) 161 | } 162 | 163 | private createCanvas(el: Element | HTMLCanvasElement): void { 164 | if (el instanceof HTMLCanvasElement) { 165 | if (!el.isConnected) { 166 | document.body.append(el) 167 | } 168 | 169 | this.canvas = el 170 | } else { 171 | this.canvas = document.createElement('canvas') 172 | this.container.append(this.canvas) 173 | } 174 | 175 | this.ctx = this.canvas.getContext('2d')! 176 | this.updateSize() 177 | } 178 | 179 | private render(): void { 180 | if (!this.ctx || !this.running) return 181 | 182 | const { opacity, lineStyle, lineWidth } = this.opts 183 | this.ctx.globalCompositeOperation = 'destination-out' 184 | this.ctx.fillStyle = `rgba(0, 0, 0, ${opacity})` 185 | this.ctx.fillRect(0, 0, this.width, this.height) 186 | this.ctx.globalCompositeOperation = 'lighter' 187 | this.ctx.lineCap = lineStyle 188 | this.ctx.lineJoin = 'round' 189 | this.ctx.lineWidth = randomFloat(lineWidth.trace.min, lineWidth.trace.max) 190 | 191 | this.initTrace() 192 | this.drawTrace() 193 | this.drawExplosion() 194 | } 195 | 196 | private createTrace(): void { 197 | const { 198 | hue, 199 | rocketsPoint, 200 | boundaries, 201 | traceLength, 202 | traceSpeed, 203 | acceleration, 204 | mouse 205 | } = this.opts 206 | 207 | this.traces.push( 208 | new Trace({ 209 | x: (this.width * randomInt(rocketsPoint.min, rocketsPoint.max)) / 100, 210 | y: this.height, 211 | dx: 212 | (this.mouse.x && mouse.move) || this.mouse.active 213 | ? this.mouse.x 214 | : randomInt(boundaries.x, boundaries.width - boundaries.x * 2), 215 | dy: 216 | (this.mouse.y && mouse.move) || this.mouse.active 217 | ? this.mouse.y 218 | : randomInt(boundaries.y, boundaries.height * 0.5), 219 | ctx: this.ctx, 220 | hue: randomInt(hue.min, hue.max), 221 | speed: traceSpeed, 222 | acceleration, 223 | traceLength: floor(traceLength) 224 | }) 225 | ) 226 | } 227 | 228 | private initTrace(): void { 229 | if (this.waitStopRaf) return 230 | 231 | const { delay, mouse } = this.opts 232 | if ( 233 | this.raf.tick > randomInt(delay.min, delay.max) || 234 | (this.mouse.active && mouse.max > this.traces.length) 235 | ) { 236 | this.createTrace() 237 | this.raf.tick = 0 238 | } 239 | } 240 | 241 | private drawTrace(): void { 242 | let traceLength = this.traces.length 243 | while (traceLength--) { 244 | this.traces[traceLength]!.draw() 245 | this.traces[traceLength]!.update((x: number, y: number, hue: number) => { 246 | this.initExplosion(x, y, hue) 247 | this.sound.play() 248 | this.traces.splice(traceLength, 1) 249 | }) 250 | } 251 | } 252 | 253 | private initExplosion(x: number, y: number, hue: number): void { 254 | const { 255 | particles, 256 | flickering, 257 | lineWidth, 258 | explosion, 259 | brightness, 260 | friction, 261 | gravity, 262 | decay 263 | } = this.opts 264 | 265 | let particlesLength = floor(particles) 266 | while (particlesLength--) { 267 | this.explosions.push( 268 | new Explosion({ 269 | x, 270 | y, 271 | ctx: this.ctx, 272 | hue, 273 | friction, 274 | gravity, 275 | flickering: randomInt(0, 100) <= flickering, 276 | lineWidth: randomFloat( 277 | lineWidth.explosion.min, 278 | lineWidth.explosion.max 279 | ), 280 | explosionLength: floor(explosion), 281 | brightness, 282 | decay 283 | }) 284 | ) 285 | } 286 | } 287 | 288 | private drawExplosion(): void { 289 | let length = this.explosions.length 290 | while (length--) { 291 | this.explosions[length]!.draw() 292 | this.explosions[length]!.update(() => { 293 | this.explosions.splice(length, 1) 294 | }) 295 | } 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/helpers.ts: -------------------------------------------------------------------------------- 1 | export function floor(num: number): number { 2 | return Math.abs(Math.floor(num)) 3 | } 4 | 5 | export function randomFloat(min: number, max: number): number { 6 | return Math.random() * (max - min) + min 7 | } 8 | 9 | export function randomInt(min: number, max: number): number { 10 | return Math.floor(randomFloat(min, max + 1)) 11 | } 12 | 13 | export function getDistance( 14 | x: number, 15 | y: number, 16 | dx: number, 17 | dy: number 18 | ): number { 19 | const pow = Math.pow 20 | return Math.sqrt(pow(x - dx, 2) + pow(y - dy, 2)) 21 | } 22 | 23 | export function hsla(hue: number, lightness: number, alpha = 1): string { 24 | if (hue > 360 || hue < 0) { 25 | throw new Error(`Expected hue 0-360 range, got \`${hue}\``) 26 | } 27 | 28 | if (lightness > 100 || lightness < 0) { 29 | throw new Error(`Expected lightness 0-100 range, got \`${lightness}\``) 30 | } 31 | 32 | if (alpha > 1 || alpha < 0) { 33 | throw new Error(`Expected alpha 0-1 range, got \`${alpha}\``) 34 | } 35 | 36 | return `hsla(${hue}, 100%, ${lightness}%, ${alpha})` 37 | } 38 | 39 | /* https://github.com/voodoocreation/ts-deepmerge */ 40 | interface IObject { 41 | [key: string]: any 42 | length?: never 43 | } 44 | 45 | type IUnionToIntersection = ( 46 | U extends any ? (k: U) => void : never 47 | ) extends (k: infer I) => void 48 | ? I 49 | : never 50 | 51 | const isObject = (obj: any) => { 52 | if (typeof obj === 'object' && obj !== null) { 53 | if (typeof Object.getPrototypeOf === 'function') { 54 | const prototype = Object.getPrototypeOf(obj) 55 | return prototype === Object.prototype || prototype === null 56 | } 57 | 58 | return Object.prototype.toString.call(obj) === '[object Object]' 59 | } 60 | 61 | return false 62 | } 63 | 64 | const PROTECTED_KEYS = [ 65 | '__proto__', 66 | 'constructor', 67 | 'prototype' 68 | ] 69 | 70 | export const deepMerge = ( 71 | ...objects: T 72 | ): IUnionToIntersection => { 73 | return objects.reduce((result, current) => { 74 | Object.keys(current).forEach((key) => { 75 | if (PROTECTED_KEYS.includes(key)) { 76 | return 77 | } 78 | 79 | if (Array.isArray(result[key]) && Array.isArray(current[key])) { 80 | result[key] = false 81 | ? Array.from(new Set((result[key] as unknown[]).concat(current[key]))) 82 | : current[key] 83 | } else if (isObject(result[key]) && isObject(current[key])) { 84 | result[key] = deepMerge(result[key] as IObject, current[key] as IObject) 85 | } else { 86 | result[key] = current[key] 87 | } 88 | }) 89 | 90 | return result 91 | }, {}) as any 92 | } 93 | 94 | // https://github.com/zero-dependency/utils/blob/master/src/debounce.ts 95 | export function debounce void>( 96 | fn: T, 97 | ms: number 98 | ): (...args: Parameters) => void { 99 | let timeoutId: ReturnType 100 | 101 | return (...args) => { 102 | if (timeoutId) { 103 | clearTimeout(timeoutId) 104 | } 105 | 106 | timeoutId = setTimeout(() => fn(...args), ms) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Fireworks } from './fireworks.js' 2 | import type { 3 | FireworksHandlers, 4 | FireworksOptions, 5 | FireworksTypes 6 | } from './types.js' 7 | 8 | export { Fireworks } 9 | export default Fireworks 10 | export type { FireworksTypes, FireworksOptions, FireworksHandlers } 11 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/mouse.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from './options.js' 2 | 3 | export class Mouse { 4 | active = false 5 | x: number 6 | y: number 7 | 8 | constructor( 9 | private readonly options: Options, 10 | private readonly canvas: HTMLCanvasElement 11 | ) { 12 | this.pointerDown = this.pointerDown.bind(this) 13 | this.pointerUp = this.pointerUp.bind(this) 14 | this.pointerMove = this.pointerMove.bind(this) 15 | } 16 | 17 | private get mouseOptions() { 18 | return this.options.mouse 19 | } 20 | 21 | mount(): void { 22 | this.canvas.addEventListener('pointerdown', this.pointerDown) 23 | this.canvas.addEventListener('pointerup', this.pointerUp) 24 | this.canvas.addEventListener('pointermove', this.pointerMove) 25 | } 26 | 27 | unmount(): void { 28 | this.canvas.removeEventListener('pointerdown', this.pointerDown) 29 | this.canvas.removeEventListener('pointerup', this.pointerUp) 30 | this.canvas.removeEventListener('pointermove', this.pointerMove) 31 | } 32 | 33 | private usePointer(event: PointerEvent, active: boolean): void { 34 | const { click, move } = this.mouseOptions 35 | if (click || move) { 36 | this.x = event.pageX - this.canvas.offsetLeft 37 | this.y = event.pageY - this.canvas.offsetTop 38 | this.active = active 39 | } 40 | } 41 | 42 | private pointerDown(event: PointerEvent): void { 43 | this.usePointer(event, this.mouseOptions.click) 44 | } 45 | 46 | private pointerUp(event: PointerEvent): void { 47 | this.usePointer(event, false) 48 | } 49 | 50 | private pointerMove(event: PointerEvent): void { 51 | this.usePointer(event, this.active) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/options.ts: -------------------------------------------------------------------------------- 1 | import { deepMerge } from './helpers.js' 2 | import type { FireworksOptions, FireworksTypes } from './types.js' 3 | 4 | export class Options implements FireworksTypes.Options { 5 | hue: FireworksTypes.MinMax 6 | rocketsPoint: FireworksTypes.MinMax 7 | opacity: number 8 | acceleration: number 9 | friction: number 10 | gravity: number 11 | particles: number 12 | explosion: number 13 | mouse: FireworksTypes.Mouse 14 | boundaries: FireworksTypes.Boundaries 15 | sound: FireworksTypes.Sounds 16 | delay: FireworksTypes.MinMax 17 | brightness: FireworksTypes.MinMax 18 | decay: FireworksTypes.MinMax 19 | flickering: number 20 | intensity: number 21 | traceLength: number 22 | traceSpeed: number 23 | lineWidth: FireworksTypes.LineWidth 24 | lineStyle: FireworksTypes.LineStyle 25 | autoresize: boolean 26 | 27 | constructor() { 28 | this.autoresize = true 29 | this.lineStyle = 'round' 30 | this.flickering = 50 31 | this.traceLength = 3 32 | this.traceSpeed = 10 33 | this.intensity = 30 34 | this.explosion = 5 35 | this.gravity = 1.5 36 | this.opacity = 0.5 37 | this.particles = 50 38 | this.friction = 0.95 39 | this.acceleration = 1.05 40 | 41 | this.hue = { 42 | min: 0, 43 | max: 360 44 | } 45 | 46 | this.rocketsPoint = { 47 | min: 50, 48 | max: 50 49 | } 50 | 51 | this.lineWidth = { 52 | explosion: { 53 | min: 1, 54 | max: 3 55 | }, 56 | trace: { 57 | min: 1, 58 | max: 2 59 | } 60 | } 61 | 62 | this.mouse = { 63 | click: false, 64 | move: false, 65 | max: 1 66 | } 67 | 68 | this.delay = { 69 | min: 30, 70 | max: 60 71 | } 72 | 73 | this.brightness = { 74 | min: 50, 75 | max: 80 76 | } 77 | 78 | this.decay = { 79 | min: 0.015, 80 | max: 0.03 81 | } 82 | 83 | this.sound = { 84 | enabled: false, 85 | files: [ 86 | 'explosion0.mp3', 87 | 'explosion1.mp3', 88 | 'explosion2.mp3' 89 | ], 90 | volume: { 91 | min: 4, 92 | max: 8 93 | } 94 | } 95 | 96 | this.boundaries = { 97 | debug: false, 98 | height: 0, 99 | width: 0, 100 | x: 50, 101 | y: 50 102 | } 103 | } 104 | 105 | update(options: T): void { 106 | Object.assign(this, deepMerge(this, options)) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/raf.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from './options.js' 2 | 3 | export class RequestAnimationFrame { 4 | tick = 0 5 | 6 | private rafId = 0 7 | private fps = 60 8 | private tolerance = 0.1 9 | private now: number 10 | 11 | constructor( 12 | private readonly options: Options, 13 | private readonly render: () => void 14 | ) {} 15 | 16 | mount(): void { 17 | this.now = performance.now() 18 | const interval = 1000 / this.fps 19 | 20 | const raf = (timestamp: number) => { 21 | this.rafId = requestAnimationFrame(raf) 22 | const delta = timestamp - this.now 23 | 24 | if (delta >= interval - this.tolerance) { 25 | this.render() 26 | this.now = timestamp - (delta % interval) 27 | this.tick += (delta * (this.options.intensity * Math.PI)) / 1000 28 | } 29 | } 30 | 31 | this.rafId = requestAnimationFrame(raf) 32 | } 33 | 34 | unmount() { 35 | cancelAnimationFrame(this.rafId) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/resize.ts: -------------------------------------------------------------------------------- 1 | import { debounce } from './helpers.js' 2 | import type { Options } from './options.js' 3 | 4 | export class Resize { 5 | private resizer: ResizeObserver | undefined 6 | 7 | constructor( 8 | private readonly options: Options, 9 | private readonly updateSize: () => void, 10 | private readonly container: Element 11 | ) {} 12 | 13 | mount(): void { 14 | if (!this.resizer) { 15 | const debouncedResize = debounce(() => this.updateSize(), 100) 16 | this.resizer = new ResizeObserver(debouncedResize) 17 | } 18 | 19 | if (this.options.autoresize) { 20 | this.resizer.observe(this.container) 21 | } 22 | } 23 | 24 | unmount(): void { 25 | if (this.resizer) { 26 | this.resizer.unobserve(this.container) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/sound.ts: -------------------------------------------------------------------------------- 1 | import { randomFloat, randomInt } from './helpers.js' 2 | import type { Options } from './options.js' 3 | 4 | declare global { 5 | interface Window { 6 | webkitAudioContext: typeof AudioContext 7 | } 8 | } 9 | 10 | export class Sound { 11 | private buffers: AudioBuffer[] = [] 12 | private audioContext: AudioContext 13 | private onInit = false 14 | 15 | constructor(private readonly options: Options) { 16 | this.init() 17 | } 18 | 19 | private get isEnabled() { 20 | return this.options.sound.enabled 21 | } 22 | 23 | private get soundOptions() { 24 | return this.options.sound 25 | } 26 | 27 | private init(): void { 28 | if (!this.onInit && this.isEnabled) { 29 | this.onInit = true 30 | this.audioContext = new (window.AudioContext || 31 | window.webkitAudioContext)() 32 | this.loadSounds() 33 | } 34 | } 35 | 36 | private async loadSounds(): Promise { 37 | for (const file of this.soundOptions.files) { 38 | const response = await (await fetch(file)).arrayBuffer() 39 | 40 | this.audioContext 41 | .decodeAudioData(response) 42 | .then((buffer) => { 43 | this.buffers.push(buffer) 44 | }) 45 | .catch((err) => { 46 | throw err 47 | }) 48 | } 49 | } 50 | 51 | play(): void { 52 | if (this.isEnabled && this.buffers.length) { 53 | const bufferSource = this.audioContext.createBufferSource() 54 | const soundBuffer = this.buffers[randomInt(0, this.buffers.length - 1)]! 55 | const volume = this.audioContext.createGain() 56 | 57 | bufferSource.buffer = soundBuffer 58 | volume.gain.value = randomFloat( 59 | this.soundOptions.volume.min / 100, 60 | this.soundOptions.volume.max / 100 61 | ) 62 | volume.connect(this.audioContext.destination) 63 | bufferSource.connect(volume) 64 | bufferSource.start(0) 65 | } else { 66 | this.init() 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/trace.ts: -------------------------------------------------------------------------------- 1 | import { getDistance, hsla, randomInt } from './helpers.js' 2 | import type { FireworksTypes } from './types.js' 3 | 4 | export class Trace { 5 | private x: number 6 | private y: number 7 | private sx: number 8 | private sy: number 9 | private dx: number 10 | private dy: number 11 | private ctx: CanvasRenderingContext2D 12 | private hue: number 13 | private speed: number 14 | private acceleration: number 15 | private traceLength: number 16 | 17 | private totalDistance: number 18 | private angle: number 19 | private brightness: number 20 | private coordinates: [number, number][] = [] 21 | private currentDistance = 0 22 | 23 | constructor({ 24 | x, 25 | y, 26 | dx, 27 | dy, 28 | ctx, 29 | hue, 30 | speed, 31 | traceLength, 32 | acceleration 33 | }: FireworksTypes.Trace) { 34 | this.x = x 35 | this.y = y 36 | this.sx = x 37 | this.sy = y 38 | this.dx = dx 39 | this.dy = dy 40 | this.ctx = ctx 41 | this.hue = hue 42 | this.speed = speed 43 | this.traceLength = traceLength 44 | this.acceleration = acceleration 45 | this.totalDistance = getDistance(x, y, dx, dy) 46 | this.angle = Math.atan2(dy - y, dx - x) 47 | this.brightness = randomInt(50, 70) 48 | 49 | while (this.traceLength--) { 50 | this.coordinates.push([x, y]) 51 | } 52 | } 53 | 54 | update(callback: (x: number, y: number, hue: number) => void): void { 55 | this.coordinates.pop() 56 | this.coordinates.unshift([this.x, this.y]) 57 | this.speed *= this.acceleration 58 | 59 | const vx = Math.cos(this.angle) * this.speed 60 | const vy = Math.sin(this.angle) * this.speed 61 | 62 | this.currentDistance = getDistance( 63 | this.sx, 64 | this.sy, 65 | this.x + vx, 66 | this.y + vy 67 | ) 68 | 69 | if (this.currentDistance >= this.totalDistance) { 70 | callback(this.dx, this.dy, this.hue) 71 | } else { 72 | this.x += vx 73 | this.y += vy 74 | } 75 | } 76 | 77 | draw(): void { 78 | const lastIndex = this.coordinates.length - 1 79 | 80 | this.ctx.beginPath() 81 | this.ctx.moveTo( 82 | this.coordinates[lastIndex]![0], 83 | this.coordinates[lastIndex]![1] 84 | ) 85 | this.ctx.lineTo(this.x, this.y) 86 | this.ctx.strokeStyle = hsla(this.hue, this.brightness) 87 | this.ctx.stroke() 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /packages/fireworks-js/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Fireworks } from './fireworks.js' 2 | 3 | export namespace FireworksTypes { 4 | export interface Options { 5 | hue: MinMax 6 | rocketsPoint: MinMax 7 | opacity: number 8 | acceleration: number 9 | friction: number 10 | gravity: number 11 | particles: number 12 | explosion: number 13 | mouse: Mouse 14 | boundaries: Boundaries 15 | sound: Sounds 16 | delay: MinMax 17 | brightness: MinMax 18 | decay: MinMax 19 | flickering: number 20 | intensity: number 21 | traceLength: number 22 | traceSpeed: number 23 | lineWidth: LineWidth 24 | lineStyle: LineStyle 25 | autoresize: boolean 26 | } 27 | 28 | export type LineStyle = 'round' | 'square' 29 | 30 | export interface Mouse { 31 | click: boolean 32 | move: boolean 33 | max: number 34 | } 35 | 36 | export interface Boundaries { 37 | x: number 38 | y: number 39 | width: number 40 | height: number 41 | debug: boolean 42 | } 43 | 44 | export interface Sounds { 45 | enabled: boolean 46 | files: string[] 47 | volume: MinMax 48 | } 49 | 50 | export interface LineWidth { 51 | explosion: MinMax 52 | trace: MinMax 53 | } 54 | 55 | export interface MinMax { 56 | min: number 57 | max: number 58 | } 59 | 60 | export interface Sizes { 61 | width: number 62 | height: number 63 | } 64 | 65 | export interface Trace { 66 | x: number 67 | y: number 68 | dx: number 69 | dy: number 70 | ctx: CanvasRenderingContext2D 71 | hue: number 72 | speed: number 73 | acceleration: number 74 | traceLength: number 75 | } 76 | 77 | export interface Explosion { 78 | x: number 79 | y: number 80 | ctx: CanvasRenderingContext2D 81 | hue: number 82 | friction: number 83 | gravity: number 84 | explosionLength: number 85 | flickering: boolean 86 | lineWidth: number 87 | brightness: MinMax 88 | decay: MinMax 89 | } 90 | } 91 | 92 | export type FireworksOptions = RecursivePartial 93 | 94 | export interface FireworksHandlers 95 | extends Pick< 96 | Fireworks, 97 | | 'isRunning' 98 | | 'start' 99 | | 'launch' 100 | | 'pause' 101 | | 'clear' 102 | | 'updateOptions' 103 | | 'updateBoundaries' 104 | | 'updateSize' 105 | | 'currentOptions' 106 | > { 107 | waitStop(): Promise 108 | stop(): void 109 | } 110 | 111 | export type RecursivePartial = { 112 | [P in keyof T]?: T[P] extends (infer U)[] 113 | ? RecursivePartial[] 114 | : T[P] extends object 115 | ? RecursivePartial 116 | : T[P] 117 | } 118 | -------------------------------------------------------------------------------- /packages/fireworks-js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "types": [ 6 | "vite/client" 7 | ] 8 | }, 9 | "include": [ 10 | "src" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/fireworks-js/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { defineConfig } from 'vite' 3 | import banner from 'vite-plugin-banner' 4 | import dts from 'vite-plugin-dts' 5 | import { author, homepage, license, name, version } from './package.json' 6 | 7 | export default defineConfig({ 8 | plugins: [ 9 | dts({ insertTypesEntry: true }), 10 | banner( 11 | `/**\n * name: ${name}` + 12 | `\n * version: ${version}` + 13 | `\n * author: ${author.name} (${author.url})` + 14 | `\n * homepage: ${homepage}` + 15 | `\n * license ${license}\n */` 16 | ) 17 | ], 18 | define: { 19 | __VERSION__: JSON.stringify(version) 20 | }, 21 | build: { 22 | target: 'esnext', 23 | lib: { 24 | entry: resolve(__dirname, 'src/index.ts'), 25 | name: 'Fireworks', 26 | formats: [ 27 | 'es', 28 | 'cjs', 29 | 'umd' 30 | ], 31 | fileName: (format) => `index.${format}.js` 32 | }, 33 | rollupOptions: { 34 | output: { 35 | exports: 'named' 36 | } 37 | } 38 | } 39 | }) 40 | -------------------------------------------------------------------------------- /packages/preact/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/preact 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/preact", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "main": "./dist/index.cjs.js", 9 | "jsdelivr": "./dist/index.umd.js", 10 | "unpkg": "./dist/index.umd.js", 11 | "module": "./dist/index.es.js", 12 | "exports": { 13 | "require": "./dist/index.cjs.js", 14 | "import": "./dist/index.es.js", 15 | "types": "./dist/index.d.ts" 16 | }, 17 | "files": [ 18 | "dist" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 23 | }, 24 | "keywords": [ 25 | "preact", 26 | "canvas", 27 | "fireworks", 28 | "animation" 29 | ], 30 | "author": { 31 | "name": "Vitalij Ryndin", 32 | "email": "sys@crashmax.ru", 33 | "url": "https://crashmax.ru" 34 | }, 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 38 | }, 39 | "scripts": { 40 | "dev": "vite build --watch", 41 | "build": "vite build && tsc", 42 | "prepublishOnly": "pnpm build" 43 | }, 44 | "dependencies": { 45 | "fireworks-js": "workspace:2.10.7" 46 | }, 47 | "devDependencies": { 48 | "@preact/preset-vite": "2.4.0", 49 | "preact": "10.11.2" 50 | }, 51 | "peerDependencies": { 52 | "preact": ">=8.0.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/preact/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { Fireworks as FireworksJs } from 'fireworks-js' 2 | import React from 'preact/compat' 3 | import { useEffect, useImperativeHandle, useRef } from 'preact/hooks' 4 | import type { FireworksHandlers, FireworksOptions } from 'fireworks-js' 5 | import type { ComponentChildren } from 'preact' 6 | 7 | interface FireworksProps extends React.HTMLAttributes { 8 | children?: ComponentChildren 9 | options?: FireworksOptions 10 | autostart?: boolean 11 | } 12 | 13 | const Fireworks = React.forwardRef( 14 | ({ children, options, autostart = true, ...rest }, ref) => { 15 | const container = useRef(null) 16 | const fireworks = useRef(null) 17 | 18 | useImperativeHandle(ref, () => ({ 19 | get isRunning() { 20 | return fireworks.current!.isRunning 21 | }, 22 | get currentOptions() { 23 | return fireworks.current!.currentOptions 24 | }, 25 | start() { 26 | fireworks.current!.start() 27 | }, 28 | launch(count) { 29 | fireworks.current!.launch(count) 30 | }, 31 | stop() { 32 | fireworks.current!.stop() 33 | }, 34 | async waitStop() { 35 | await fireworks.current!.waitStop() 36 | }, 37 | pause() { 38 | fireworks.current!.pause() 39 | }, 40 | clear() { 41 | fireworks.current!.clear() 42 | }, 43 | updateOptions(options) { 44 | fireworks.current!.updateOptions(options) 45 | }, 46 | updateSize(size) { 47 | fireworks.current!.updateSize(size) 48 | }, 49 | updateBoundaries(boundaries) { 50 | fireworks.current!.updateBoundaries(boundaries) 51 | } 52 | })) 53 | 54 | useEffect(() => { 55 | fireworks.current = new FireworksJs(container.current!, options) 56 | if (autostart) { 57 | fireworks.current.start() 58 | } 59 | 60 | return () => { 61 | fireworks.current!.stop() 62 | } 63 | }, []) 64 | 65 | return ( 66 |
70 | {children} 71 |
72 | ) 73 | } 74 | ) 75 | 76 | export { Fireworks } 77 | export default Fireworks 78 | export type { FireworksProps, FireworksHandlers, FireworksOptions } 79 | -------------------------------------------------------------------------------- /packages/preact/src/preact.d.ts: -------------------------------------------------------------------------------- 1 | import JSX = preact.JSX 2 | -------------------------------------------------------------------------------- /packages/preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "emitDeclarationOnly": true, 5 | "jsx": "preserve", 6 | "jsxFactory": "h", 7 | "jsxFragmentFactory": "Fragment", 8 | "outDir": "dist", 9 | "types": [ 10 | "vite/client" 11 | ] 12 | }, 13 | "include": [ 14 | "src" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/preact/vite.config.ts: -------------------------------------------------------------------------------- 1 | import preact from '@preact/preset-vite' 2 | import { resolve } from 'path' 3 | import { defineConfig } from 'vite' 4 | import banner from 'vite-plugin-banner' 5 | import dts from 'vite-plugin-dts' 6 | import { author, homepage, license, name, version } from './package.json' 7 | 8 | export default defineConfig({ 9 | plugins: [ 10 | preact(), 11 | dts({ insertTypesEntry: true }), 12 | banner( 13 | `/**\n * name: ${name}` + 14 | `\n * version: ${version}` + 15 | `\n * author: ${author.name} (${author.url})` + 16 | `\n * homepage: ${homepage}` + 17 | `\n * license ${license}\n */` 18 | )], 19 | build: { 20 | target: 'esnext', 21 | lib: { 22 | entry: resolve(__dirname, 'src/index.tsx'), 23 | name: 'Fireworks', 24 | formats: [ 25 | 'es', 26 | 'cjs', 27 | 'umd' 28 | ], 29 | fileName: (format) => `index.${format}.js` 30 | }, 31 | rollupOptions: { 32 | external: [ 33 | 'preact/compat', 34 | 'preact/hooks', 35 | 'fireworks-js' 36 | ], 37 | output: { 38 | exports: 'named', 39 | globals: { 40 | 'preact/compat': 'PreactCompat', 41 | 'preact/hooks': 'PreactHooks', 42 | 'fireworks-js': 'Fireworks' 43 | } 44 | } 45 | } 46 | } 47 | }) 48 | -------------------------------------------------------------------------------- /packages/react/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/react 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/react", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "main": "./dist/index.cjs.js", 9 | "jsdelivr": "./dist/index.umd.js", 10 | "unpkg": "./dist/index.umd.js", 11 | "module": "./dist/index.es.js", 12 | "exports": { 13 | "require": "./dist/index.cjs.js", 14 | "import": "./dist/index.es.js", 15 | "types": "./dist/index.d.ts" 16 | }, 17 | "files": [ 18 | "dist" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 23 | }, 24 | "keywords": [ 25 | "react", 26 | "canvas", 27 | "fireworks", 28 | "animation" 29 | ], 30 | "author": { 31 | "name": "Vitalij Ryndin", 32 | "email": "sys@crashmax.ru", 33 | "url": "https://crashmax.ru" 34 | }, 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 38 | }, 39 | "scripts": { 40 | "dev": "vite build --watch", 41 | "build": "vite build", 42 | "prepublishOnly": "pnpm build" 43 | }, 44 | "dependencies": { 45 | "fireworks-js": "workspace:2.10.7" 46 | }, 47 | "devDependencies": { 48 | "@types/react": "18.0.24", 49 | "@types/react-dom": "18.0.8", 50 | "@vitejs/plugin-react": "2.2.0", 51 | "react": "18.2.0", 52 | "react-dom": "18.2.0" 53 | }, 54 | "peerDependencies": { 55 | "@types/react": ">=16.8.0", 56 | "react": ">=16.8.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/react/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useImperativeHandle, useRef } from 'react' 2 | import { Fireworks as FireworksJs } from 'fireworks-js' 3 | import type { FireworksHandlers, FireworksOptions } from 'fireworks-js' 4 | 5 | interface FireworksProps extends React.HTMLAttributes { 6 | children?: React.ReactNode 7 | options?: FireworksOptions 8 | autostart?: boolean 9 | } 10 | 11 | const Fireworks = React.forwardRef( 12 | ({ children, options, autostart = true, ...rest }, ref) => { 13 | const container = useRef(null) 14 | const fireworks = useRef(null) 15 | 16 | useImperativeHandle(ref, () => ({ 17 | get isRunning() { 18 | return fireworks.current!.isRunning 19 | }, 20 | get currentOptions() { 21 | return fireworks.current!.currentOptions 22 | }, 23 | start() { 24 | fireworks.current!.start() 25 | }, 26 | launch(count) { 27 | fireworks.current!.launch(count) 28 | }, 29 | stop() { 30 | fireworks.current!.stop() 31 | }, 32 | async waitStop() { 33 | await fireworks.current!.waitStop() 34 | }, 35 | pause() { 36 | fireworks.current!.pause() 37 | }, 38 | clear() { 39 | fireworks.current!.clear() 40 | }, 41 | updateOptions(options) { 42 | fireworks.current!.updateOptions(options) 43 | }, 44 | updateSize(size) { 45 | fireworks.current!.updateSize(size) 46 | }, 47 | updateBoundaries(boundaries) { 48 | fireworks.current!.updateBoundaries(boundaries) 49 | } 50 | })) 51 | 52 | useEffect(() => { 53 | if (!fireworks.current) { 54 | fireworks.current = new FireworksJs(container.current!, options) 55 | } 56 | 57 | if (autostart) { 58 | fireworks.current.start() 59 | } 60 | 61 | return () => { 62 | fireworks.current!.stop() 63 | } 64 | }, []) 65 | 66 | return ( 67 |
71 | {children} 72 |
73 | ) 74 | } 75 | ) 76 | 77 | export { Fireworks } 78 | export default Fireworks 79 | export type { FireworksProps, FireworksHandlers, FireworksOptions } 80 | -------------------------------------------------------------------------------- /packages/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "types": [ 5 | "vite/client" 6 | ] 7 | }, 8 | "include": [ 9 | "src" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react' 2 | import { resolve } from 'path' 3 | import { defineConfig } from 'vite' 4 | import banner from 'vite-plugin-banner' 5 | import dts from 'vite-plugin-dts' 6 | import { author, homepage, license, name, version } from './package.json' 7 | 8 | export default defineConfig({ 9 | plugins: [ 10 | react({ jsxRuntime: 'classic' }), 11 | dts({ insertTypesEntry: true }), 12 | banner( 13 | `/**\n * name: ${name}` + 14 | `\n * version: ${version}` + 15 | `\n * author: ${author.name} (${author.url})` + 16 | `\n * homepage: ${homepage}` + 17 | `\n * license ${license}\n */` 18 | )], 19 | esbuild: { 20 | banner: '"use client";' 21 | }, 22 | build: { 23 | target: 'esnext', 24 | lib: { 25 | entry: resolve(__dirname, 'src/index.tsx'), 26 | name: 'Fireworks', 27 | formats: [ 28 | 'es', 29 | 'cjs', 30 | 'umd' 31 | ], 32 | fileName: (format) => `index.${format}.js` 33 | }, 34 | rollupOptions: { 35 | external: ['react', 'fireworks-js'], 36 | output: { 37 | exports: 'named', 38 | globals: { 39 | react: 'React', 40 | 'fireworks-js': 'Fireworks' 41 | } 42 | } 43 | } 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /packages/solid/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/solid 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/solid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/solid", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "main": "./dist/index.cjs.js", 9 | "jsdelivr": "./dist/index.umd.js", 10 | "unpkg": "./dist/index.umd.js", 11 | "module": "./dist/index.es.js", 12 | "exports": { 13 | "require": "./dist/index.cjs.js", 14 | "import": "./dist/index.es.js", 15 | "types": "./dist/index.d.ts" 16 | }, 17 | "files": [ 18 | "dist" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 23 | }, 24 | "keywords": [ 25 | "solid-js", 26 | "canvas", 27 | "fireworks", 28 | "animation" 29 | ], 30 | "author": { 31 | "name": "Vitalij Ryndin", 32 | "email": "sys@crashmax.ru", 33 | "url": "https://crashmax.ru" 34 | }, 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 38 | }, 39 | "scripts": { 40 | "dev": "vite build --watch", 41 | "build": "vite build", 42 | "prepublishOnly": "pnpm build" 43 | }, 44 | "dependencies": { 45 | "fireworks-js": "workspace:2.10.7", 46 | "solid-js": "^1.6.1" 47 | }, 48 | "devDependencies": { 49 | "solid-js": "1.4.7", 50 | "vite-plugin-solid": "2.3.10" 51 | }, 52 | "peerDependencies": { 53 | "solid-js": ">=1.0.0" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/solid/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { Fireworks as FireworksJS } from 'fireworks-js' 2 | import { mergeProps, onCleanup, onMount } from 'solid-js' 3 | import type { FireworksHandlers, FireworksOptions } from 'fireworks-js' 4 | import type { JSX, ParentComponent } from 'solid-js' 5 | 6 | interface FireworksProps 7 | extends Omit, 'ref'> { 8 | options?: FireworksOptions 9 | autostart?: boolean 10 | ref?: (handlers: FireworksHandlers) => void 11 | } 12 | 13 | const Fireworks: ParentComponent = (props) => { 14 | const { autostart, options, children, ref, ...rest } = mergeProps( 15 | { autostart: true }, 16 | props 17 | ) 18 | let container: HTMLDivElement | undefined 19 | let fireworks: FireworksJS | undefined 20 | 21 | onMount(() => { 22 | fireworks = new FireworksJS(container!, options) 23 | if (autostart) { 24 | fireworks.start() 25 | } 26 | 27 | if (ref) { 28 | ref(fireworks) 29 | } 30 | 31 | onCleanup(() => { 32 | fireworks!.stop() 33 | }) 34 | }) 35 | 36 | return ( 37 |
41 | {children} 42 |
43 | ) 44 | } 45 | 46 | export { Fireworks } 47 | export default Fireworks 48 | export type { FireworksOptions, FireworksHandlers } 49 | -------------------------------------------------------------------------------- /packages/solid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "jsxImportSource": "solid-js", 6 | "outDir": "dist", 7 | "types": [ 8 | "vite/client" 9 | ] 10 | }, 11 | "include": [ 12 | "src" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/solid/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { defineConfig } from 'vite' 3 | import banner from 'vite-plugin-banner' 4 | import dts from 'vite-plugin-dts' 5 | import solid from 'vite-plugin-solid' 6 | import { author, homepage, license, name, version } from './package.json' 7 | 8 | export default defineConfig({ 9 | plugins: [ 10 | solid(), 11 | dts({ insertTypesEntry: true }), 12 | banner( 13 | `/**\n * name: ${name}` + 14 | `\n * version: ${version}` + 15 | `\n * author: ${author.name} (${author.url})` + 16 | `\n * homepage: ${homepage}` + 17 | `\n * license ${license}\n */` 18 | )], 19 | build: { 20 | target: 'esnext', 21 | polyfillModulePreload: false, 22 | lib: { 23 | entry: resolve(__dirname, 'src/index.tsx'), 24 | name: 'Fireworks', 25 | formats: [ 26 | 'es', 27 | 'cjs', 28 | 'umd' 29 | ], 30 | fileName: (format) => `index.${format}.js` 31 | }, 32 | rollupOptions: { 33 | external: ['solid-js', 'fireworks-js'], 34 | output: { 35 | exports: 'named', 36 | globals: { 37 | 'solid-js': 'Solid', 38 | 'fireworks-js': 'Fireworks' 39 | } 40 | } 41 | } 42 | } 43 | }) 44 | -------------------------------------------------------------------------------- /packages/svelte/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/svelte 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | 5 | ## Installation 6 | 7 | ```sh 8 | npm install @fireworks-js/svelte 9 | ``` 10 | 11 | ## Usage 12 | 13 | #### [`fireworks-js`](https://github.com/crashmax-dev/fireworks-js/tree/master/examples/with-svelte) 14 | 15 | ```svelte 16 | 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /packages/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/svelte", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "svelte": "./dist/index.js", 9 | "files": [ 10 | "dist" 11 | ], 12 | "exports": { 13 | "./package.json": "./package.json", 14 | "./fireworks.svelte": "./dist/fireworks.svelte", 15 | ".": "./dist/index.js" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 20 | }, 21 | "keywords": [ 22 | "svelte", 23 | "canvas", 24 | "fireworks", 25 | "animation" 26 | ], 27 | "author": { 28 | "name": "Vitalij Ryndin", 29 | "email": "sys@crashmax.ru", 30 | "url": "https://crashmax.ru" 31 | }, 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 35 | }, 36 | "scripts": { 37 | "dev": "vite dev --port 8081 --open", 38 | "build": "svelte-kit sync && svelte-package && del-cli dist/package.json dist/README.md", 39 | "prepublishOnly": "pnpm build" 40 | }, 41 | "dependencies": { 42 | "fireworks-js": "workspace:2.10.7" 43 | }, 44 | "devDependencies": { 45 | "@sveltejs/adapter-auto": "1.0.0-next.86", 46 | "@sveltejs/kit": "1.0.0-next.531", 47 | "@sveltejs/package": "1.0.0-next.5", 48 | "svelte": "^3.52.0", 49 | "svelte-check": "^2.9.2", 50 | "svelte-preprocess": "^4.10.6", 51 | "tslib": "^2.4.1", 52 | "typescript": "^4.7.4", 53 | "vite": "^3.2.2" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/svelte/src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // See https://kit.svelte.dev/docs/types#app 4 | // for information about these interfaces 5 | // and what to do when importing types 6 | declare namespace App { 7 | // interface Locals {} 8 | // interface PageData {} 9 | // interface Error {} 10 | // interface Platform {} 11 | } 12 | -------------------------------------------------------------------------------- /packages/svelte/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | @fireworks-js/svelte 8 | %sveltekit.head% 9 | 10 | 11 |
%sveltekit.body%
12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/svelte/src/lib/fireworks.svelte: -------------------------------------------------------------------------------- 1 | 32 | 33 |
38 | 39 |
40 | -------------------------------------------------------------------------------- /packages/svelte/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | import { default as Fireworks } from './fireworks.svelte' 2 | import type { FireworksOptions } from 'fireworks-js' 3 | 4 | export { Fireworks } 5 | export default Fireworks 6 | export type { FireworksOptions } 7 | -------------------------------------------------------------------------------- /packages/svelte/src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 34 | 35 |
36 |
37 | 40 | 43 | 50 |
51 | 52 |
53 | 54 | 71 | -------------------------------------------------------------------------------- /packages/svelte/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/packages/svelte/static/favicon.png -------------------------------------------------------------------------------- /packages/svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto' 2 | import preprocess from 'svelte-preprocess' 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://github.com/sveltejs/svelte-preprocess 7 | // for more information about preprocessors 8 | preprocess: preprocess(), 9 | kit: { 10 | adapter: adapter() 11 | }, 12 | package: { 13 | dir: 'dist' 14 | } 15 | } 16 | 17 | export default config 18 | -------------------------------------------------------------------------------- /packages/svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/svelte/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite' 2 | import type { UserConfig } from 'vite' 3 | 4 | const config: UserConfig = { 5 | plugins: [sveltekit()] 6 | } 7 | 8 | export default config 9 | -------------------------------------------------------------------------------- /packages/vue/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/vue 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/vue", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "main": "./dist/index.umd.js", 9 | "module": "./dist/index.es.js", 10 | "jsdelivr": "./dist/index.umd.js", 11 | "unpkg": "./dist/index.umd.js", 12 | "files": [ 13 | "dist" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 18 | }, 19 | "keywords": [ 20 | "vue", 21 | "canvas", 22 | "fireworks", 23 | "animation" 24 | ], 25 | "author": { 26 | "name": "Vitalij Ryndin", 27 | "email": "sys@crashmax.ru", 28 | "url": "https://crashmax.ru" 29 | }, 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 33 | }, 34 | "scripts": { 35 | "dev": "vite build --watch", 36 | "build": "del-cli dist && vite build && pnpm types", 37 | "types": "vue-tsc --declaration --emitDeclarationOnly", 38 | "prepublishOnly": "pnpm build" 39 | }, 40 | "dependencies": { 41 | "fireworks-js": "workspace:2.10.7" 42 | }, 43 | "devDependencies": { 44 | "@vitejs/plugin-vue": "3.2.0", 45 | "vue": "3.2.41", 46 | "vue-tsc": "1.0.9" 47 | }, 48 | "peerDependencies": { 49 | "vue": ">=3.0.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/vue/src/fireworks.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 72 | -------------------------------------------------------------------------------- /packages/vue/src/index.ts: -------------------------------------------------------------------------------- 1 | import Fireworks from './fireworks.vue' 2 | 3 | export { Fireworks } 4 | export default Fireworks 5 | export type { FireworksOptions } from 'fireworks-js' 6 | -------------------------------------------------------------------------------- /packages/vue/src/shim.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /packages/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "outDir": "dist", 6 | "noEmitOnError": false 7 | }, 8 | "include": [ 9 | "src" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import { resolve } from 'path' 3 | import { defineConfig } from 'vite' 4 | import banner from 'vite-plugin-banner' 5 | import { author, homepage, license, name, version } from './package.json' 6 | 7 | export default defineConfig({ 8 | plugins: [ 9 | vue(), 10 | banner( 11 | `/**\n * name: ${name}` + 12 | `\n * version: ${version}` + 13 | `\n * author: ${author.name} (${author.url})` + 14 | `\n * homepage: ${homepage}` + 15 | `\n * license ${license}\n */` 16 | ) 17 | ], 18 | build: { 19 | target: 'esnext', 20 | lib: { 21 | entry: resolve(__dirname, 'src/index.ts'), 22 | name: 'Fireworks', 23 | formats: [ 24 | 'es', 25 | 'cjs', 26 | 'umd' 27 | ], 28 | fileName: (format) => `index.${format}.js` 29 | }, 30 | rollupOptions: { 31 | external: ['vue', 'fireworks-js'], 32 | output: { 33 | exports: 'named', 34 | globals: { 35 | vue: 'Vue', 36 | 'fireworks-js': 'Fireworks' 37 | } 38 | } 39 | } 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /packages/web/README.md: -------------------------------------------------------------------------------- 1 | # @fireworks-js/web 2 | 3 | > https://github.com/crashmax-dev/fireworks-js 4 | -------------------------------------------------------------------------------- /packages/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fireworks-js/web", 3 | "version": "2.10.7", 4 | "type": "module", 5 | "description": "A simple fireworks library!", 6 | "homepage": "https://fireworks.js.org", 7 | "types": "./dist/index.d.ts", 8 | "main": "./dist/index.cjs.js", 9 | "jsdelivr": "./dist/index.umd.js", 10 | "unpkg": "./dist/index.umd.js", 11 | "module": "./dist/index.es.js", 12 | "exports": { 13 | "require": "./dist/index.cjs.js", 14 | "import": "./dist/index.es.js", 15 | "types": "./dist/index.d.ts" 16 | }, 17 | "files": [ 18 | "dist" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/crashmax-dev/fireworks-js.git" 23 | }, 24 | "keywords": [ 25 | "web-components", 26 | "fireworks", 27 | "animation" 28 | ], 29 | "author": { 30 | "name": "Vitalij Ryndin", 31 | "email": "sys@crashmax.ru", 32 | "url": "https://crashmax.ru" 33 | }, 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/crashmax-dev/fireworks-js/issues" 37 | }, 38 | "scripts": { 39 | "dev": "vite build --watch", 40 | "build": "del-cli dist && vite build && tsc", 41 | "prepublishOnly": "pnpm build" 42 | }, 43 | "dependencies": { 44 | "fireworks-js": "workspace:2.10.7" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/web/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Fireworks as FireworksJs } from 'fireworks-js' 2 | import type { FireworksOptions } from 'fireworks-js' 3 | 4 | class Fireworks extends HTMLElement { 5 | fireworks: FireworksJs 6 | private options: FireworksOptions = {} 7 | 8 | static get observedAttributes() { 9 | return ['options', 'style'] 10 | } 11 | 12 | constructor() { 13 | super() 14 | 15 | const shadowRoot = this.attachShadow({ mode: 'open' }) 16 | const div = document.createElement('div') 17 | const style = document.createElement('style') 18 | shadowRoot.append(style, div) 19 | 20 | this.attributeChangedCallback() 21 | } 22 | 23 | connectedCallback(): void { 24 | if (!this.isConnected) return 25 | 26 | const container = this.shadowRoot!.querySelector('div') 27 | if (!this.fireworks && container) { 28 | this.fireworks = new FireworksJs(container, this.options) 29 | this.fireworks.start() 30 | } 31 | } 32 | 33 | disconnectedCallback(): void { 34 | this.fireworks.stop() 35 | } 36 | 37 | attributeChangedCallback() { 38 | const options = this.getAttribute('options') 39 | if (options) { 40 | try { 41 | this.options = JSON.parse(options) 42 | this.fireworks?.updateOptions(this.options) 43 | } catch (err) { 44 | console.error('Attribute `options` failed parsed:', err) 45 | } 46 | } 47 | 48 | const style = this.getAttribute('style') 49 | if (style) { 50 | this.shadowRoot!.querySelector('style')!.textContent = `div { ${style} }` 51 | } 52 | } 53 | } 54 | 55 | declare global { 56 | interface HTMLElementTagNameMap { 57 | 'fireworks-js': Fireworks 58 | } 59 | } 60 | 61 | customElements.define('fireworks-js', Fireworks) 62 | 63 | export { Fireworks } 64 | export default Fireworks 65 | export type { FireworksOptions } 66 | -------------------------------------------------------------------------------- /packages/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "compilerOptions": { 4 | "emitDeclarationOnly": true, 5 | "outDir": "dist", 6 | "types": [ 7 | "vite/client" 8 | ] 9 | }, 10 | "include": [ 11 | "src" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { defineConfig } from 'vite' 3 | import banner from 'vite-plugin-banner' 4 | import dts from 'vite-plugin-dts' 5 | import { author, homepage, license, name, version } from './package.json' 6 | 7 | export default defineConfig({ 8 | plugins: [ 9 | dts({ insertTypesEntry: true }), 10 | banner( 11 | `/**\n * name: ${name}` + 12 | `\n * version: ${version}` + 13 | `\n * author: ${author.name} (${author.url})` + 14 | `\n * homepage: ${homepage}` + 15 | `\n * license ${license}\n */` 16 | ) 17 | ], 18 | build: { 19 | target: 'esnext', 20 | lib: { 21 | entry: resolve(__dirname, 'src/index.ts'), 22 | name: 'fireworks-js', 23 | formats: [ 24 | 'es', 25 | 'cjs', 26 | 'umd' 27 | ], 28 | fileName: (format) => `index.${format}.js` 29 | }, 30 | rollupOptions: { 31 | output: { 32 | exports: 'named' 33 | } 34 | } 35 | } 36 | }) 37 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'website' 3 | - 'examples/*' 4 | - 'packages/*' 5 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.org/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": [ 6 | "^build" 7 | ], 8 | "outputs": [ 9 | "dist/**", 10 | ".svelte-kit/**", 11 | ".angular/**" 12 | ] 13 | }, 14 | "dev": { 15 | "dependsOn": [ 16 | "^build" 17 | ], 18 | "cache": false 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fireworks-js 8 | 10 | 11 | 12 | 13 | 14 | 16 |
17 |
🎆
18 |

fireworks-js

19 |

A simple fireworks library!

20 | 21 | Visit on GitHub 22 | 23 |
24 |
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "private": true, 4 | "version": "0.0.0", 5 | "homepage": "https://fireworks.js.org", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build" 9 | }, 10 | "dependencies": { 11 | "@r3-dev/brand": "1.2.0", 12 | "@tweakpane/core": "1.1.4", 13 | "@tweakpane/plugin-essentials": "0.1.7", 14 | "fireworks-js": "workspace:*", 15 | "tweakpane": "3.1.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /website/public/CNAME: -------------------------------------------------------------------------------- 1 | fireworks.js.org -------------------------------------------------------------------------------- /website/public/images/fireworks_banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/website/public/images/fireworks_banner.gif -------------------------------------------------------------------------------- /website/public/images/fireworks_emoji.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/website/public/images/fireworks_emoji.gif -------------------------------------------------------------------------------- /website/public/images/fireworks_emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/website/public/images/fireworks_emoji.png -------------------------------------------------------------------------------- /website/public/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', 3 | 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 4 | line-height: 1; 5 | user-select: none; 6 | overscroll-behavior: none; 7 | } 8 | 9 | .container { 10 | position: fixed; 11 | width: 240px; 12 | height: inherit; 13 | background: hsla(0, 0%, 10%, 1); 14 | top: 50%; 15 | left: 50%; 16 | margin: -120px 0 0 -120px; 17 | padding: 20px; 18 | border-radius: 4px; 19 | box-sizing: border-box; 20 | font-size: 20px; 21 | z-index: 1; 22 | opacity: 0.9; 23 | line-height: initial; 24 | } 25 | 26 | .container div { 27 | text-align: center; 28 | font-size: 3rem; 29 | } 30 | 31 | .container h1 { 32 | font-size: 1.8em; 33 | text-align: center; 34 | color: #ffffff; 35 | margin: 0; 36 | } 37 | 38 | .container h2 { 39 | font-weight: 400; 40 | font-size: 16px; 41 | margin-bottom: 10px; 42 | text-align: center; 43 | color: #ffffff; 44 | } 45 | 46 | .container a { 47 | width: 100%; 48 | text-align: center; 49 | line-height: 36px; 50 | background: #ffffff; 51 | margin-top: 10px; 52 | color: #222; 53 | border-radius: 4px; 54 | display: inline-block; 55 | font-size: 16px; 56 | font-weight: 500; 57 | transition-duration: 0.1s; 58 | text-decoration: none; 59 | } 60 | 61 | .container a:hover { 62 | transition: ease-in color; 63 | background: #222; 64 | color: hsla(0, 0%, 70%, 1); 65 | } 66 | 67 | .fireworks-container { 68 | position: fixed; 69 | left: 0; 70 | top: 0; 71 | width: 100%; 72 | height: 100%; 73 | background: #000000; 74 | } 75 | 76 | .fireworks-container > canvas { 77 | cursor: crosshair; 78 | } 79 | 80 | :root { 81 | --tp-base-background-color: hsla(0, 0%, 0%, 0.75); 82 | --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2); 83 | --tp-button-background-color: hsla(0, 0%, 70%, 1); 84 | --tp-button-background-color-active: hsla(0, 0%, 85%, 1); 85 | --tp-button-background-color-focus: hsla(0, 0%, 80%, 1); 86 | --tp-button-background-color-hover: hsla(0, 0%, 75%, 1); 87 | --tp-button-foreground-color: hsla(0, 0%, 0%, 1); 88 | --tp-container-background-color: hsla(0, 0%, 10%, 1); 89 | --tp-container-background-color-active: hsla(0, 0%, 25%, 1); 90 | --tp-container-background-color-focus: hsla(0, 0%, 20%, 1); 91 | --tp-container-background-color-hover: hsla(0, 0%, 15%, 1); 92 | --tp-container-foreground-color: hsla(0, 0%, 50%, 1); 93 | --tp-groove-foreground-color: hsla(0, 0%, 10%, 1); 94 | --tp-input-background-color: hsla(0, 0%, 10%, 1); 95 | --tp-input-background-color-active: hsla(0, 0%, 25%, 1); 96 | --tp-input-background-color-focus: hsla(0, 0%, 20%, 1); 97 | --tp-input-background-color-hover: hsla(0, 0%, 15%, 1); 98 | --tp-input-foreground-color: hsla(0, 0%, 70%, 1); 99 | --tp-label-foreground-color: hsla(0, 0%, 50%, 1); 100 | --tp-monitor-background-color: hsla(0, 0%, 8%, 1); 101 | --tp-monitor-foreground-color: hsla(0, 0%, 48%, 1); 102 | } 103 | 104 | :root .tp-dfwv { 105 | padding-bottom: 8px; 106 | width: 350px !important; 107 | z-index: 1; 108 | } 109 | -------------------------------------------------------------------------------- /website/public/sounds/explosion0.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/website/public/sounds/explosion0.mp3 -------------------------------------------------------------------------------- /website/public/sounds/explosion1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/website/public/sounds/explosion1.mp3 -------------------------------------------------------------------------------- /website/public/sounds/explosion2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/fireworks-js/8c15ac042fdafee69fd724e59bb2bb01a32230df/website/public/sounds/explosion2.mp3 -------------------------------------------------------------------------------- /website/src/config.ts: -------------------------------------------------------------------------------- 1 | import type { FireworksOptions } from 'fireworks-js' 2 | 3 | export const mainContainer = 4 | document.querySelector('.container')! 5 | 6 | export const fireworksContainer = document.querySelector( 7 | '.fireworks-container' 8 | )! 9 | 10 | export const fireworksOptions: FireworksOptions = { 11 | hue: { 12 | min: 0, 13 | max: 345 14 | }, 15 | delay: { 16 | min: 30, 17 | max: 60 18 | }, 19 | rocketsPoint: { 20 | min: 50, 21 | max: 50 22 | }, 23 | opacity: 0.5, // fillStyle 24 | acceleration: 1.02, 25 | friction: 0.97, 26 | gravity: 1.5, 27 | particles: 60, 28 | traceLength: 3, 29 | traceSpeed: 10, 30 | explosion: 5, 31 | intensity: 30, 32 | flickering: 50, 33 | lineStyle: 'round', 34 | lineWidth: { 35 | explosion: { 36 | min: 1, 37 | max: 4 38 | }, 39 | trace: { 40 | min: 0.1, 41 | max: 1 42 | } 43 | }, 44 | brightness: { 45 | min: 50, 46 | max: 80 47 | }, 48 | decay: { 49 | min: 0.015, 50 | max: 0.03 51 | }, 52 | boundaries: { 53 | x: 50, 54 | y: 50, 55 | width: fireworksContainer.clientWidth, 56 | height: fireworksContainer.clientHeight 57 | }, 58 | sound: { 59 | enabled: false, 60 | files: [ 61 | location.href + 'sounds/explosion0.mp3', 62 | location.href + 'sounds/explosion1.mp3', 63 | location.href + 'sounds/explosion2.mp3' 64 | ], 65 | volume: { 66 | min: 2, 67 | max: 4 68 | } 69 | }, 70 | mouse: { 71 | click: true, 72 | move: false, 73 | max: 1 74 | } 75 | } 76 | 77 | export const backgroundConfig = { 78 | color: '#000000', 79 | image: '', 80 | size: 'cover', 81 | position: '50% 50%', 82 | repeat: 'no-repeat', 83 | container: false, 84 | fps: false 85 | } 86 | -------------------------------------------------------------------------------- /website/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as EssentialsPlugin from '@tweakpane/plugin-essentials' 2 | import { Fireworks } from 'fireworks-js' 3 | import { Pane } from 'tweakpane' 4 | import { 5 | backgroundConfig, 6 | fireworksContainer, 7 | fireworksOptions, 8 | mainContainer 9 | } from './config.js' 10 | import type { FpsGraphBladeApi } from '@tweakpane/plugin-essentials/dist/types/fps-graph/api/fps-graph' 11 | import '@r3-dev/brand' 12 | 13 | declare global { 14 | interface Window { 15 | fireworks: Fireworks 16 | } 17 | } 18 | 19 | const fireworks = new Fireworks(fireworksContainer, fireworksOptions) 20 | window.fireworks = fireworks 21 | fireworks.start() 22 | 23 | const fireworksGetters = { 24 | get traces(): number { 25 | // @ts-ignore 26 | return fireworks.traces.length 27 | }, 28 | get particles(): number { 29 | // @ts-ignore 30 | return fireworks.explosions.length 31 | } 32 | } 33 | 34 | const isPcWidth = window.innerWidth > 1000 35 | const tweakpane = new Pane({ 36 | document, 37 | expanded: isPcWidth, 38 | title: document.title 39 | }) 40 | 41 | tweakpane.registerPlugin(EssentialsPlugin) 42 | 43 | tweakpane.on('fold', ({ expanded }) => { 44 | if (isPcWidth) return 45 | mainContainer.style.display = expanded ? 'none' : 'block' 46 | }) 47 | 48 | /** options */ 49 | tweakpane.addInput(fireworksOptions, 'hue', { 50 | min: 0, 51 | max: 360, 52 | step: 1 53 | }) 54 | 55 | tweakpane.addInput(fireworksOptions, 'acceleration', { 56 | min: 1, 57 | max: 2 58 | }) 59 | 60 | tweakpane.addInput(fireworksOptions, 'brightness', { 61 | min: 1, 62 | max: 100, 63 | step: 1 64 | }) 65 | 66 | tweakpane.addInput(fireworksOptions, 'decay', { 67 | min: 0.001, 68 | max: 0.05 69 | }) 70 | 71 | tweakpane.addInput(fireworksOptions, 'delay', { 72 | min: 10, 73 | max: 100 74 | }) 75 | 76 | tweakpane.addInput(fireworksOptions, 'explosion', { 77 | min: 1, 78 | max: 10, 79 | step: 1 80 | }) 81 | 82 | tweakpane.addInput(fireworksOptions, 'flickering', { 83 | min: 0, 84 | max: 100 85 | }) 86 | 87 | tweakpane.addInput(fireworksOptions, 'intensity', { 88 | min: 1, 89 | max: 60 90 | }) 91 | 92 | tweakpane.addInput(fireworksOptions, 'friction', { 93 | min: 0.5, 94 | max: 3 95 | }) 96 | 97 | tweakpane.addInput(fireworksOptions, 'gravity', { 98 | min: 0, 99 | max: 10 100 | }) 101 | 102 | tweakpane.addInput(fireworksOptions, 'opacity', { 103 | min: 0, 104 | max: 1, 105 | step: 0.1 106 | }) 107 | 108 | tweakpane.addInput(fireworksOptions, 'particles', { 109 | step: 1, 110 | min: 1, 111 | max: 200 112 | }) 113 | 114 | tweakpane.addInput(fireworksOptions, 'traceLength', { 115 | min: 1, 116 | max: 10 117 | }) 118 | 119 | tweakpane.addInput(fireworksOptions, 'traceSpeed', { 120 | min: 1, 121 | max: 100, 122 | step: 1 123 | }) 124 | 125 | tweakpane.addInput(fireworksOptions, 'rocketsPoint', { 126 | min: 0, 127 | max: 100, 128 | step: 1 129 | }) 130 | 131 | tweakpane.addInput(fireworksOptions.lineWidth!, 'explosion', { 132 | label: 'lineWidth (explosion)', 133 | min: 0, 134 | max: 10 135 | }) 136 | 137 | tweakpane.addInput(fireworksOptions.lineWidth!, 'trace', { 138 | label: 'lineWidth (trace)', 139 | min: 0, 140 | max: 10 141 | }) 142 | 143 | tweakpane.addInput(fireworksOptions, 'lineStyle', { 144 | options: { 145 | round: 'round', 146 | square: 'square' 147 | } 148 | }) 149 | 150 | /** mouse events */ 151 | const mouse = tweakpane.addFolder({ 152 | title: 'mouse', 153 | expanded: false 154 | }) 155 | 156 | mouse.addInput(fireworksOptions.mouse!, 'click', { 157 | label: 'mouse click' 158 | }) 159 | 160 | mouse.addInput(fireworksOptions.mouse!, 'max', { 161 | label: 'maximum rockets', 162 | min: 1, 163 | max: 15, 164 | step: 1 165 | }) 166 | 167 | mouse.addInput(fireworksOptions.mouse!, 'move', { 168 | label: 'follow mouse' 169 | }) 170 | 171 | /** sounds */ 172 | const sound = tweakpane.addFolder({ 173 | title: 'sound', 174 | expanded: false 175 | }) 176 | 177 | sound.addInput(fireworksOptions.sound!, 'enabled') 178 | 179 | sound.addInput(fireworksOptions.sound!, 'volume', { 180 | min: 0, 181 | max: 100, 182 | step: 1 183 | }) 184 | 185 | tweakpane.on('change', () => { 186 | fireworks.updateOptions(fireworksOptions) 187 | }) 188 | 189 | /** background */ 190 | const background = tweakpane.addFolder({ 191 | title: 'background', 192 | expanded: false 193 | }) 194 | 195 | background.addInput(backgroundConfig, 'container').on('change', ({ value }) => { 196 | mainContainer.style.display = value ? 'none' : 'block' 197 | }) 198 | 199 | background.addInput(backgroundConfig, 'color').on('change', ({ value }) => { 200 | fireworksContainer.style.backgroundColor = value 201 | }) 202 | 203 | background.addInput(backgroundConfig, 'image').on('change', ({ value }) => { 204 | fireworksContainer.style.backgroundImage = `url(${value})` 205 | }) 206 | 207 | background.addInput(backgroundConfig, 'size').on('change', ({ value }) => { 208 | fireworksContainer.style.backgroundSize = value 209 | }) 210 | 211 | background.addInput(backgroundConfig, 'position').on('change', ({ value }) => { 212 | fireworksContainer.style.backgroundPosition = value 213 | }) 214 | 215 | background.addInput(backgroundConfig, 'repeat').on('change', ({ value }) => { 216 | fireworksContainer.style.backgroundRepeat = value 217 | }) 218 | 219 | /** monitors */ 220 | const monitors = tweakpane.addFolder({ 221 | title: 'monitors', 222 | expanded: false 223 | }) 224 | 225 | const fpsGraph = monitors.addBlade({ 226 | view: 'fpsgraph', 227 | label: 'fps' 228 | }) as FpsGraphBladeApi 229 | 230 | monitors.addMonitor(fireworksGetters, 'particles', { 231 | view: 'graph', 232 | label: 'particles', 233 | min: 0, 234 | max: 5000 235 | }) 236 | 237 | monitors.addMonitor(fireworksGetters, 'traces', { 238 | view: 'graph', 239 | label: 'traces', 240 | min: 0, 241 | max: 50 242 | }) 243 | 244 | const updateGraph = () => { 245 | fpsGraph.begin() 246 | fpsGraph.end() 247 | requestAnimationFrame(updateGraph) 248 | } 249 | 250 | requestAnimationFrame(updateGraph) 251 | 252 | /** fullscreen */ 253 | declare global { 254 | interface Element { 255 | webkitRequestFullscreen?(): void 256 | mozRequestFullScreen?(): void 257 | msRequestFullscreen?(): void 258 | } 259 | } 260 | 261 | document.addEventListener('keydown', (event) => { 262 | if (event.code === 'F11') { 263 | event.preventDefault() 264 | 265 | if (fireworksContainer.requestFullscreen) { 266 | fireworksContainer.requestFullscreen() 267 | } else if (fireworksContainer.webkitRequestFullscreen) { 268 | fireworksContainer.webkitRequestFullscreen() 269 | } else if (fireworksContainer.mozRequestFullScreen) { 270 | fireworksContainer.mozRequestFullScreen() 271 | } else if (fireworksContainer.msRequestFullscreen) { 272 | fireworksContainer.msRequestFullscreen() 273 | } 274 | } 275 | }) 276 | -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@crashmax/tsconfig", 3 | "include": [ 4 | "src" 5 | ] 6 | } 7 | --------------------------------------------------------------------------------