@@ -3,6 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
3
3
import { styleMap } from 'lit/directives/style-map.js' ;
4
4
import { analog , ElementPin } from './pin' ;
5
5
import { clamp } from './utils/clamp' ;
6
+ import { calculateBoundingRect } from './utils/geometry' ;
6
7
7
8
const knobCenter = {
8
9
x : 9.91 ,
@@ -152,6 +153,7 @@ export class PotentiometerElement extends LitElement {
152
153
</ g >
153
154
< ellipse cx ="9.95 " cy ="8.06 " rx ="6.60 " ry ="6.58 " fill ="#c3c2c3 " stroke-width =".15 " />
154
155
< rect id ="rotating " x ="10 " y ="2 " width =".42 " height ="3.1 " stroke-width =".15 " />
156
+ < rect x ="0 " y ="9.5 " width ="1 " height ="1 " fill ="none " id ="firefox-workaround " />
155
157
</ svg >
156
158
` ;
157
159
}
@@ -192,6 +194,39 @@ export class PotentiometerElement extends LitElement {
192
194
private updateKnobMatrix ( ) {
193
195
const knob = this . shadowRoot ?. querySelector < SVGRectElement > ( '#knob' ) ;
194
196
this . pageToKnobMatrix = knob ?. getScreenCTM ( ) ?. inverse ( ) ?? null ;
197
+
198
+ if ( navigator . userAgent . indexOf ( 'Firefox' ) >= 0 ) {
199
+ // Firefox's getScreenCTM() is broken: https://bugzilla.mozilla.org/show_bug.cgi?id=1610093
200
+ const firefoxWorkaround =
201
+ this . shadowRoot ?. querySelector < SVGRectElement > ( '#firefox-workaround' ) ;
202
+ const boundingRect = firefoxWorkaround ?. getBoundingClientRect ( ) ;
203
+ const svgRect = firefoxWorkaround ?. ownerSVGElement ?. getBoundingClientRect ( ) ;
204
+ if ( ! boundingRect || ! svgRect ) {
205
+ return ;
206
+ }
207
+
208
+ const cx = svgRect . x + svgRect . width / 2 ;
209
+ const cy = svgRect . y + svgRect . height / 2 ;
210
+ const deltaX = cx - ( boundingRect . x + boundingRect . width / 2 ) ;
211
+ const deltaY = cy - ( boundingRect . y + boundingRect . height / 2 ) ;
212
+ const angle = ( Math . atan2 ( deltaY , deltaX ) / Math . PI ) * 180 ;
213
+ const rotation = new DOMMatrix ( ) . rotate ( angle ) ;
214
+ const rotatedRect = calculateBoundingRect ( new DOMRect ( 0 , 9.5 , 1 , 1 ) , rotation ) ;
215
+ const sx = rotatedRect . width / boundingRect . width ;
216
+ const sy = rotatedRect . height / boundingRect . height ;
217
+ this . pageToKnobMatrix = rotation
218
+ . inverse ( )
219
+ . multiply (
220
+ new DOMMatrix ( [
221
+ sx ,
222
+ 0 ,
223
+ 0 ,
224
+ sy ,
225
+ rotatedRect . left - boundingRect . left * sx ,
226
+ rotatedRect . top - boundingRect . top * sy ,
227
+ ] )
228
+ ) ;
229
+ }
195
230
}
196
231
197
232
private rotateHandler ( event : MouseEvent | TouchEvent ) {
0 commit comments