Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@neoconfetti/svelte

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@neoconfetti/svelte - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0

dist/min/index.js

67

dist/index.d.ts

@@ -1,60 +0,4 @@

/**
* Actions can return an object containing the two properties defined in this interface. Both are optional.
* - update: An action can have a parameter. This method will be called whenever that parameter changes,
* immediately after Svelte has applied updates to the markup.
* - destroy: Method that is called after the element is unmounted
*
* Additionally, you can specify which additional attributes and events the action enables on the applied element.
* This applies to TypeScript typings only and has no effect at runtime.
*
* Example usage:
* ```ts
* interface Attributes {
* newprop?: string;
* 'on:event': (e: CustomEvent<boolean>) => void;
* }
*
* export function myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes> {
* // ...
* return {
* update: (updatedParameter) => {...},
* destroy: () => {...}
* };
* }
* ```
*
* Docs: https://svelte.dev/docs#template-syntax-element-directives-use-action
*/
interface ActionReturn<Parameter = any, Attributes extends Record<string, any> = Record<never, any>> {
update?: (parameter: Parameter) => void;
destroy?: () => void;
type ParticleShape = 'mix' | 'circles' | 'rectangles';
type ConfettiOptions = {
/**
* ### DO NOT USE THIS
* This exists solely for type-checking and has no effect at runtime.
* Set this through the `Attributes` generic instead.
*/
$$_attributes?: Attributes;
}
/**
* Actions are functions that are called when an element is created.
* You can use this interface to type such actions.
* The following example defines an action that only works on `<div>` elements
* and optionally accepts a parameter which it has a default value for:
* ```ts
* export const myAction: Action<HTMLDivElement, { someProperty: boolean }> = (node, param = { someProperty: true }) => {
* // ...
* }
* ```
* You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has.
* See interface `ActionReturn` for more details.
*
* Docs: https://svelte.dev/docs#template-syntax-element-directives-use-action
*/
interface Action<Element = HTMLElement, Parameter = any, Attributes extends Record<string, any> = Record<never, any>> {
<Node extends Element>(node: Node, parameter?: Parameter): void | ActionReturn<Parameter, Attributes>;
}
declare type ParticleShape = 'mix' | 'circles' | 'rectangles';
declare type ConfettiOptions = {
/**
* Number of confetti particles to create

@@ -119,4 +63,7 @@ *

};
declare const confetti: Action<HTMLElement, ConfettiOptions>;
declare function confetti(node: HTMLElement, options?: ConfettiOptions): {
update(newOptions: ConfettiOptions): void;
destroy(): void;
};
export { ConfettiOptions, ParticleShape as ConfettiParticleShape, confetti };
export { type ConfettiOptions, type ParticleShape as ConfettiParticleShape, confetti };

@@ -1,2 +0,159 @@

const t=(t,b={})=>{w(b);let{colors:k=["#FFC700","#FF0000","#2E3191","#41BBC7"],duration:W=3500,force:S=.5,particleCount:G=150,particleShape:X="mix",particleSize:_=12,destroyAfterDone:C=!0,stageHeight:z=800,stageWidth:E=1600}=b;!function(t){const e=f("style");e.dataset.neoconfetti="",e.textContent='@keyframes fk9XWG_y-axis{to{transform:translate3d(0,var(--stage-height),0)}}@keyframes fk9XWG_x-axis{to{transform:translate3d(var(--x-landing-point),0,0)}}@keyframes fk9XWG_rotation{50%{transform:rotate3d(var(--half-rotation),180deg)}to{transform:rotate3d(var(--rotation),360deg)}}.fk9XWG_container{width:0;height:0;z-index:1200;position:relative;overflow:visible}.fk9XWG_particle{animation:x-axis var(--duration-chaos)forwards cubic-bezier(var(--x1),var(--x2),var(--x3),var(--x4));animation-name:fk9XWG_x-axis}.fk9XWG_particle>div{animation:y-axis var(--duration-chaos)forwards cubic-bezier(var(--y1),var(--y2),var(--y3),var(--y4));width:var(--width);height:var(--height);animation-name:fk9XWG_y-axis;position:absolute;top:0;left:0}.fk9XWG_particle>div:before{height:100%;width:100%;content:"";background-color:var(--bgcolor);animation:rotation var(--rotation-duration)infinite linear;border-radius:var(--border-radius);animation-name:fk9XWG_rotation;display:block}',h(document.head,e)}(),t.classList.add("fk9XWG_container"),t.style.setProperty("--stage-height",z+"px");let P,A=p(G,k),H=e(t,A);function M(t,e){const f=l(c()*(x-1)),h="rectangles"!==X&&("circles"===X||v(f)),p=(e,r)=>t.style.setProperty(e,r+"");p("--x-landing-point",u(s(m(e,90)-180),0,180,-E/2,E/2)+"px"),p("--duration-chaos",W-l(1e3*c())+"ms");const b=c()<a?g(c()*i,2):0;p("--x1",b),p("--x2",-1*b),p("--x3",b),p("--x4",g(s(u(s(m(e,90)-180),0,180,-1,1)),4)),p("--y1",g(c()*n,4)),p("--y2",g(c()*S*(y()?1:-1),4)),p("--y3",n),p("--y4",g(d(u(s(e-180),0,180,S,-S),0),4)),p("--width",(h?_:l(4*c())+_/2)+"px"),p("--height",(h?_:l(2*c())+_)+"px");const k=f.toString(2).padStart(3,"0").split("");p("--half-rotation",k.map((t=>+t/2+""))),p("--rotation",k),p("--rotation-duration",g(c()*(o-r)+r)+"ms"),p("--border-radius",h?"50%":0)}for(const[t,e]of Object.entries(H))M(e,A[+t].degree);return Promise.resolve().then((()=>P=setTimeout((()=>C&&(t.innerHTML="")),W))),{update(r){w(r);const o=r.particleCount??G,a=r.colors??k,i=r.stageHeight??z;if(A=p(o,a),o===G&&JSON.stringify(k)!==JSON.stringify(a))for(const[t,{color:e}]of Object.entries(A))H[+t].style.setProperty("--bgcolor",e);o!==G&&(t.innerHTML="",H=e(t,A)),C&&!r.destroyAfterDone&&clearTimeout(P),t.style.setProperty("--stage-height",i+"px"),k=a,W=r.duration??W,S=r.force??S,G=o,X=r.particleShape??X,_=r.particleSize??_,C=r.destroyAfterDone??C,z=i,E=r.stageWidth??E},destroy(){clearTimeout(P)}}};function e(t,e=[]){const r=[];for(const{color:o}of e){const e=f("div");e.className="fk9XWG_particle",e.style.setProperty("--bgcolor",o);const a=f("div");h(e,a),h(t,e),r.push(e)}return r}const r=200,o=800,a=.1,i=.3,n=.5,s=Math.abs,c=Math.random,l=Math.round,d=Math.max,f=t=>document.createElement(t),h=(t,e)=>t.appendChild(e),p=(t,e)=>Array.from({length:t},((r,o)=>({color:e[o%e.length],degree:360*o/t}))),g=(t,e=2)=>l((t+Number.EPSILON)*10**e)/10**e,u=(t,e,r,o,a)=>(t-e)*(a-o)/(r-e)+o,m=(t,e)=>t+e>360?t+e-360:t+e,y=()=>c()>.5,x=6,v=t=>1!==t&&y(),b=t=>void 0===t,k=(t,e)=>{if(!b(t)&&Number.isSafeInteger(t)&&t<0)throw new Error(e+" must be a positive integer")},w=({particleCount:t,duration:e,colors:r,particleSize:o,force:a,stageHeight:i,stageWidth:n,particleShape:s})=>{if(k(t,"particleCount"),k(e,"duration"),k(o,"particleSize"),k(a,"force"),k(i,"stageHeight"),k(n,"stageWidth"),!b(s)&&!/^(mix|circles|rectangles)$/i.test(s))throw new Error('particlesShape should be either "mix" or "circles" or "rectangle"');if(!b(r)&&!Array.isArray(r))throw new Error("colors must be an array of strings");if(a>1)throw new Error("force must be within 0 and 1")};export{t as confetti};
//# sourceMappingURL=index.js.map
// ../core/dist/index.js
var style_module_default = '@keyframes Bc2PgW_y-axis{to{translate:0 var(--sh)}}@keyframes Bc2PgW_x-axis{to{translate:var(--xlp)0}}@keyframes Bc2PgW_rotation{50%{rotate:var(--hr)180deg}to{rotate:var(--r)360deg}}.Bc2PgW_container{z-index:1200;width:0;height:0;position:relative;overflow:visible}.Bc2PgW_particle{animation:x-axis var(--dc)forwards cubic-bezier(var(--x1),var(--x2),var(--x3),var(--x4));animation-name:Bc2PgW_x-axis}.Bc2PgW_particle>div{animation:y-axis var(--dc)forwards cubic-bezier(var(--y1),var(--y2),var(--y3),var(--y4));width:var(--w);height:var(--h);animation-name:Bc2PgW_y-axis;position:absolute;top:0;left:0}.Bc2PgW_particle>div:before{content:"";background-color:var(--bgc);animation:rotation var(--rd)infinite linear;border-radius:var(--br);width:100%;height:100%;animation-name:Bc2PgW_rotation;display:block}';
var particle = "Bc2PgW_particle";
var container = "Bc2PgW_container";
function confetti(node, options = {}) {
let {
colors = ["#FFC700", "#FF0000", "#2E3191", "#41BBC7"],
duration = 3500,
force = 0.5,
particleCount = 150,
particleShape = "mix",
particleSize = 12,
destroyAfterDone = true,
stageHeight = 800,
stageWidth = 1600
} = options;
appendStyles(style_module_default);
node.classList.add(container);
node.style.setProperty("--sh", stageHeight + "px");
let particles = createParticles(particleCount, colors);
let nodes = createParticleNodes(node, particles);
function confettiStyles(node2, degree) {
const rotationTransform = mathRound(random() * (POSSIBLE_ROTATION_TRANSFORMS - 1));
const isCircle = particleShape !== "rectangles" && (particleShape === "circles" || shouldBeCircle(rotationTransform));
const setCSSVar = (key, val) => node2.style.setProperty(key, val + "");
setCSSVar(
// x landing point
"--xlp",
mapRange(abs(rotate(degree, 90) - 180), 0, 180, -stageWidth / 2, stageWidth / 2) + "px"
);
setCSSVar(
// duration chaos
"--dc",
duration - mathRound(random() * 1e3) + "ms"
);
const x1 = random() < CRAZY_PARTICLES_FREQUENCY ? round(random() * CRAZY_PARTICLE_CRAZINESS, 2) : 0;
setCSSVar("--x1", x1);
setCSSVar("--x2", x1 * -1);
setCSSVar("--x3", x1);
setCSSVar("--x4", round(abs(mapRange(abs(rotate(degree, 90) - 180), 0, 180, -1, 1)), 4));
setCSSVar("--y1", round(random() * BEZIER_MEDIAN, 4));
setCSSVar("--y2", round(random() * force * (coinFlip() ? 1 : -1), 4));
setCSSVar("--y3", BEZIER_MEDIAN);
setCSSVar("--y4", round(max(mapRange(abs(degree - 180), 0, 180, force, -force), 0), 4));
setCSSVar(
// --width
"--w",
(isCircle ? particleSize : mathRound(random() * 4) + particleSize / 2) + "px"
);
setCSSVar(
// --height
"--h",
(isCircle ? particleSize : mathRound(random() * 2) + particleSize) + "px"
);
const rotation = rotationTransform.toString(2).padStart(3, "0").split("");
setCSSVar(
// --half-rotation
"--hr",
rotation.map((n) => +n / 2 + "").join(" ")
);
setCSSVar(
// --rotation
"--r",
rotation.join(" ")
);
setCSSVar(
// --rotation-duration
"--rd",
round(random() * (ROTATION_SPEED_MAX - ROTATION_SPEED_MIN) + ROTATION_SPEED_MIN) + "ms"
);
setCSSVar(
// --border-radius
"--br",
isCircle ? "50%" : 0
);
}
for (const [i, node2] of Object.entries(nodes))
confettiStyles(node2, particles[+i].degree);
let timer;
Promise.resolve().then(
() => timer = setTimeout(() => destroyAfterDone && (node.innerHTML = ""), duration)
);
return {
update(newOptions) {
const newParticleCount = newOptions.particleCount ?? particleCount;
const newColors = newOptions.colors ?? colors;
const newStageHeight = newOptions.stageHeight ?? stageHeight;
particles = createParticles(newParticleCount, newColors);
if (newParticleCount === particleCount && JSON.stringify(colors) !== JSON.stringify(newColors))
for (const [i, { color }] of Object.entries(particles))
nodes[+i].style.setProperty(
// bgcolor
"--bgc",
color
);
if (newParticleCount !== particleCount) {
node.innerHTML = "";
nodes = createParticleNodes(node, particles);
}
if (destroyAfterDone && !newOptions.destroyAfterDone)
clearTimeout(timer);
node.style.setProperty("--sh", newStageHeight + "px");
colors = newColors;
duration = newOptions.duration ?? duration;
force = newOptions.force ?? force;
particleCount = newParticleCount;
particleShape = newOptions.particleShape ?? particleShape;
particleSize = newOptions.particleSize ?? particleSize;
destroyAfterDone = newOptions.destroyAfterDone ?? destroyAfterDone;
stageHeight = newStageHeight;
stageWidth = newOptions.stageWidth ?? stageWidth;
},
destroy() {
clearTimeout(timer);
}
};
}
function appendStyles(styles) {
const style = element("style");
style.dataset.neoconfetti = "";
style.textContent = styles;
appendChild(document.head, style);
}
function createParticleNodes(node, particles = []) {
const particleNodes = [];
for (const { color } of particles) {
const particleNode = element("div");
particleNode.className = particle;
particleNode.style.setProperty("--bgc", color);
const innerParticle = element("div");
appendChild(particleNode, innerParticle);
appendChild(node, particleNode);
particleNodes.push(particleNode);
}
return particleNodes;
}
var ROTATION_SPEED_MIN = 200;
var ROTATION_SPEED_MAX = 800;
var CRAZY_PARTICLES_FREQUENCY = 0.1;
var CRAZY_PARTICLE_CRAZINESS = 0.3;
var BEZIER_MEDIAN = 0.5;
var abs = Math.abs;
var random = Math.random;
var mathRound = Math.round;
var max = Math.max;
var element = (name) => document.createElement(name);
var appendChild = (parent, child) => parent.appendChild(child);
var createParticles = (count, colors) => Array.from({ length: count }, (_, i) => ({
color: colors[i % colors.length],
degree: i * 360 / count
}));
var round = (num, precision = 2) => mathRound((num + Number.EPSILON) * 10 ** precision) / 10 ** precision;
var mapRange = (value, x1, y1, x2, y2) => (value - x1) * (y2 - x2) / (y1 - x1) + x2;
var rotate = (degree, amount) => degree + amount > 360 ? degree + amount - 360 : degree + amount;
var coinFlip = () => random() > 0.5;
var POSSIBLE_ROTATION_TRANSFORMS = 6;
var shouldBeCircle = (rotationTransform) => rotationTransform !== 1 && coinFlip();
export { confetti };
{
"name": "@neoconfetti/svelte",
"version": "1.0.0",
"version": "2.0.0",
"description": "Confetti explosion in Svelte 🎉🎊",

@@ -43,11 +43,11 @@ "author": "Puru Vijay",

"devDependencies": {
"@neoconfetti/core": "1.0.0"
"@neoconfetti/core": "2.0.0"
},
"scripts": {
"dev": "rollup -cw",
"build": "rollup -c ",
"compile:watch": "tsup --watch",
"compile": "tsup",
"size": "echo 'Svelte size:' && brotli-size dist/min/index.js",
"pub": "pnpm build && pnpm publish --no-git-checks --access public",
"pub:dry": "pnpm build && pnpm publish --dry-run --no-git-checks --access public",
"size": "echo 'Svelte size:' && brotli-size dist/index.js"
"pub:dry": "pnpm build && pnpm publish --dry-run --no-git-checks --access public"
}
}

@@ -77,3 +77,3 @@ # @neoconfetti/svelte

```svelte
<div use:confetti={{ particleSize:20 }} />
<div use:confetti={{ particleSize: 20 }} />
```

@@ -169,3 +169,3 @@

### shouldDestroyAfterDone
### destroyAfterDone

@@ -172,0 +172,0 @@ Whether or not destroy all confetti nodes after the `duration` period has passed. By default it destroys all nodes, to free up memory.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc