resizertopbound.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import {
  2. getAbsoluteBoundaryPoint
  3. } from './utils';
  4. import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
  5. import mix from '@ckeditor/ckeditor5-utils/src/mix';
  6. import global from '@ckeditor/ckeditor5-utils/src/dom/global';
  7. /**
  8. *
  9. * This resizer is top bound, and expands symmetrically towards left, right and increasingly fast toward bottom
  10. * (to compensate for top anchoring).
  11. *
  12. *
  13. *
  14. */
  15. /**
  16. * Implements a resizer that enlarges/shrinks in all directions.
  17. *
  18. * @class ResizerCentral
  19. */
  20. export default class ResizerCentral {
  21. constructor( context, options ) {
  22. this.context = context;
  23. this.options = options || {};
  24. }
  25. attach() {}
  26. begin() {
  27. this.redraw();
  28. const resizeHost = this.context._getResizeHost();
  29. this.closestReferencePoint = getAbsoluteBoundaryPoint( resizeHost, this.context.referenceHandlerPosition );
  30. }
  31. redraw() {
  32. if ( this.context.domResizeWrapper ) {
  33. const clientRect = this.context._getResizeHost().getBoundingClientRect();
  34. // Size of resize host before current resizing transaction.
  35. this.initialSize = {
  36. width: clientRect.width,
  37. height: clientRect.height
  38. };
  39. this.context.domResizeWrapper.style.width = this.initialSize.width + 'px';
  40. this.context.domResizeWrapper.style.height = this.initialSize.height + 'px';
  41. }
  42. }
  43. commit() {}
  44. cancel() {}
  45. destroy() {}
  46. updateSize( domEventData ) {
  47. const context = this.context;
  48. const currentCoordinates = context._extractCoordinates( domEventData );
  49. const isCentered = this.options.isCentered ? this.options.isCentered( this.context ) : true;
  50. const enlargement = {
  51. // @todo it could be simplified if context.referenceCoordinates was an inverted corner (at least for bottom-left).
  52. x: this.context.referenceCoordinates.x - ( currentCoordinates.x + this.initialSize.width ),
  53. y: ( currentCoordinates.y - this.initialSize.height ) - this.context.referenceCoordinates.y
  54. };
  55. // temp workaround
  56. if ( isCentered && this.context.referenceHandlerPosition.endsWith( '-right' ) ) {
  57. enlargement.x = currentCoordinates.x - ( this.context.referenceCoordinates.x + this.initialSize.width );
  58. }
  59. // @todo: oddly enough, this condition **check** is not needed for tables.
  60. if ( isCentered && enlargement.x < 0 ) {
  61. enlargement.x *= 2;
  62. }
  63. const resizeHost = this.context._getResizeHost();
  64. const clientRect = resizeHost.getBoundingClientRect();
  65. const originalSize = {
  66. x: clientRect.width,
  67. y: clientRect.height
  68. };
  69. const proposedSize = {
  70. x: Math.abs( this.initialSize.width + enlargement.x ),
  71. y: Math.abs( this.initialSize.height + enlargement.y )
  72. };
  73. // Dominant determination must take the ratio into account.
  74. proposedSize.dominant = proposedSize.x / context.aspectRatio > proposedSize.y ? 'x' : 'y';
  75. proposedSize.max = proposedSize[ proposedSize.dominant ];
  76. const drawnSize = {
  77. x: proposedSize.x,
  78. y: proposedSize.y
  79. };
  80. if ( proposedSize.dominant == 'x' ) {
  81. drawnSize.y = drawnSize.x / context.aspectRatio;
  82. } else {
  83. drawnSize.x = drawnSize.y * context.aspectRatio;
  84. }
  85. const resizeUsingImage = global.window.pocResizeUsingImage !== false;
  86. let shadowBoundValue = '0px';
  87. if ( !resizeUsingImage ) {
  88. shadowBoundValue = 'auto';
  89. }
  90. // Reset shadow bounding.
  91. context.domResizeShadow.style.top = shadowBoundValue;
  92. context.domResizeShadow.style.left = shadowBoundValue;
  93. context.domResizeShadow.style.bottom = shadowBoundValue;
  94. context.domResizeShadow.style.right = shadowBoundValue;
  95. if ( resizeUsingImage ) {
  96. resizeHost.style.width = `${ drawnSize.x }px`;
  97. resizeHost.style.height = `${ drawnSize.y }px`;
  98. } else {
  99. const invertedPosition = this.context._invertPosition( context.referenceHandlerPosition );
  100. const diff2 = {
  101. x: parseFloat( originalSize.x ) - drawnSize.x,
  102. y: parseFloat( originalSize.y ) - drawnSize.y
  103. };
  104. context.domResizeShadow.style[ invertedPosition.split( '-' )[ 0 ] ] = '0px';
  105. context.domResizeShadow.style[ invertedPosition.split( '-' )[ 1 ] ] = `${ diff2.x / 2 }px`;
  106. // Apply the actual shadow dimensions.
  107. context.domResizeShadow.style.width = `${ drawnSize.x }px`;
  108. context.domResizeShadow.style.height = `${ drawnSize.y }px`;
  109. }
  110. return drawnSize; // @todo decide what size should actually be returned.
  111. }
  112. }
  113. mix( ResizerCentral, ObservableMixin );