@tremolo-ui/react 0.0.6 → 0.0.8

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.
Files changed (133) hide show
  1. package/dist/cjs/index.js +954 -217
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/AnimationCanvas/index.d.ts +16 -9
  4. package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
  5. package/dist/cjs/types/components/AnimationKnob/index.d.ts +53 -0
  6. package/dist/cjs/types/components/AnimationKnob/index.d.ts.map +1 -0
  7. package/dist/cjs/types/components/DragObserver/index.d.ts +19 -0
  8. package/dist/cjs/types/components/DragObserver/index.d.ts.map +1 -0
  9. package/dist/cjs/types/components/Knob/index.d.ts +26 -26
  10. package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
  11. package/dist/cjs/types/components/NumberInput/index.d.ts +2 -5
  12. package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
  13. package/dist/cjs/types/components/Piano/BlackKey.d.ts +3 -3
  14. package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +1 -1
  15. package/dist/cjs/types/components/Piano/KeyLabel.d.ts +5 -8
  16. package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -1
  17. package/dist/cjs/types/components/Piano/WhiteKey.d.ts +3 -3
  18. package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +1 -1
  19. package/dist/cjs/types/components/Piano/index.d.ts +4 -5
  20. package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
  21. package/dist/cjs/types/components/Piano/key.d.ts +4 -7
  22. package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
  23. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
  24. package/dist/cjs/types/components/Slider/Scale.d.ts +11 -0
  25. package/dist/cjs/types/components/Slider/Scale.d.ts.map +1 -0
  26. package/dist/cjs/types/components/Slider/ScaleOption.d.ts +25 -0
  27. package/dist/cjs/types/components/Slider/ScaleOption.d.ts.map +1 -0
  28. package/dist/cjs/types/components/Slider/Thumb.d.ts +5 -13
  29. package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
  30. package/dist/cjs/types/components/Slider/Track.d.ts +10 -21
  31. package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
  32. package/dist/cjs/types/components/Slider/context.d.ts +21 -0
  33. package/dist/cjs/types/components/Slider/context.d.ts.map +1 -0
  34. package/dist/cjs/types/components/Slider/index.d.ts +18 -12
  35. package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
  36. package/dist/cjs/types/components/WheelObserver/index.d.ts +24 -0
  37. package/dist/cjs/types/components/WheelObserver/index.d.ts.map +1 -0
  38. package/dist/cjs/types/components/XYPad/Area.d.ts +13 -0
  39. package/dist/cjs/types/components/XYPad/Area.d.ts.map +1 -0
  40. package/dist/cjs/types/components/XYPad/Thumb.d.ts +19 -0
  41. package/dist/cjs/types/components/XYPad/Thumb.d.ts.map +1 -0
  42. package/dist/cjs/types/components/XYPad/index.d.ts +39 -0
  43. package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -0
  44. package/dist/cjs/types/hooks/useCallbackRef.d.ts.map +1 -1
  45. package/dist/cjs/types/index.d.ts +11 -0
  46. package/dist/cjs/types/index.d.ts.map +1 -1
  47. package/dist/esm/index.js +932 -218
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/types/components/AnimationCanvas/index.d.ts +16 -9
  50. package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
  51. package/dist/esm/types/components/AnimationKnob/index.d.ts +53 -0
  52. package/dist/esm/types/components/AnimationKnob/index.d.ts.map +1 -0
  53. package/dist/esm/types/components/DragObserver/index.d.ts +19 -0
  54. package/dist/esm/types/components/DragObserver/index.d.ts.map +1 -0
  55. package/dist/esm/types/components/Knob/index.d.ts +26 -26
  56. package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
  57. package/dist/esm/types/components/NumberInput/index.d.ts +2 -5
  58. package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
  59. package/dist/esm/types/components/Piano/BlackKey.d.ts +3 -3
  60. package/dist/esm/types/components/Piano/BlackKey.d.ts.map +1 -1
  61. package/dist/esm/types/components/Piano/KeyLabel.d.ts +5 -8
  62. package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -1
  63. package/dist/esm/types/components/Piano/WhiteKey.d.ts +3 -3
  64. package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +1 -1
  65. package/dist/esm/types/components/Piano/index.d.ts +4 -5
  66. package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
  67. package/dist/esm/types/components/Piano/key.d.ts +4 -7
  68. package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
  69. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts.map +1 -1
  70. package/dist/esm/types/components/Slider/Scale.d.ts +11 -0
  71. package/dist/esm/types/components/Slider/Scale.d.ts.map +1 -0
  72. package/dist/esm/types/components/Slider/ScaleOption.d.ts +25 -0
  73. package/dist/esm/types/components/Slider/ScaleOption.d.ts.map +1 -0
  74. package/dist/esm/types/components/Slider/Thumb.d.ts +5 -13
  75. package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
  76. package/dist/esm/types/components/Slider/Track.d.ts +10 -21
  77. package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
  78. package/dist/esm/types/components/Slider/context.d.ts +21 -0
  79. package/dist/esm/types/components/Slider/context.d.ts.map +1 -0
  80. package/dist/esm/types/components/Slider/index.d.ts +18 -12
  81. package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
  82. package/dist/esm/types/components/WheelObserver/index.d.ts +24 -0
  83. package/dist/esm/types/components/WheelObserver/index.d.ts.map +1 -0
  84. package/dist/esm/types/components/XYPad/Area.d.ts +13 -0
  85. package/dist/esm/types/components/XYPad/Area.d.ts.map +1 -0
  86. package/dist/esm/types/components/XYPad/Thumb.d.ts +19 -0
  87. package/dist/esm/types/components/XYPad/Thumb.d.ts.map +1 -0
  88. package/dist/esm/types/components/XYPad/index.d.ts +39 -0
  89. package/dist/esm/types/components/XYPad/index.d.ts.map +1 -0
  90. package/dist/esm/types/hooks/useCallbackRef.d.ts.map +1 -1
  91. package/dist/esm/types/index.d.ts +11 -0
  92. package/dist/esm/types/index.d.ts.map +1 -1
  93. package/dist/styles/index.css +241 -0
  94. package/package.json +2 -5
  95. package/src/components/AnimationCanvas/index.tsx +87 -57
  96. package/src/components/AnimationKnob/index.tsx +305 -0
  97. package/src/components/DragObserver/index.tsx +94 -0
  98. package/src/components/Knob/index.css +48 -0
  99. package/src/components/Knob/index.tsx +152 -165
  100. package/src/components/NumberInput/index.css +25 -0
  101. package/src/components/NumberInput/index.tsx +8 -41
  102. package/src/components/Piano/BlackKey.tsx +104 -98
  103. package/src/components/Piano/KeyLabel.tsx +18 -40
  104. package/src/components/Piano/WhiteKey.tsx +92 -87
  105. package/src/components/Piano/index.css +63 -0
  106. package/src/components/Piano/index.tsx +78 -61
  107. package/src/components/Piano/key.ts +4 -7
  108. package/src/components/Piano/keyboardShortcuts.ts +23 -4
  109. package/src/components/Slider/Scale.tsx +55 -0
  110. package/src/components/Slider/ScaleOption.tsx +103 -0
  111. package/src/components/Slider/Thumb.tsx +69 -76
  112. package/src/components/Slider/Track.tsx +37 -48
  113. package/src/components/Slider/context.tsx +66 -0
  114. package/src/components/Slider/index.css +76 -0
  115. package/src/components/Slider/index.tsx +256 -298
  116. package/src/components/WheelObserver/index.tsx +47 -0
  117. package/src/components/XYPad/Area.tsx +40 -0
  118. package/src/components/XYPad/Thumb.tsx +92 -0
  119. package/src/components/XYPad/index.css +24 -0
  120. package/src/components/XYPad/index.tsx +317 -0
  121. package/src/hooks/useCallbackRef.ts +1 -0
  122. package/src/hooks/useRefCallbackEvent.ts +1 -0
  123. package/src/index.ts +12 -0
  124. package/dist/cjs/types/components/Slider/type.d.ts +0 -7
  125. package/dist/cjs/types/components/Slider/type.d.ts.map +0 -1
  126. package/dist/cjs/types/system/pseudo.d.ts +0 -14
  127. package/dist/cjs/types/system/pseudo.d.ts.map +0 -1
  128. package/dist/esm/types/components/Slider/type.d.ts +0 -7
  129. package/dist/esm/types/components/Slider/type.d.ts.map +0 -1
  130. package/dist/esm/types/system/pseudo.d.ts +0 -14
  131. package/dist/esm/types/system/pseudo.d.ts.map +0 -1
  132. package/src/components/Slider/type.ts +0 -16
  133. package/src/system/pseudo.ts +0 -55
@@ -6,3 +6,244 @@
6
6
  .tremolo-no-select {
7
7
  user-select: none;
8
8
  }
9
+
10
+ .tremolo-knob {
11
+ display: inline-block;
12
+ cursor: pointer;
13
+ overflow: visible;
14
+ outline: 0;
15
+
16
+ &:focus,
17
+ &:hover {
18
+ > .tremolo-knob-active-line {
19
+ color: #4e76e6;
20
+ }
21
+
22
+ > .tremolo-knob-inactive-line {
23
+ color: #ddd;
24
+ }
25
+
26
+ > .tremolo-knob-thumb {
27
+ color: #ccc;
28
+ }
29
+ }
30
+
31
+ &[aria-readonly='true'] {
32
+ cursor: not-allowed;
33
+ }
34
+
35
+ &[aria-disabled='true'] {
36
+ > .tremolo-knob-active-line {
37
+ color: #5d6478;
38
+ }
39
+ }
40
+ }
41
+
42
+ .tremolo-knob-active-line {
43
+ overflow: visible;
44
+ color: #7998ec;
45
+ }
46
+
47
+ .tremolo-knob-inactive-line {
48
+ color: #eee;
49
+ }
50
+
51
+ .tremolo-knob-thumb {
52
+ color: #d0d0d0;
53
+ }
54
+
55
+ .tremolo-knob-thumb-line {
56
+ color: #eee;
57
+ }
58
+
59
+ .tremolo-number-input {
60
+ display: inline-block;
61
+ font: inherit;
62
+ margin: 0px;
63
+ padding-top: 6px;
64
+ padding-bottom: 6px;
65
+ padding-left: 10px;
66
+ padding-right: 10px;
67
+ border-style: solid;
68
+ border-width: 1px;
69
+ border-color: #bbb;
70
+ border-radius: 4px;
71
+ outline: 0px;
72
+ transition: all 0.1s linear;
73
+ appearance: textfield;
74
+
75
+ &:hover {
76
+ border-color: var(--tremolo-theme-color);
77
+ }
78
+
79
+ &:focus {
80
+ border-color: var(--tremolo-theme-color);
81
+ box-shadow: 0px 0px 0px 2px rgba(var(--tremolo-theme-color-rgb), 0.1);
82
+ }
83
+ }
84
+
85
+ .tremolo-piano {
86
+ display: inline-block;
87
+ box-sizing: border-box;
88
+ user-select: none;
89
+ position: relative;
90
+ }
91
+
92
+ .tremolo-piano-white-key {
93
+ position: absolute;
94
+ background-color: white;
95
+ color: black;
96
+ border: 1px solid #555;
97
+ border-radius: 0px 0px 8px 8px;
98
+ cursor: pointer;
99
+ z-index: 1;
100
+
101
+ &[data-active='true'] {
102
+ background-color: #ccc;
103
+ }
104
+
105
+ &[aria-disabled='true'] {
106
+ cursor: not-allowed;
107
+ }
108
+ }
109
+
110
+ .tremolo-piano-black-key {
111
+ position: absolute;
112
+ background-color: #333;
113
+ color: white;
114
+ border: 1px solid #555;
115
+ border-radius: 0px 0px 8px 8px;
116
+ cursor: pointer;
117
+ z-index: 2;
118
+
119
+ &[data-active='true'] {
120
+ background-color: #666;
121
+ }
122
+
123
+ &[aria-disabled='true'] {
124
+ cursor: not-allowed;
125
+ }
126
+ }
127
+
128
+ .tremolo-piano-key-label-wrapper {
129
+ display: flex;
130
+ justify-content: center;
131
+ align-items: end;
132
+ height: 100%;
133
+ }
134
+
135
+ .tremolo-piano-key-label {
136
+ display: flex;
137
+ justify-content: center;
138
+ align-items: center;
139
+ font-size: 0.6rem;
140
+ height: 10px;
141
+ margin-bottom: 10px;
142
+ padding: 4px;
143
+ border-radius: 4px;
144
+ border: 1px solid #888;
145
+ aspect-ratio: 1;
146
+ max-width: calc(100% - 16px);
147
+ }
148
+
149
+ .tremolo-slider {
150
+ display: inline-block;
151
+ cursor: pointer;
152
+ outline: 0;
153
+ -webkit-tap-highlight-color: transparent;
154
+
155
+ &[aria-readonly='true'] {
156
+ cursor: not-allowed;
157
+ }
158
+ }
159
+
160
+ .tremolo-slider-thumb-wrapper {
161
+ position: absolute;
162
+ translate: -50% -50%;
163
+ z-index: 100;
164
+ }
165
+
166
+ .tremolo-slider-thumb {
167
+ background: #4e76e6;
168
+ border-radius: 50%;
169
+ outline: none;
170
+
171
+ &[aria-disabled='true'] {
172
+ background: #5d6478;
173
+ }
174
+
175
+ &[aria-readonly='false']:focus {
176
+ box-shadow: 0px 0px 0px 3px rgba(var(--tremolo-theme-color-rgb), 0.2);
177
+ }
178
+ }
179
+
180
+ .tremolo-slider-track {
181
+ --active: #7998ec;
182
+ --inactive: #eee;
183
+
184
+ position: relative;
185
+
186
+ &:hover {
187
+ --active: #6387e9;
188
+ --inactive: #e0e0e0;
189
+ }
190
+
191
+ &[aria-disabled='true'] {
192
+ --active: #858890;
193
+ --inactive: #ddd;
194
+ }
195
+ }
196
+
197
+ .tremolo-slider-scale {
198
+ display: block;
199
+ position: relative;
200
+ }
201
+
202
+ .tremolo-slider-scale-option {
203
+ display: flex;
204
+ color: #222;
205
+ flex-direction: column;
206
+ justify-content: center;
207
+ align-items: center;
208
+ position: absolute;
209
+ translate: -50% 0;
210
+ z-index: 10;
211
+
212
+ &[data-vertical='true'] {
213
+ flex-direction: row;
214
+ translate: 0 -50%;
215
+ }
216
+ }
217
+
218
+ .tremolo-slider-scale-option-mark {
219
+ background-color: currentColor;
220
+ }
221
+
222
+ .tremolo-slider-scale-option-label {
223
+ text-align: right;
224
+ }
225
+
226
+ .tremolo-xy-pad {
227
+ display: inline-block;
228
+ cursor: pointer;
229
+ }
230
+
231
+ .tremolo-xy-pad-thumb-wrapper {
232
+ position: absolute;
233
+ translate: -50% -50%;
234
+ z-index: 100;
235
+ }
236
+
237
+ .tremolo-xy-pad-thumb {
238
+ border-radius: 50%;
239
+ outline: none;
240
+ background-color: #4e76e6;
241
+
242
+ &[aria-disabled='true'] {
243
+ background-color: #5d6478;
244
+ }
245
+
246
+ &:focus {
247
+ box-shadow: 0px 0px 0px 3px rgba(var(--tremolo-theme-color-rgb), 0.2);
248
+ }
249
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tremolo-ui/react",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "React component library for audio app",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -54,11 +54,9 @@
54
54
  "react-components",
55
55
  "ui",
56
56
  "components",
57
- "web-audio",
58
- "emotion"
57
+ "web-audio"
59
58
  ],
60
59
  "devDependencies": {
61
- "@emotion/react": "^11.13.0",
62
60
  "@storybook/addon-essentials": "^8.3.3",
63
61
  "@storybook/addon-interactions": "^8.3.3",
64
62
  "@storybook/addon-links": "^8.3.3",
@@ -75,7 +73,6 @@
75
73
  "tone": "^15.0.4"
76
74
  },
77
75
  "peerDependencies": {
78
- "@emotion/react": "11.x",
79
76
  "react": "18.x",
80
77
  "react-dom": "18.x"
81
78
  },
@@ -1,6 +1,12 @@
1
- import { css, CSSObject } from '@emotion/react'
2
- import { ComponentPropsWithRef, MutableRefObject, useEffect, useRef } from 'react'
3
1
  import clsx from 'clsx'
2
+ import {
3
+ ComponentPropsWithoutRef,
4
+ MutableRefObject,
5
+ ReactElement,
6
+ useCallback,
7
+ useEffect,
8
+ useRef,
9
+ } from 'react'
4
10
 
5
11
  import { DrawingContext, drawingState, DrawingStateValue } from './canvas'
6
12
 
@@ -25,25 +31,45 @@ export type DrawFunction = (
25
31
  count: number,
26
32
  ) => void
27
33
 
28
- export interface AnimationCanvasProps {
34
+ interface CommonProps {
35
+ /**
36
+ * @see https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/getContext#contextattributes
37
+ */
38
+ options?: CanvasRenderingContext2DSettings
39
+ init?: DrawFunction
40
+ draw: DrawFunction
41
+ }
42
+
43
+ interface AbsoluteSizingProps {
29
44
  width?: number
30
45
  height?: number
46
+ }
47
+
48
+ interface RelativeSizingProps {
31
49
  relativeSize?: boolean
32
- /** only available relativeSize=true */
33
50
  reduceFlickering?: boolean
34
- options?: CanvasRenderingContext2DSettings
35
- style?: CSSObject
36
- init?: DrawFunction
37
- draw: DrawFunction
38
51
  }
39
52
 
53
+ export type AnimationCanvasProps = AbsoluteSizingProps &
54
+ RelativeSizingProps &
55
+ CommonProps
56
+
40
57
  /**
41
58
  * A simple animatable canvas with requestAnimationFrame()
42
59
  */
60
+ export function AnimationCanvas(
61
+ props: AbsoluteSizingProps &
62
+ CommonProps &
63
+ Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>,
64
+ ): ReactElement
65
+ export function AnimationCanvas(
66
+ props: RelativeSizingProps &
67
+ CommonProps &
68
+ Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>,
69
+ ): ReactElement
43
70
  export function AnimationCanvas({
44
71
  width = 100,
45
72
  height = 100,
46
- style,
47
73
  relativeSize = false,
48
74
  reduceFlickering = true,
49
75
  options,
@@ -52,24 +78,30 @@ export function AnimationCanvas({
52
78
  className,
53
79
  ...props
54
80
  }: AnimationCanvasProps &
55
- Omit<ComponentPropsWithRef<'canvas'>, keyof AnimationCanvasProps>) {
81
+ Omit<
82
+ ComponentPropsWithoutRef<'canvas'>,
83
+ keyof AnimationCanvasProps
84
+ >): ReactElement {
56
85
  const canvasRef = useRef<HTMLCanvasElement>(null)
57
86
  const memoCanvasRef = useRef<HTMLCanvasElement>(null)
58
87
  const reqIdRef = useRef<number>()
59
88
  const widthRef = useRef(0)
60
89
  const heightRef = useRef(0)
61
90
 
62
- const loop = (
63
- context: CanvasRenderingContext2D,
64
- width: MutableRefObject<number>,
65
- height: MutableRefObject<number>,
66
- count: number,
67
- ) => {
68
- reqIdRef.current = requestAnimationFrame(() =>
69
- loop(context, width, height, count + 1),
70
- )
71
- draw(context, width, height, count + 1)
72
- }
91
+ const loop = useCallback(
92
+ (
93
+ context: CanvasRenderingContext2D,
94
+ width: MutableRefObject<number>,
95
+ height: MutableRefObject<number>,
96
+ count: number,
97
+ ) => {
98
+ reqIdRef.current = requestAnimationFrame(() =>
99
+ loop(context, width, height, count + 1),
100
+ )
101
+ draw(context, width, height, count + 1)
102
+ },
103
+ [draw],
104
+ )
73
105
 
74
106
  useEffect(() => {
75
107
  if (!canvasRef.current) return
@@ -84,34 +116,38 @@ export function AnimationCanvas({
84
116
  const memoCanvas = memoCanvasRef.current
85
117
  const memoContext = memoCanvas?.getContext('2d', options)
86
118
 
87
- const resizeObserver = new ResizeObserver(() => {
88
- // console.log('resize')
89
- // Prevents loss of some context when the canvas is resized
90
- const contextMemo = {} as DrawingContext
91
- for (const prop of drawingState) {
92
- (contextMemo[prop] as DrawingStateValue) = context[prop]
93
- }
94
-
95
- const w = Math.floor(parent.clientWidth)
96
- const h = Math.floor(parent.clientHeight)
97
-
98
- if (reduceFlickering && memoCanvas && memoContext) {
99
- memoCanvas.width = w * dpr
100
- memoCanvas.height = h * dpr
101
- memoContext.scale(1 / dpr, 1 / dpr)
102
- memoContext.drawImage(context.canvas, 0, 0)
103
- }
104
-
105
- setDprConfig(canvas, context, w, h, dpr)
106
- widthRef.current = w
107
- heightRef.current = h
108
-
109
- for (const prop of drawingState) {
110
- (context[prop] as DrawingStateValue) = contextMemo[prop]
111
- }
112
-
113
- if (reduceFlickering && memoContext) {
114
- context.drawImage(memoContext.canvas, 0, 0)
119
+ const resizeObserver = new ResizeObserver((entries) => {
120
+ // TODO: If the parent element has no absolute height, the height increases infinitely.
121
+ // : 親要素に絶対的な高さを持たない場合、高さは無限に増加します。
122
+ // 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
123
+ for (const entry of entries) {
124
+ // Prevents loss of some context when the canvas is resized
125
+ const contextMemo = {} as DrawingContext
126
+ for (const prop of drawingState) {
127
+ ;(contextMemo[prop] as DrawingStateValue) = context[prop]
128
+ }
129
+
130
+ const w = Math.floor(entry.contentRect.width)
131
+ const h = Math.floor(entry.contentRect.height)
132
+
133
+ if (reduceFlickering && memoCanvas && memoContext) {
134
+ memoCanvas.width = w * dpr
135
+ memoCanvas.height = h * dpr
136
+ memoContext.scale(1 / dpr, 1 / dpr)
137
+ memoContext.drawImage(context.canvas, 0, 0)
138
+ }
139
+
140
+ setDprConfig(canvas, context, w, h, dpr)
141
+ widthRef.current = w
142
+ heightRef.current = h
143
+
144
+ for (const prop of drawingState) {
145
+ ;(context[prop] as DrawingStateValue) = contextMemo[prop]
146
+ }
147
+
148
+ if (reduceFlickering && memoContext) {
149
+ context.drawImage(memoContext.canvas, 0, 0)
150
+ }
115
151
  }
116
152
  })
117
153
  resizeObserver.observe(parent)
@@ -140,7 +176,7 @@ export function AnimationCanvas({
140
176
  if (reqIdRef.current) cancelAnimationFrame(reqIdRef.current)
141
177
  }
142
178
  }
143
- }, [loop])
179
+ }, [loop, init, options, reduceFlickering, relativeSize])
144
180
 
145
181
  return (
146
182
  <>
@@ -148,17 +184,11 @@ export function AnimationCanvas({
148
184
  className={clsx('tremolo-animation-canvas', className)}
149
185
  width={relativeSize ? 0 : width}
150
186
  height={relativeSize ? 0 : height}
151
- css={css(style)}
152
187
  ref={canvasRef}
153
188
  {...props}
154
189
  ></canvas>
155
190
  {relativeSize && reduceFlickering && (
156
- <canvas
157
- style={{ display: 'none' }}
158
- width={relativeSize ? 0 : width}
159
- height={relativeSize ? 0 : height}
160
- ref={memoCanvasRef}
161
- ></canvas>
191
+ <canvas style={{ display: 'none' }} ref={memoCanvasRef}></canvas>
162
192
  )}
163
193
  </>
164
194
  )