@cos-design/fireworks 3.5.3 → 3.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});require('./index.css');var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("react");c=s(c,1);let l=require("@cos-design/shared"),u=require("react/jsx-runtime");var d={fireworks:`cos-fireworks-fsSqL`,canvas:`cos-canvas-spL8G`,hint:`cos-hint-5XDRH`},f=[`#ff6b6b`,`#ffd93d`,`#6bcb77`,`#4d96ff`,`#a66cff`,`#ff85c0`],p=.12,m=240,h=()=>f[Math.floor(Math.random()*f.length)],g=(e,t,n)=>{let r=60+Math.floor(Math.random()*30);return Array.from({length:r},()=>{let r=Math.random()*Math.PI*2,i=Math.random()*4+2;return{x:e,y:t,vx:Math.cos(r)*i,vy:Math.sin(r)*i,alpha:1,color:Math.random()>.3?n:h(),decay:Math.random()*.015+.01}})},_=(0,c.forwardRef)(({width:e=800,height:t=500,auto:n=!0},r)=>{let i=(0,c.useRef)(null),a=(0,c.useRef)([]),o=(0,c.useRef)(0),s=(0,c.useCallback)(n=>{let r=n??Math.random()*e*.6+e*.2;a.current.push({x:r,y:t,vy:-(Math.random()*4+6),targetY:Math.random()*t*.35+t*.15,color:h(),exploded:!1,particles:[],age:0})},[t,e]);return(0,c.useImperativeHandle)(r,()=>({launch:s}),[s]),(0,c.useEffect)(()=>{let r=i.current;if(!r)return;let c=window.devicePixelRatio||1;r.width=e*c,r.height=t*c;let u=r.getContext(`2d`);if(!u)return;u.setTransform(c,0,0,c,0,0);let d=0,f=document.hidden,h=(0,l.bindVisibilityPause)(e=>{f=e}),_=()=>{o.current=requestAnimationFrame(_),!f&&(u.fillStyle=`rgb(15 23 42 / 25%)`,u.fillRect(0,0,e,t),a.current=a.current.filter(e=>{if(!e.exploded){e.age+=1,e.y+=e.vy,e.vy+=p,u.beginPath(),u.arc(e.x,e.y,2.5,0,Math.PI*2),u.fillStyle=e.color,u.fill();let t=e.vy>=0,n=e.y<=e.targetY,r=e.y<0,i=e.age>=m;return(t||n||r||i)&&(e.exploded=!0,e.particles=g(e.x,e.y,e.color)),!0}return e.particles=e.particles.filter(e=>(e.x+=e.vx,e.y+=e.vy,e.vy+=.06,e.alpha-=e.decay,e.alpha<=0?!1:(u.beginPath(),u.arc(e.x,e.y,2,0,Math.PI*2),u.fillStyle=e.color,u.globalAlpha=e.alpha,u.fill(),u.globalAlpha=1,!0))),e.particles.length>0}))};return _(),n&&(d=window.setInterval(()=>s(),1200)),()=>{cancelAnimationFrame(o.current),clearInterval(d),h()}},[n,t,s,e]),(0,u.jsxs)(`div`,{className:d.fireworks,style:{width:e,height:t},children:[(0,u.jsx)(`canvas`,{ref:i,className:d.canvas,style:{width:e,height:t},onClick:e=>{let t=e.currentTarget.getBoundingClientRect();s(e.clientX-t.left)}}),(0,u.jsx)(`p`,{className:d.hint,children:`点击画布燃放烟花`})]})});_.displayName=`Fireworks`,exports.Fireworks=_,exports.default=_;
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});require('./index.css');var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("react");c=s(c,1);let l=require("@cos-design/shared"),u=require("react/jsx-runtime");var d={fireworks:`cos-fireworks-fsSqL`,canvas:`cos-canvas-spL8G`,hint:`cos-hint-5XDRH`},f=[`#ff6b6b`,`#ffd93d`,`#6bcb77`,`#4d96ff`,`#a66cff`,`#ff85c0`],p=.12,m=240,h=()=>f[Math.floor(Math.random()*f.length)],g=(e,t,n)=>{let r=60+Math.floor(Math.random()*30);return Array.from({length:r},()=>{let r=Math.random()*Math.PI*2,i=Math.random()*4+2;return{x:e,y:t,vx:Math.cos(r)*i,vy:Math.sin(r)*i,alpha:1,color:Math.random()>.3?n:h(),decay:Math.random()*.015+.01}})},_=(0,c.forwardRef)((e,t)=>{let{width:n,height:r,fill:i=!1,auto:a=!0,hint:o=`点击画布燃放烟花`,onComplete:s}=e,f=(0,c.useRef)(null),{width:_,height:v}=(0,l.resolveCanvasBoxSize)({fill:i,width:n,height:r,defaultWidth:800,defaultHeight:500,measured:(0,l.useElementSize)(f,{enabled:i})}),y=(0,c.useRef)(null),b=(0,c.useRef)([]),x=(0,c.useRef)(0),S=(0,c.useRef)(!1),C=(0,c.useRef)(s);(0,c.useEffect)(()=>{C.current=s},[s]);let w=(0,c.useCallback)(e=>{let t=e??Math.random()*_*.6+_*.2;b.current.push({x:t,y:v,vy:-(Math.random()*4+6),targetY:Math.random()*v*.35+v*.15,color:h(),exploded:!1,particles:[],age:0}),S.current=!0},[v,_]);return(0,c.useImperativeHandle)(t,()=>({launch:w}),[w]),(0,c.useEffect)(()=>{let e=y.current;if(!e)return;let t=window.devicePixelRatio||1;e.width=_*t,e.height=v*t;let n=e.getContext(`2d`);if(!n)return;n.setTransform(t,0,0,t,0,0);let r=0,i=document.hidden,o=(0,l.prefersReducedMotion)(),s=(0,l.bindVisibilityPause)(e=>{i=e}),c=(0,l.bindPrefersReducedMotion)(e=>{o=e}),u=()=>{if(x.current=requestAnimationFrame(u),!i){if(n.fillStyle=`rgb(15 23 42 / 25%)`,n.fillRect(0,0,_,v),o){S.current&&b.current.length===0&&(S.current=!1,C.current?.());return}b.current=b.current.filter(e=>{if(!e.exploded){e.age+=1,e.y+=e.vy,e.vy+=p,n.beginPath(),n.arc(e.x,e.y,2.5,0,Math.PI*2),n.fillStyle=e.color,n.fill();let t=e.vy>=0,r=e.y<=e.targetY,i=e.y<0,a=e.age>=m;return(t||r||i||a)&&(e.exploded=!0,e.particles=g(e.x,e.y,e.color)),!0}return e.particles=e.particles.filter(e=>(e.x+=e.vx,e.y+=e.vy,e.vy+=.06,e.alpha-=e.decay,e.alpha<=0?!1:(n.beginPath(),n.arc(e.x,e.y,2,0,Math.PI*2),n.fillStyle=e.color,n.globalAlpha=e.alpha,n.fill(),n.globalAlpha=1,!0))),e.particles.length>0}),S.current&&b.current.length===0&&(S.current=!1,C.current?.())}};return u(),a&&!o?r=window.setInterval(()=>w(),1200):a&&o&&w(),()=>{cancelAnimationFrame(x.current),clearInterval(r),s(),c()}},[a,v,w,_]),(0,u.jsxs)(`div`,{ref:f,className:d.fireworks,style:i?{width:`100%`,height:`100%`}:{width:_,height:v},children:[(0,u.jsx)(`canvas`,{ref:y,className:d.canvas,style:{width:_,height:v,touchAction:`none`},onPointerDown:e=>{let t=(0,l.getRelativePointerPosition)(e.currentTarget,e.nativeEvent);t&&w(t.x)}}),(0,u.jsx)(`p`,{className:d.hint,children:o})]})});_.displayName=`Fireworks`,exports.Fireworks=_,exports.default=_;
package/dist/index.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { forwardRef as e, useCallback as t, useEffect as n, useImperativeHandle as r, useRef as i } from "react";
2
- import { bindVisibilityPause as a } from "@cos-design/shared";
3
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import './index.css';var c = {
2
+ import { bindPrefersReducedMotion as a, bindVisibilityPause as o, getRelativePointerPosition as s, prefersReducedMotion as c, resolveCanvasBoxSize as l, useElementSize as u } from "@cos-design/shared";
3
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
4
+ import './index.css';var p = {
5
5
  fireworks: "cos-fireworks-fsSqL",
6
6
  canvas: "cos-canvas-spL8G",
7
7
  hint: "cos-hint-5XDRH"
8
- }, l = [
8
+ }, m = [
9
9
  "#ff6b6b",
10
10
  "#ffd93d",
11
11
  "#6bcb77",
12
12
  "#4d96ff",
13
13
  "#a66cff",
14
14
  "#ff85c0"
15
- ], u = .12, d = 240, f = () => l[Math.floor(Math.random() * l.length)], p = (e, t, n) => {
15
+ ], h = .12, g = 240, _ = () => m[Math.floor(Math.random() * m.length)], v = (e, t, n) => {
16
16
  let r = 60 + Math.floor(Math.random() * 30);
17
17
  return Array.from({ length: r }, () => {
18
18
  let r = Math.random() * Math.PI * 2, i = Math.random() * 4 + 2;
@@ -22,75 +22,99 @@ import './index.css';var c = {
22
22
  vx: Math.cos(r) * i,
23
23
  vy: Math.sin(r) * i,
24
24
  alpha: 1,
25
- color: Math.random() > .3 ? n : f(),
25
+ color: Math.random() > .3 ? n : _(),
26
26
  decay: Math.random() * .015 + .01
27
27
  };
28
28
  });
29
- }, m = e(({ width: e = 800, height: l = 500, auto: m = !0 }, h) => {
30
- let g = i(null), _ = i([]), v = i(0), y = t((t) => {
31
- let n = t ?? Math.random() * e * .6 + e * .2;
32
- _.current.push({
33
- x: n,
34
- y: l,
29
+ }, y = e((e, m) => {
30
+ let { width: y, height: b, fill: x = !1, auto: S = !0, hint: C = "点击画布燃放烟花", onComplete: w } = e, T = i(null), { width: E, height: D } = l({
31
+ fill: x,
32
+ width: y,
33
+ height: b,
34
+ defaultWidth: 800,
35
+ defaultHeight: 500,
36
+ measured: u(T, { enabled: x })
37
+ }), O = i(null), k = i([]), A = i(0), j = i(!1), M = i(w);
38
+ n(() => {
39
+ M.current = w;
40
+ }, [w]);
41
+ let N = t((e) => {
42
+ let t = e ?? Math.random() * E * .6 + E * .2;
43
+ k.current.push({
44
+ x: t,
45
+ y: D,
35
46
  vy: -(Math.random() * 4 + 6),
36
- targetY: Math.random() * l * .35 + l * .15,
37
- color: f(),
47
+ targetY: Math.random() * D * .35 + D * .15,
48
+ color: _(),
38
49
  exploded: !1,
39
50
  particles: [],
40
51
  age: 0
41
- });
42
- }, [l, e]);
43
- return r(h, () => ({ launch: y }), [y]), n(() => {
44
- let t = g.current;
45
- if (!t) return;
46
- let n = window.devicePixelRatio || 1;
47
- t.width = e * n, t.height = l * n;
48
- let r = t.getContext("2d");
49
- if (!r) return;
50
- r.setTransform(n, 0, 0, n, 0, 0);
51
- let i = 0, o = document.hidden, s = a((e) => {
52
- o = e;
53
- }), c = () => {
54
- v.current = requestAnimationFrame(c), !o && (r.fillStyle = "rgb(15 23 42 / 25%)", r.fillRect(0, 0, e, l), _.current = _.current.filter((e) => {
55
- if (!e.exploded) {
56
- e.age += 1, e.y += e.vy, e.vy += u, r.beginPath(), r.arc(e.x, e.y, 2.5, 0, Math.PI * 2), r.fillStyle = e.color, r.fill();
57
- let t = e.vy >= 0, n = e.y <= e.targetY, i = e.y < 0, a = e.age >= d;
58
- return (t || n || i || a) && (e.exploded = !0, e.particles = p(e.x, e.y, e.color)), !0;
52
+ }), j.current = !0;
53
+ }, [D, E]);
54
+ return r(m, () => ({ launch: N }), [N]), n(() => {
55
+ let e = O.current;
56
+ if (!e) return;
57
+ let t = window.devicePixelRatio || 1;
58
+ e.width = E * t, e.height = D * t;
59
+ let n = e.getContext("2d");
60
+ if (!n) return;
61
+ n.setTransform(t, 0, 0, t, 0, 0);
62
+ let r = 0, i = document.hidden, s = c(), l = o((e) => {
63
+ i = e;
64
+ }), u = a((e) => {
65
+ s = e;
66
+ }), d = () => {
67
+ if (A.current = requestAnimationFrame(d), !i) {
68
+ if (n.fillStyle = "rgb(15 23 42 / 25%)", n.fillRect(0, 0, E, D), s) {
69
+ j.current && k.current.length === 0 && (j.current = !1, M.current?.());
70
+ return;
59
71
  }
60
- return e.particles = e.particles.filter((e) => (e.x += e.vx, e.y += e.vy, e.vy += .06, e.alpha -= e.decay, e.alpha <= 0 ? !1 : (r.beginPath(), r.arc(e.x, e.y, 2, 0, Math.PI * 2), r.fillStyle = e.color, r.globalAlpha = e.alpha, r.fill(), r.globalAlpha = 1, !0))), e.particles.length > 0;
61
- }));
72
+ k.current = k.current.filter((e) => {
73
+ if (!e.exploded) {
74
+ e.age += 1, e.y += e.vy, e.vy += h, n.beginPath(), n.arc(e.x, e.y, 2.5, 0, Math.PI * 2), n.fillStyle = e.color, n.fill();
75
+ let t = e.vy >= 0, r = e.y <= e.targetY, i = e.y < 0, a = e.age >= g;
76
+ return (t || r || i || a) && (e.exploded = !0, e.particles = v(e.x, e.y, e.color)), !0;
77
+ }
78
+ return e.particles = e.particles.filter((e) => (e.x += e.vx, e.y += e.vy, e.vy += .06, e.alpha -= e.decay, e.alpha <= 0 ? !1 : (n.beginPath(), n.arc(e.x, e.y, 2, 0, Math.PI * 2), n.fillStyle = e.color, n.globalAlpha = e.alpha, n.fill(), n.globalAlpha = 1, !0))), e.particles.length > 0;
79
+ }), j.current && k.current.length === 0 && (j.current = !1, M.current?.());
80
+ }
62
81
  };
63
- return c(), m && (i = window.setInterval(() => y(), 1200)), () => {
64
- cancelAnimationFrame(v.current), clearInterval(i), s();
82
+ return d(), S && !s ? r = window.setInterval(() => N(), 1200) : S && s && N(), () => {
83
+ cancelAnimationFrame(A.current), clearInterval(r), l(), u();
65
84
  };
66
85
  }, [
67
- m,
68
- l,
69
- y,
70
- e
71
- ]), /* @__PURE__ */ s("div", {
72
- className: c.fireworks,
73
- style: {
74
- width: e,
75
- height: l
86
+ S,
87
+ D,
88
+ N,
89
+ E
90
+ ]), /* @__PURE__ */ f("div", {
91
+ ref: T,
92
+ className: p.fireworks,
93
+ style: x ? {
94
+ width: "100%",
95
+ height: "100%"
96
+ } : {
97
+ width: E,
98
+ height: D
76
99
  },
77
- children: [/* @__PURE__ */ o("canvas", {
78
- ref: g,
79
- className: c.canvas,
100
+ children: [/* @__PURE__ */ d("canvas", {
101
+ ref: O,
102
+ className: p.canvas,
80
103
  style: {
81
- width: e,
82
- height: l
104
+ width: E,
105
+ height: D,
106
+ touchAction: "none"
83
107
  },
84
- onClick: (e) => {
85
- let t = e.currentTarget.getBoundingClientRect();
86
- y(e.clientX - t.left);
108
+ onPointerDown: (e) => {
109
+ let t = s(e.currentTarget, e.nativeEvent);
110
+ t && N(t.x);
87
111
  }
88
- }), /* @__PURE__ */ o("p", {
89
- className: c.hint,
90
- children: "点击画布燃放烟花"
112
+ }), /* @__PURE__ */ d("p", {
113
+ className: p.hint,
114
+ children: C
91
115
  })]
92
116
  });
93
117
  });
94
- m.displayName = "Fireworks";
118
+ y.displayName = "Fireworks";
95
119
  //#endregion
96
- export { m as Fireworks, m as default };
120
+ export { y as Fireworks, y as default };
@@ -1,3 +1,10 @@
1
- /** 注册 visibilitychange,页面隐藏时暂停动画循环 */
2
- export declare const bindVisibilityPause: (onChange: (paused: boolean) => void) => () => void;
3
- export declare const clamp: (value: number, min: number, max: number) => number;
1
+ export { clamp } from './math';
2
+ export { bindVisibilityPause } from './visibility';
3
+ export { prefersReducedMotion, bindPrefersReducedMotion } from './reduced-motion';
4
+ export { observeElementSize } from './size';
5
+ export type { ElementSize } from './size';
6
+ export { getRelativePointerPosition } from './pointer';
7
+ export type { PointerPosition } from './pointer';
8
+ export type { PhotoItem, PhotoIndexChangeHandler, PhotoFaceChangeHandler } from './photo';
9
+ export { useElementSize, resolveCanvasBoxSize } from './use-element-size';
10
+ export type { UseElementSizeOptions, CanvasBoxSizeInput, CanvasBoxSize } from './use-element-size';
@@ -0,0 +1 @@
1
+ export declare const clamp: (value: number, min: number, max: number) => number;
@@ -0,0 +1,15 @@
1
+ /** 图片预览组件通用照片项 */
2
+ export interface PhotoItem {
3
+ /** 图片地址 */
4
+ src: string;
5
+ /** 图片替代文本 */
6
+ alt?: string;
7
+ /** 照片标题 */
8
+ title?: string;
9
+ /** 照片说明 */
10
+ description?: string;
11
+ }
12
+ /** 线性浏览:当前索引变化(相册 / 胶卷 / 晾绳等) */
13
+ export type PhotoIndexChangeHandler<T = PhotoItem> = (index: number, photo: T) => void;
14
+ /** 环形浏览:正对镜头的面变化(走马灯 / 旋转木马等) */
15
+ export type PhotoFaceChangeHandler<T = PhotoItem> = (index: number, photo?: T) => void;
@@ -0,0 +1,14 @@
1
+ export interface PointerPosition {
2
+ x: number;
3
+ y: number;
4
+ }
5
+ type PointLike = {
6
+ clientX: number;
7
+ clientY: number;
8
+ };
9
+ /** 相对元素左上角的指针坐标(兼容 mouse / touch / pointer) */
10
+ export declare const getRelativePointerPosition: (element: Element, event: PointLike | {
11
+ touches?: ArrayLike<PointLike>;
12
+ changedTouches?: ArrayLike<PointLike>;
13
+ }) => PointerPosition | null;
14
+ export {};
@@ -0,0 +1,4 @@
1
+ /** 当前是否偏好减少动效 */
2
+ export declare const prefersReducedMotion: () => boolean;
3
+ /** 监听 prefers-reduced-motion 变化;返回取消订阅函数 */
4
+ export declare const bindPrefersReducedMotion: (onChange: (reduced: boolean) => void) => () => void;
@@ -0,0 +1,8 @@
1
+ export interface ElementSize {
2
+ width: number;
3
+ height: number;
4
+ }
5
+ /** 观察元素内容尺寸;返回取消订阅函数 */
6
+ export declare const observeElementSize: (element: Element, onChange: (size: ElementSize) => void, options?: {
7
+ box?: ResizeObserverBoxOptions;
8
+ }) => () => void;
@@ -0,0 +1,25 @@
1
+ import { RefObject } from 'react';
2
+ import { ElementSize } from './size';
3
+ export interface UseElementSizeOptions {
4
+ /** 为 false 时不观察 */
5
+ enabled?: boolean;
6
+ }
7
+ /** 观察元素尺寸(clientWidth / clientHeight) */
8
+ export declare const useElementSize: <T extends Element>(ref: RefObject<T | null>, options?: UseElementSizeOptions) => ElementSize;
9
+ export interface CanvasBoxSizeInput {
10
+ /** 为 true 时跟随父容器尺寸(需父级有明确高度) */
11
+ fill?: boolean;
12
+ width?: number;
13
+ height?: number;
14
+ defaultWidth: number;
15
+ defaultHeight: number;
16
+ measured: ElementSize;
17
+ }
18
+ export interface CanvasBoxSize {
19
+ width: number;
20
+ height: number;
21
+ /** 是否处于 fill 模式且尚未量到有效尺寸 */
22
+ pending: boolean;
23
+ }
24
+ /** 根据 fill / 显式宽高 / 测量结果解析画布逻辑尺寸 */
25
+ export declare const resolveCanvasBoxSize: ({ fill, width, height, defaultWidth, defaultHeight, measured }: CanvasBoxSizeInput) => CanvasBoxSize;
@@ -0,0 +1,2 @@
1
+ /** 注册 visibilitychange,页面隐藏时暂停动画循环 */
2
+ export declare const bindVisibilityPause: (onChange: (paused: boolean) => void) => () => void;
@@ -2,8 +2,14 @@ import { default as React } from 'react';
2
2
  export interface FireworksProps {
3
3
  width?: number;
4
4
  height?: number;
5
+ /** 为 true 时铺满父容器(父级需有明确高度) */
6
+ fill?: boolean;
5
7
  /** 是否自动燃放,默认 true */
6
8
  auto?: boolean;
9
+ /** 画布操作提示 */
10
+ hint?: string;
11
+ /** 画面空闲(无火箭/粒子)时回调 */
12
+ onComplete?: () => void;
7
13
  }
8
14
  export interface FireworksHandle {
9
15
  /** 手动燃放烟花,可指定 x 坐标 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cos-design/fireworks",
3
- "version": "3.5.3",
3
+ "version": "3.5.5",
4
4
  "description": "Fireworks component from cos-design",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -52,6 +52,6 @@
52
52
  "registry": "https://registry.npmjs.org"
53
53
  },
54
54
  "dependencies": {
55
- "@cos-design/shared": "3.5.3"
55
+ "@cos-design/shared": "3.5.5"
56
56
  }
57
57
  }