@tremolo-ui/react 0.1.0-alpha.2 → 0.1.0

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.
@@ -1,13 +1,33 @@
1
- import { ComponentPropsWithoutRef, ReactElement, RefObject } from 'react';
1
+ import { ComponentPropsWithoutRef, ReactElement } from 'react';
2
2
  /** @category AnimationCanvas */
3
- export type DrawFunction = (context: CanvasRenderingContext2D, width: RefObject<number>, height: RefObject<number>, count: number) => void;
3
+ export type InitFunction = (context: CanvasRenderingContext2D, option: {
4
+ /** current canvas width */
5
+ width: number;
6
+ /** current canvas height */
7
+ height: number;
8
+ }) => void;
9
+ /** @category AnimationCanvas */
10
+ export type DrawFunction = (context: CanvasRenderingContext2D, option: {
11
+ /** current canvas width */
12
+ width: number;
13
+ /** current canvas height */
14
+ height: number;
15
+ /** frame count */
16
+ count: number;
17
+ /** delta time (ms) */
18
+ deltaTime: number;
19
+ /** elapsed time (ms) */
20
+ elapsedTime: number;
21
+ /** frame per second */
22
+ fps: number;
23
+ }) => void;
4
24
  /** @category AnimationCanvas */
5
25
  export interface CommonProps {
6
26
  /**
7
27
  * @see https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/getContext#contextattributes
8
28
  */
9
29
  options?: CanvasRenderingContext2DSettings;
10
- init?: DrawFunction;
30
+ init?: InitFunction;
11
31
  draw: DrawFunction;
12
32
  }
13
33
  /** @category AnimationCanvas */
@@ -21,11 +41,11 @@ export interface RelativeSizingProps {
21
41
  reduceFlickering?: boolean;
22
42
  }
23
43
  /** @category AnimationCanvas */
24
- export type AnimationCanvasProps = AbsoluteSizingProps & RelativeSizingProps & CommonProps;
44
+ export type AnimationCanvasProps = CommonProps & AbsoluteSizingProps & RelativeSizingProps;
25
45
  /**
26
46
  * A simple animatable canvas with requestAnimationFrame()
27
47
  * @category AnimationCanvas
28
48
  */
29
- export declare function AnimationCanvas(props: AbsoluteSizingProps & CommonProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>): ReactElement;
30
- export declare function AnimationCanvas(props: RelativeSizingProps & CommonProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>): ReactElement;
49
+ export declare function AnimationCanvas(props: CommonProps & AbsoluteSizingProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>): ReactElement;
50
+ export declare function AnimationCanvas(pros: CommonProps & RelativeSizingProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>): ReactElement;
31
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/AnimationCanvas/index.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,SAAS,EAIV,MAAM,OAAO,CAAA;AAkBd,gCAAgC;AAChC,MAAM,MAAM,YAAY,GAAG,CAGzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,EACxB,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,MAAM,KACV,IAAI,CAAA;AAET,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,gCAAgC,CAAA;IAC1C,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED,gCAAgC;AAChC,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GACpD,mBAAmB,GACnB,WAAW,CAAA;AAEb;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,mBAAmB,GACxB,WAAW,GACX,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,oBAAoB,CAAC,GACrE,YAAY,CAAA;AACf,wBAAgB,eAAe,CAC7B,KAAK,EAAE,mBAAmB,GACxB,WAAW,GACX,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,oBAAoB,CAAC,GACrE,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/AnimationCanvas/index.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,YAAY,EAKb,MAAM,OAAO,CAAA;AA2Bd,gCAAgC;AAChC,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE;IACN,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAA;CACf,KACE,IAAI,CAAA;AAET,gCAAgC;AAChC,MAAM,MAAM,YAAY,GAAG,CAGzB,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE;IACN,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAA;CACZ,KACE,IAAI,CAAA;AAET,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,gCAAgC,CAAA;IAC1C,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED,gCAAgC;AAChC,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAC5C,mBAAmB,GACnB,mBAAmB,CAAA;AAErB;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,GAChB,mBAAmB,GACnB,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,oBAAoB,CAAC,GACrE,YAAY,CAAA;AACf,wBAAgB,eAAe,CAC7B,IAAI,EAAE,WAAW,GACf,mBAAmB,GACnB,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,oBAAoB,CAAC,GACrE,YAAY,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/AnimationKnob/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,aAAa,EAKd,MAAM,OAAO,CAAA;AAEd,OAAO,EAML,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,EAAmB,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAElE,8BAA8B;AAC9B,MAAM,MAAM,kBAAkB,GAAG;IAE/B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IAGX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAA;IAE5B,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAA;IAE9B,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uBAAuB;IACvB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,IAAI,CAAC,EAAE,YAAY,CAAA;IAEnB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAClC,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAClC,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB;AAKD;;;GAGG;AACH,eAAO,MAAM,aAAa,8NA4NzB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/AnimationKnob/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,aAAa,EAKd,MAAM,OAAO,CAAA;AAEd,OAAO,EAML,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,EAAmB,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAElE,8BAA8B;AAC9B,MAAM,MAAM,kBAAkB,GAAG;IAE/B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IAGX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAA;IAE5B,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAA;IAE9B,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uBAAuB;IACvB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,IAAI,CAAC,EAAE,YAAY,CAAA;IAEnB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAClC,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAClC,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB;AAKD;;;GAGG;AACH,eAAO,MAAM,aAAa,8NA0NzB,CAAA"}
@@ -16,7 +16,7 @@ type State = {
16
16
  type Action = {
17
17
  notePosition: (note: number) => number;
18
18
  };
19
- type PianoProviderProps = React.PropsWithChildren<Partial<State>>;
19
+ type PianoProviderProps = React.PropsWithChildren<Partial<State> & Action>;
20
20
  export declare function PianoProvider({ children, ...props }: PianoProviderProps): import("react/jsx-runtime").JSX.Element;
21
21
  /** @category Piano */
22
22
  export declare function usePianoContext<T>(selector: (state: State & Action) => T): T;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../src/components/Piano/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAAiC,MAAM,OAAO,CAAA;AAO/E,sBAAsB;AACtB,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;CAClD,CAAA;AAED,KAAK,MAAM,GAAG;IACZ,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACvC,CAAA;AAsDD,KAAK,kBAAkB,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;AAEjE,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,2CAmBvE;AAED,sBAAsB;AACtB,wBAAgB,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAI5E"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../src/components/Piano/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAAiC,MAAM,OAAO,CAAA;AAG/E,sBAAsB;AACtB,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,KAAK,KAAK,GAAG;IACX,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;CAClD,CAAA;AAED,KAAK,MAAM,GAAG;IACZ,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACvC,CAAA;AAyBD,KAAK,kBAAkB,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAA;AAE1E,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,2CAmBvE;AAED,sBAAsB;AACtB,wBAAgB,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAI5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/Piano/index.tsx"],"names":[],"mappings":"AACA,OAAc,EACZ,wBAAwB,EAExB,aAAa,EACb,YAAY,EACZ,SAAS,EAOV,MAAM,OAAO,CAAA;AAad,OAAO,EAAE,SAAS,EAAiB,MAAM,WAAW,CAAA;AAQpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEvD;;;;;GAKG;AAEH,sBAAsB;AACtB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,YAKrD;AAED,sBAAsB;AACtB,MAAM,WAAW,UAAU;IAEzB,SAAS,EAAE,SAAS,CAAA;IAGpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAExB,KAAK,CAAC,EAAE,aAAa,CAAA;IAErB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IAEzC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;IAElD;;OAEG;IACH,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;CACzC;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EACpB,SAAS,EACT,SAAgB,EAChB,OAAa,EACb,iBAAiB,EACjB,IAAY,EACZ,MAA4B,EAC5B,cAAc,EAAE,eAAsC,EACtD,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,KAAK,EACL,QAAQ,EACR,aAAa,EACb,GAAG,KAAK,EACT,EAAE,UAAU,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,UAAU,CAAC,2CA+MtE;AAED,cAAc,qBAAqB,CAAA;AAEnC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/Piano/index.tsx"],"names":[],"mappings":"AACA,OAAc,EACZ,wBAAwB,EAExB,aAAa,EACb,YAAY,EACZ,SAAS,EAOV,MAAM,OAAO,CAAA;AAad,OAAO,EAAE,SAAS,EAAiB,MAAM,WAAW,CAAA;AAQpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEvD;;;;;GAKG;AAEH,sBAAsB;AACtB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,YAKrD;AAED,sBAAsB;AACtB,MAAM,WAAW,UAAU;IAEzB,SAAS,EAAE,SAAS,CAAA;IAGpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAExB,KAAK,CAAC,EAAE,aAAa,CAAA;IAErB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IAEzC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;IAElD;;OAEG;IACH,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;CACzC;AAID;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EACpB,SAAS,EACT,SAAgB,EAChB,OAAa,EACb,iBAAiB,EACjB,IAAY,EACZ,MAA4B,EAC5B,cAAc,EAAE,eAAsC,EACtD,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,KAAK,EACL,QAAQ,EACR,aAAa,EACb,GAAG,KAAK,EACT,EAAE,UAAU,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,UAAU,CAAC,2CAiNtE;AAED,cAAc,qBAAqB,CAAA;AAEnC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tremolo-ui/react",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0",
4
4
  "description": "React component library for audio app",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -10,6 +10,13 @@ import {
10
10
 
11
11
  import { DrawingContext, drawingState, DrawingStateValue } from './canvas'
12
12
 
13
+ /*
14
+ TODO
15
+ AbsoluteSizingProps, RelativeSizingPropsの型付けを強くする
16
+ AbsoluteSizingPropsの場合、width, heightは必須
17
+ RelativeSizingPropsのの場合、relativeSizeは必須、reduceFlickeringはオプショナル
18
+ */
19
+
13
20
  function setDprConfig(
14
21
  canvas: HTMLCanvasElement,
15
22
  context: CanvasRenderingContext2D,
@@ -19,19 +26,43 @@ function setDprConfig(
19
26
  ) {
20
27
  canvas.width = width * dpr
21
28
  canvas.height = height * dpr
29
+ // Reset current transformation matrix to the identity matrix
30
+ context.setTransform(1, 0, 0, 1, 0, 0)
22
31
  context.scale(dpr, dpr)
23
32
  canvas.style.width = `${width}px`
24
33
  canvas.style.height = `${height}px`
25
34
  }
26
35
 
36
+ /** @category AnimationCanvas */
37
+ export type InitFunction = (
38
+ context: CanvasRenderingContext2D,
39
+ option: {
40
+ /** current canvas width */
41
+ width: number
42
+ /** current canvas height */
43
+ height: number
44
+ },
45
+ ) => void
46
+
27
47
  /** @category AnimationCanvas */
28
48
  export type DrawFunction = (
29
49
  // TODO: saving scale and translate
30
50
  // context: Omit<CanvasRenderingContext2D, 'save' | 'restore' | 'scale'>,
31
51
  context: CanvasRenderingContext2D,
32
- width: RefObject<number>,
33
- height: RefObject<number>,
34
- count: number,
52
+ option: {
53
+ /** current canvas width */
54
+ width: number
55
+ /** current canvas height */
56
+ height: number
57
+ /** frame count */
58
+ count: number
59
+ /** delta time (ms) */
60
+ deltaTime: number
61
+ /** elapsed time (ms) */
62
+ elapsedTime: number
63
+ /** frame per second */
64
+ fps: number
65
+ },
35
66
  ) => void
36
67
 
37
68
  /** @category AnimationCanvas */
@@ -40,7 +71,7 @@ export interface CommonProps {
40
71
  * @see https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/getContext#contextattributes
41
72
  */
42
73
  options?: CanvasRenderingContext2DSettings
43
- init?: DrawFunction
74
+ init?: InitFunction
44
75
  draw: DrawFunction
45
76
  }
46
77
 
@@ -57,32 +88,36 @@ export interface RelativeSizingProps {
57
88
  }
58
89
 
59
90
  /** @category AnimationCanvas */
60
- export type AnimationCanvasProps = AbsoluteSizingProps &
61
- RelativeSizingProps &
62
- CommonProps
91
+ export type AnimationCanvasProps = CommonProps &
92
+ AbsoluteSizingProps &
93
+ RelativeSizingProps
63
94
 
64
95
  /**
65
96
  * A simple animatable canvas with requestAnimationFrame()
66
97
  * @category AnimationCanvas
67
98
  */
68
99
  export function AnimationCanvas(
69
- props: AbsoluteSizingProps &
70
- CommonProps &
100
+ props: CommonProps &
101
+ AbsoluteSizingProps &
71
102
  Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>,
72
103
  ): ReactElement
73
104
  export function AnimationCanvas(
74
- props: RelativeSizingProps &
75
- CommonProps &
105
+ pros: CommonProps &
106
+ RelativeSizingProps &
76
107
  Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>,
77
108
  ): ReactElement
78
109
  export function AnimationCanvas({
79
- width = 100,
80
- height = 100,
81
- relativeSize = false,
82
- reduceFlickering = true,
110
+ // common
83
111
  options,
84
112
  init,
85
113
  draw,
114
+ // absolute
115
+ width = 100,
116
+ height = 100,
117
+ // relative
118
+ relativeSize,
119
+ reduceFlickering = true,
120
+ // canvas props
86
121
  className,
87
122
  onContextMenu = (event) => event.preventDefault(),
88
123
  ...props
@@ -96,6 +131,8 @@ export function AnimationCanvas({
96
131
  const reqIdRef = useRef(-1)
97
132
  const widthRef = useRef(0)
98
133
  const heightRef = useRef(0)
134
+ const deltaMemoRef = useRef(-1)
135
+ const startTimeRef = useRef(-1)
99
136
 
100
137
  const loop = useCallback(
101
138
  (
@@ -104,10 +141,21 @@ export function AnimationCanvas({
104
141
  height: RefObject<number>,
105
142
  count: number,
106
143
  ) => {
144
+ const now = performance.now()
145
+ const deltaTime = now - deltaMemoRef.current
146
+ const elapsedTime = now - startTimeRef.current
147
+ deltaMemoRef.current = now
107
148
  reqIdRef.current = requestAnimationFrame(() =>
108
149
  loop(context, width, height, count + 1),
109
150
  )
110
- draw(context, width, height, count + 1)
151
+ draw(context, {
152
+ width: width.current,
153
+ height: height.current,
154
+ count: count + 1,
155
+ deltaTime,
156
+ elapsedTime,
157
+ fps: 1000 / deltaTime,
158
+ })
111
159
  },
112
160
  [draw],
113
161
  )
@@ -117,7 +165,7 @@ export function AnimationCanvas({
117
165
  const canvas = canvasRef.current
118
166
  const context = canvas.getContext('2d', options)
119
167
  if (!context) throw new Error('Cannot get canvas context.')
120
- const dpr = globalThis.window.devicePixelRatio
168
+ const dpr = globalThis.devicePixelRatio
121
169
 
122
170
  if (relativeSize) {
123
171
  const parent = canvas.parentElement
@@ -125,20 +173,16 @@ export function AnimationCanvas({
125
173
  const memoCanvas = memoCanvasRef.current
126
174
  const memoContext = memoCanvas?.getContext('2d', options)
127
175
 
128
- const resizeObserver = new ResizeObserver((entries) => {
129
- // TODO: If the parent element has no absolute height, the height increases infinitely.
130
- // : 親要素に絶対的な高さを持たない場合、高さは無限に増加します。
131
- // https://zenn.dev/megeton/articles/be1c677e174c84#%E6%A0%B9%E6%9C%AC%E7%9A%84%E3%81%AB-resizeobserver-loop-limit-exceeded-%E3%81%8C%E5%87%BA%E3%82%8B%E5%95%8F%E9%A1%8C%E3%81%AB%E5%90%91%E3%81%8D%E5%90%88%E3%81%86
176
+ const ro = new ResizeObserver((entries) => {
132
177
  for (const entry of entries) {
133
178
  // Prevents loss of some context when the canvas is resized
134
- // TODO: saving scale and translate
135
179
  const contextMemo = {} as DrawingContext
136
180
  for (const prop of drawingState) {
137
181
  ;(contextMemo[prop] as DrawingStateValue) = context[prop]
138
182
  }
139
183
 
140
- const w = Math.floor(entry.contentRect.width)
141
- const h = Math.floor(entry.contentRect.height)
184
+ const w = entry.contentRect.width
185
+ const h = entry.contentRect.height
142
186
 
143
187
  if (reduceFlickering && memoCanvas && memoContext) {
144
188
  memoCanvas.width = w * dpr
@@ -168,18 +212,22 @@ export function AnimationCanvas({
168
212
  }
169
213
  }
170
214
  })
171
- resizeObserver.observe(parent)
215
+ ro.observe(parent)
172
216
 
173
- const w = Math.floor(parent.clientWidth)
174
- const h = Math.floor(parent.clientHeight)
217
+ const w = parent.clientWidth
218
+ const h = parent.clientHeight
175
219
  setDprConfig(canvas, context, w, h, dpr)
176
220
 
177
- if (init) init(context, widthRef, heightRef, 0)
178
- loop(context, widthRef, heightRef, 0)
221
+ if (init)
222
+ init(context, { width: widthRef.current, height: heightRef.current })
223
+ const now = performance.now()
224
+ deltaMemoRef.current = now
225
+ startTimeRef.current = now
226
+ loop(context, widthRef, heightRef, -1)
179
227
 
180
228
  return () => {
181
229
  if (reqIdRef.current) cancelAnimationFrame(reqIdRef.current)
182
- resizeObserver.unobserve(parent)
230
+ ro.disconnect()
183
231
  }
184
232
  } else {
185
233
  const rect = canvas.getBoundingClientRect()
@@ -187,8 +235,12 @@ export function AnimationCanvas({
187
235
  widthRef.current = rect.width
188
236
  heightRef.current = rect.height
189
237
 
190
- if (init) init(context, widthRef, heightRef, 0)
191
- loop(context, widthRef, heightRef, 0)
238
+ if (init)
239
+ init(context, { width: widthRef.current, height: heightRef.current })
240
+ const now = performance.now()
241
+ deltaMemoRef.current = now
242
+ startTimeRef.current = now
243
+ loop(context, widthRef, heightRef, -1)
192
244
 
193
245
  return () => {
194
246
  if (reqIdRef.current) cancelAnimationFrame(reqIdRef.current)
@@ -245,18 +245,16 @@ export const AnimationKnob = forwardRef<AnimationKnobMethods, Props>(
245
245
  draw={
246
246
  draw
247
247
  ? draw
248
- : (ctx, width, height) => {
248
+ : (ctx, { width, height }) => {
249
249
  const p = normalizeValue(value, min, max, skew)
250
250
  const startP = normalizeValue(startValue, min, max, skew)
251
- const w = width.current,
252
- cx = w / 2
253
- const h = height.current,
254
- cy = h / 2
251
+ const cx = width / 2
252
+ const cy = height / 2
255
253
  const r = Math.min(cx, cy)
256
254
  if (r <= 0) return
257
255
 
258
256
  // reset
259
- ctx.clearRect(0, 0, w, h)
257
+ ctx.clearRect(0, 0, width, height)
260
258
  ctx.lineCap = 'butt'
261
259
 
262
260
  // bg
@@ -117,7 +117,7 @@ export const InternalInput = forwardRef<
117
117
  event.preventDefault()
118
118
  const x = key == 'ArrowUp' ? keyboard[1] : -keyboard[1]
119
119
  const parsed = parseValue(String(updateValueByEvent(keyboard[0], x)))
120
- console.log('key control')
120
+ // console.log('key control')
121
121
  onChange?.(parsed.rawValue, parsed.formatValue)
122
122
  },
123
123
  [keyboard, readonly, onChange, updateValueByEvent],
@@ -131,7 +131,7 @@ export const InternalInput = forwardRef<
131
131
  if (!onChange || event.deltaY == 0) return
132
132
  const x = Math.sign(event.deltaY) * -wheel[1]
133
133
  const parsed = parseValue(String(updateValueByEvent(wheel[0], x)))
134
- console.log('wheel control')
134
+ // console.log('wheel control')
135
135
  onChange?.(parsed.rawValue, parsed.formatValue)
136
136
  },
137
137
  { passive: false },
@@ -1,10 +1,6 @@
1
1
  import { createContext, ReactNode, useContext, useEffect, useRef } from 'react'
2
2
  import { createStore, useStore } from 'zustand'
3
3
 
4
- import { isBlackKey, noteKey, NoteKey, noteKeys } from '@tremolo-ui/functions'
5
-
6
- import { defaultBlackKeyWidth, defaultWhiteKeyWidth } from './key'
7
-
8
4
  /** @category Piano */
9
5
  export type NoteRange = {
10
6
  first: number
@@ -27,8 +23,8 @@ type Action = {
27
23
 
28
24
  type PianoStore = ReturnType<typeof createPianoStore>
29
25
 
30
- const createPianoStore = (initProps?: Partial<State>) => {
31
- const noteRange = initProps?.noteRange || { first: 0, last: 127 }
26
+ const createPianoStore = (initProps: Partial<State> & Action) => {
27
+ // const noteRange = initProps.noteRange || { first: 0, last: 127 }
32
28
  const DEFAULT_PROPS: State = {
33
29
  noteRange: { first: 0, last: 127 },
34
30
  glissando: true,
@@ -42,42 +38,13 @@ const createPianoStore = (initProps?: Partial<State>) => {
42
38
  return createStore<State & Action>()(() => ({
43
39
  ...DEFAULT_PROPS,
44
40
  ...initProps,
45
- notePosition: (note: number) => {
46
- const pitchPositions: Record<NoteKey, number> = {
47
- C: 0,
48
- 'C#': 1,
49
- D: 1,
50
- 'D#': 2,
51
- E: 2,
52
- F: 3,
53
- 'F#': 4,
54
- G: 4,
55
- 'G#': 5,
56
- A: 5,
57
- 'A#': 6,
58
- B: 6,
59
- }
60
-
61
- const whiteNoteWidth = defaultWhiteKeyWidth
62
- const blackNoteWidth = defaultBlackKeyWidth
63
- const padding = 1
64
-
65
- const targetNoteKey = noteKey(note)
66
- const firstNoteKey = noteKey(noteRange.first)
67
- const octave = Math.floor((note - noteRange.first) / 12)
68
- const octaveOffset =
69
- noteKeys.indexOf(firstNoteKey) > noteKeys.indexOf(targetNoteKey) ? 1 : 0
70
- const w = whiteNoteWidth + padding
71
- const pos = pitchPositions[targetNoteKey] - pitchPositions[firstNoteKey]
72
- const blackKeyOffset = isBlackKey(note) ? blackNoteWidth / 2 : 0
73
- return pos * w + (octave + octaveOffset) * 7 * w - blackKeyOffset
74
- },
41
+ notePosition: initProps.notePosition,
75
42
  }))
76
43
  }
77
44
 
78
45
  const PianoContext = createContext<PianoStore | null>(null)
79
46
 
80
- type PianoProviderProps = React.PropsWithChildren<Partial<State>>
47
+ type PianoProviderProps = React.PropsWithChildren<Partial<State> & Action>
81
48
 
82
49
  export function PianoProvider({ children, ...props }: PianoProviderProps) {
83
50
  const storeRef = useRef<PianoStore>(null)
@@ -76,6 +76,8 @@ export interface PianoProps {
76
76
  children?: ReactElement | ReactElement[]
77
77
  }
78
78
 
79
+ const blackPerWhiteWidth = defaultBlackKeyWidth / defaultWhiteKeyWidth // 0.65
80
+
79
81
  /**
80
82
  * Customizable piano component.
81
83
  * @category Piano
@@ -115,21 +117,20 @@ export function Piano({
115
117
  const staticWidth = (whiteNoteWidth + padding) * whiteNoteCount
116
118
  // const blackNoteShiftPercent = 0.3
117
119
 
118
- // TODO: if fill setWhiteNoteWidth
119
- // useMemo
120
- // __width
121
120
  const childrenWithProps = useMemo(() => {
122
121
  return (
123
122
  children &&
124
123
  React.Children.map(children, (child, index) => {
125
124
  if (React.isValidElement(child)) {
126
- const props = { ref: keyRefs.current[index] }
125
+ const __width =
126
+ child.type == WhiteKey ? whiteNoteWidth : whiteNoteWidth * 0.65
127
+ const props = { ref: keyRefs.current[index], __width }
127
128
  return React.cloneElement(child, props)
128
129
  }
129
130
  return child
130
131
  })
131
132
  )
132
- }, [children])
133
+ }, [children, whiteNoteWidth])
133
134
 
134
135
  // --- internal functions ---
135
136
  const notePosition = useCallback(
@@ -149,10 +150,8 @@ export function Piano({
149
150
  B: 6,
150
151
  }
151
152
 
152
- const whiteNoteWidth = defaultWhiteKeyWidth
153
- const blackNoteWidth = defaultBlackKeyWidth
153
+ const blackNoteWidth = whiteNoteWidth * blackPerWhiteWidth
154
154
  const padding = 1
155
-
156
155
  const targetNoteKey = noteKey(note)
157
156
  const firstNoteKey = noteKey(noteRange.first)
158
157
  const octave = Math.floor((note - noteRange.first) / 12)
@@ -163,7 +162,7 @@ export function Piano({
163
162
  const blackKeyOffset = isBlackKey(note) ? blackNoteWidth / 2 : 0
164
163
  return pos * w + (octave + octaveOffset) * 7 * w - blackKeyOffset
165
164
  },
166
- [noteRange.first],
165
+ [noteRange.first, whiteNoteWidth],
167
166
  )
168
167
 
169
168
  const getHitKeyIndex = useCallback(
@@ -174,7 +173,9 @@ export function Piano({
174
173
  for (let i = 0; i < notes.length; i++) {
175
174
  const note = notes[i]
176
175
  const pos = notePosition(note)
177
- const w = isWhiteKey(note) ? defaultWhiteKeyWidth : defaultBlackKeyWidth
176
+ const w = isWhiteKey(note)
177
+ ? whiteNoteWidth
178
+ : whiteNoteWidth * blackPerWhiteWidth
178
179
  const h = isWhiteKey(note) ? containerHeight : containerHeight * 0.6
179
180
  if (pos <= x && x < pos + w && 0 <= y && y < h) {
180
181
  return note
@@ -182,7 +183,7 @@ export function Piano({
182
183
  }
183
184
  return -1
184
185
  },
185
- [blackNotes, notePosition, whiteNotes],
186
+ [blackNotes, notePosition, whiteNoteWidth, whiteNotes],
186
187
  )
187
188
 
188
189
  // TODO: 単一のポインターに対しては、useDragで対応可能だが、
@@ -259,6 +260,7 @@ export function Piano({
259
260
 
260
261
  return (
261
262
  <PianoProvider
263
+ notePosition={notePosition}
262
264
  noteRange={noteRange}
263
265
  glissando={glissando}
264
266
  midiMax={midiMax}
@@ -285,18 +287,20 @@ export function Piano({
285
287
  {...props}
286
288
  >
287
289
  {childrenWithProps ||
288
- getNoteRangeArray(noteRange).map((note, index) =>
290
+ noteRangeArray.map((note, index) =>
289
291
  isWhiteKey(note) ? (
290
292
  <WhiteKey
291
293
  ref={keyRefs.current[index]}
292
294
  key={note}
293
295
  noteNumber={note}
296
+ __width={whiteNoteWidth}
294
297
  />
295
298
  ) : (
296
299
  <BlackKey
297
300
  ref={keyRefs.current[index]}
298
301
  key={note}
299
302
  noteNumber={note}
303
+ __width={whiteNoteWidth * blackPerWhiteWidth}
300
304
  />
301
305
  ),
302
306
  )}