1
1
import AbstractPlugin from 'shared/AbstractPlugin' ;
2
+ import { browserInfo } from 'shared/utils' ;
2
3
3
4
import {
4
5
MirrorCreateEvent ,
@@ -277,13 +278,14 @@ export default class Mirror extends AbstractPlugin {
277
278
[ onMirrorCreated ] ( { mirror, source, sensorEvent} ) {
278
279
const mirrorClasses = this . draggable . getClassNamesFor ( 'mirror' ) ;
279
280
280
- const setState = ( { mirrorOffset, initialX, initialY, ...args } ) => {
281
+ const setState = ( { mirrorOffset, correctOffset , initialX, initialY, ...args } ) => {
281
282
this . mirrorOffset = mirrorOffset ;
283
+ this . correctOffset = correctOffset ;
282
284
this . initialX = initialX ;
283
285
this . initialY = initialY ;
284
286
this . lastMovedX = initialX ;
285
287
this . lastMovedY = initialY ;
286
- return { mirrorOffset, initialX, initialY, ...args } ;
288
+ return { mirrorOffset, correctOffset , initialX, initialY, ...args } ;
287
289
} ;
288
290
289
291
mirror . style . display = 'none' ;
@@ -304,6 +306,7 @@ export default class Mirror extends AbstractPlugin {
304
306
// Fix reflow here
305
307
. then ( computeMirrorDimensions )
306
308
. then ( calculateMirrorOffset )
309
+ . then ( calculateCorrectOffset )
307
310
. then ( resetMirror )
308
311
. then ( addMirrorClasses )
309
312
. then ( positionMirror ( { initial : true } ) )
@@ -334,6 +337,7 @@ export default class Mirror extends AbstractPlugin {
334
337
mirror : mirrorEvent . mirror ,
335
338
sensorEvent : mirrorEvent . sensorEvent ,
336
339
mirrorOffset : this . mirrorOffset ,
340
+ correctOffset : this . correctOffset ,
337
341
options : this . options ,
338
342
initialX : this . initialX ,
339
343
initialY : this . initialY ,
@@ -406,6 +410,49 @@ function calculateMirrorOffset({sensorEvent, sourceRect, options, ...args}) {
406
410
} ) ;
407
411
}
408
412
413
+ /**
414
+ * Calculates correct offset
415
+ * Adds correctOffset to state, because `position: fixed;` has some except
416
+ * See https://developer.mozilla.org/en-US/docs/Web/CSS/position
417
+ * @param {Object } state
418
+ * @param {HTMLElement } state.mirror
419
+ * @return {Promise }
420
+ * @private
421
+ */
422
+ function calculateCorrectOffset ( { mirror, ...args } ) {
423
+ return withPromise ( ( resolve ) => {
424
+ let x = 0 ;
425
+ let y = 0 ;
426
+ let container = mirror ;
427
+
428
+ if ( ! browserInfo . IE11OrLess ) {
429
+ do {
430
+ if ( container && container . getBoundingClientRect ) {
431
+ const containerStyle = getComputedStyle ( container ) ;
432
+ if (
433
+ ( containerStyle . transform && containerStyle . transform !== 'none' ) ||
434
+ ( containerStyle . perspective && containerStyle . perspective !== 'none' ) ||
435
+ ( containerStyle . filter && containerStyle . filter !== 'none' )
436
+ ) {
437
+ const containerRect = container . getBoundingClientRect ( ) ;
438
+
439
+ // Set relative to edges of padding box of container
440
+ x = containerRect . top + parseInt ( containerStyle [ 'border-top-width' ] , 10 ) ;
441
+ y = containerRect . left + parseInt ( containerStyle [ 'border-left-width' ] , 10 ) ;
442
+
443
+ break ;
444
+ }
445
+ }
446
+ /* jshint boss:true */
447
+ } while ( ( container = container . parentNode ) ) ;
448
+ }
449
+
450
+ const correctOffset = { x, y} ;
451
+
452
+ resolve ( { mirror, correctOffset, ...args } ) ;
453
+ } ) ;
454
+ }
455
+
409
456
/**
410
457
* Applys mirror styles
411
458
* @param {Object } state
@@ -426,7 +473,7 @@ function resetMirror({mirror, source, options, ...args}) {
426
473
offsetWidth = computedSourceStyles . getPropertyValue ( 'width' ) ;
427
474
}
428
475
429
- mirror . style . display = null ;
476
+ mirror . style . display = '' ;
430
477
mirror . style . position = 'fixed' ;
431
478
mirror . style . pointerEvents = 'none' ;
432
479
mirror . style . top = 0 ;
@@ -478,6 +525,7 @@ function removeMirrorID({mirror, ...args}) {
478
525
* @param {HTMLElement } state.mirror
479
526
* @param {SensorEvent } state.sensorEvent
480
527
* @param {Object } state.mirrorOffset
528
+ * @param {Object } state.correctOffset
481
529
* @param {Number } state.initialY
482
530
* @param {Number } state.initialX
483
531
* @param {Object } state.options
@@ -489,6 +537,7 @@ function positionMirror({withFrame = false, initial = false} = {}) {
489
537
mirror,
490
538
sensorEvent,
491
539
mirrorOffset,
540
+ correctOffset,
492
541
initialY,
493
542
initialX,
494
543
scrollOffset,
@@ -505,18 +554,22 @@ function positionMirror({withFrame = false, initial = false} = {}) {
505
554
mirror,
506
555
sensorEvent,
507
556
mirrorOffset,
557
+ correctOffset,
508
558
options,
509
559
...args ,
510
560
} ;
511
561
512
562
if ( mirrorOffset ) {
563
+ const thresholdX = options . thresholdX || 1 ;
564
+ const thresholdY = options . thresholdY || 1 ;
565
+
513
566
const x = passedThreshX
514
- ? Math . round ( ( sensorEvent . clientX - mirrorOffset . left - scrollOffset . x ) / ( options . thresholdX || 1 ) ) *
515
- ( options . thresholdX || 1 )
567
+ ? Math . round ( ( sensorEvent . clientX - mirrorOffset . left - scrollOffset . x - correctOffset . x ) / thresholdX ) *
568
+ thresholdX
516
569
: Math . round ( lastMovedX ) ;
517
570
const y = passedThreshY
518
- ? Math . round ( ( sensorEvent . clientY - mirrorOffset . top - scrollOffset . y ) / ( options . thresholdY || 1 ) ) *
519
- ( options . thresholdY || 1 )
571
+ ? Math . round ( ( sensorEvent . clientY - mirrorOffset . top - scrollOffset . y - correctOffset . y ) / thresholdY ) *
572
+ thresholdY
520
573
: Math . round ( lastMovedY ) ;
521
574
522
575
if ( ( options . xAxis && options . yAxis ) || initial ) {
0 commit comments