diff --git a/README.md b/README.md index 69ba290..bc6dc4b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ You can then `require('canvas-confetti');` to use it in your project build. _Not You can also include this library in your HTML page directly from a CDN: ```html - + ``` _Note: you should use the latest version at the time that you include your project. You can see all versions [on the releases page](https://github.com/catdad/canvas-confetti/releases)._ diff --git a/build/serve.js b/build/serve.js index 65be6af..8dd302d 100644 --- a/build/serve.js +++ b/build/serve.js @@ -2,6 +2,7 @@ const path = require('path'); const http = require('http'); const send = require('send'); const root = require('rootrequire'); +const { networkInterfaces } = require('os'); const PORT = 9001; @@ -25,7 +26,13 @@ http.createServer(function (req, res) { send(req, file).pipe(res); }).listen(PORT, () => { - console.log(`listening at http://localhost:${PORT}`); + console.log('listening at:'); + console.log(` http://localhost:${PORT}`); + + Object.values(networkInterfaces()) + .reduce((memo, value) => [...memo, ...value], []) + .filter(value => value.family === 'IPv4') + .forEach(({ address }) => console.log(` http://${address}:${PORT}`)); }); diff --git a/index.html b/index.html index 06ea0df..e2941f9 100644 --- a/index.html +++ b/index.html @@ -8,8 +8,9 @@ + - 🎊 + canvas confetti @@ -49,6 +50,10 @@ [data-theme="light"][auto-theme] { --theme-switch: var(--switch-auto-black); } + + html { + scroll-behavior: smooth; + } html, body { margin: 0; @@ -417,10 +422,10 @@

Realistic Look

-
+
-

Stars

+

Fireworks

- You can combine multiple calls to confetti with any settings in order to create - a more complex effect. Go ahead, combine different shapes, sizes, etc. Stagger them - for an extra boost of excitement. + Why click a button repeatedly when you can have code do it for you? Shoot some firework + of confetti from the sides of page so you can still read the content in the center.

-

✨ Celebrate with a burst of stars! ✨

@@ -442,10 +445,10 @@

Stars

-
+
-

Fireworks

+

Stars

- Why click a button repeatedly when you can have code do it for you? Shoot some firework - of confetti from the sides of page so you can still read the content in the center. + You can combine multiple calls to confetti with any settings in order to create + a more complex effect. Go ahead, combine different shapes, sizes, etc. Stagger them + for an extra boost of excitement.

+

✨ Celebrate with a burst of stars! ✨

@@ -859,10 +864,10 @@

Custom Canvas var defaults = { scalar: 2, - spread: 270, - particleCount: 25, - origin: { y: 0.4 }, - startVelocity: 35 + spread: 180, + particleCount: 30, + origin: { y: -0.1 }, + startVelocity: -35 }; confetti({ @@ -973,6 +978,21 @@

Custom Canvas }; + + diff --git a/package.json b/package.json index 07a2a3a..df632ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "canvas-confetti", - "version": "1.9.0", + "version": "1.9.1", "description": "performant confetti animation in the browser", "main": "src/confetti.js", "module": "dist/confetti.module.mjs", diff --git a/src/confetti.js b/src/confetti.js index 8228400..a67a345 100644 --- a/src/confetti.js +++ b/src/confetti.js @@ -1,3 +1,5 @@ +/* globals Map */ + (function main(global, module, isWorker, workerSize) { var canUseWorker = !!( global.Worker && @@ -11,6 +13,25 @@ global.URL.createObjectURL); var canUsePaths = typeof Path2D === 'function' && typeof DOMMatrix === 'function'; + var canDrawBitmap = (function () { + // this mostly supports ssr + if (!global.OffscreenCanvas) { + return false; + } + + var canvas = new OffscreenCanvas(1, 1); + var ctx = canvas.getContext('2d'); + ctx.fillRect(0, 0, 1, 1); + var bitmap = canvas.transferToImageBitmap(); + + try { + ctx.createPattern(bitmap, 'no-repeat'); + } catch (e) { + return false; + } + + return true; + })(); function noop() {} @@ -29,6 +50,36 @@ return null; } + var bitmapMapper = (function (skipTransform, map) { + // see https://github.com/catdad/canvas-confetti/issues/209 + // creating canvases is actually pretty expensive, so we should create a + // 1:1 map for bitmap:canvas, so that we can animate the confetti in + // a performant manner, but also not store them forever so that we don't + // have a memory leak + return { + transform: function(bitmap) { + if (skipTransform) { + return bitmap; + } + + if (map.has(bitmap)) { + return map.get(bitmap); + } + + var canvas = new OffscreenCanvas(bitmap.width, bitmap.height); + var ctx = canvas.getContext('2d'); + ctx.drawImage(bitmap, 0, 0); + + map.set(bitmap, canvas); + + return canvas; + }, + clear: function () { + map.clear(); + } + }; + })(canDrawBitmap, new Map()); + var raf = (function () { var TIME = Math.floor(1000 / 60); var frame, cancel; @@ -101,6 +152,9 @@ worker.removeEventListener('message', workerDone); prom = null; + + bitmapMapper.clear(); + done(); resolve(); } @@ -375,7 +429,7 @@ // apply the transform matrix from the confetti shape matrix.multiplySelf(new DOMMatrix(fetti.shape.matrix)); - var pattern = context.createPattern(fetti.shape.bitmap, 'no-repeat'); + var pattern = context.createPattern(bitmapMapper.transform(fetti.shape.bitmap), 'no-repeat'); pattern.setTransform(matrix); context.globalAlpha = (1 - progress); @@ -435,6 +489,7 @@ animationFrame = destroy = null; context.clearRect(0, 0, size.width, size.height); + bitmapMapper.clear(); done(); resolve();