@@ -3,6 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
33import { styleMap } from 'lit/directives/style-map.js' ;
44import { analog , ElementPin } from './pin' ;
55import { clamp } from './utils/clamp' ;
6+ import { calculateBoundingRect } from './utils/geometry' ;
67
78const knobCenter = {
89 x : 9.91 ,
@@ -152,6 +153,7 @@ export class PotentiometerElement extends LitElement {
152153 </ g >
153154 < ellipse cx ="9.95 " cy ="8.06 " rx ="6.60 " ry ="6.58 " fill ="#c3c2c3 " stroke-width =".15 " />
154155 < 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 " />
155157 </ svg >
156158 ` ;
157159 }
@@ -192,6 +194,39 @@ export class PotentiometerElement extends LitElement {
192194 private updateKnobMatrix ( ) {
193195 const knob = this . shadowRoot ?. querySelector < SVGRectElement > ( '#knob' ) ;
194196 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+ }
195230 }
196231
197232 private rotateHandler ( event : MouseEvent | TouchEvent ) {
0 commit comments