util.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import { ILayerFormed } from "../../types"
  21. import { ISlideParams } from "containers/Viz/types"
  22. import { DeltaPosition, DeltaSize } from 'containers/Display/components/Layer'
  23. import { IBaseline } from './types'
  24. import { DEFAULT_BASELINE_DIVISIONS, DEFAULT_BASELINE_THICKNESS } from './constants'
  25. export function computeEditorBaselines(
  26. operatingLayers: ILayerFormed[],
  27. otherLayers: ILayerFormed[],
  28. slideSize: Pick<ISlideParams, 'width' | 'height'>,
  29. grid: [number, number],
  30. scale: number,
  31. delta: DeltaPosition & DeltaSize,
  32. adjustType: IBaseline['adjustType']
  33. ) {
  34. const { deltaX, deltaY, deltaWidth, deltaHeight } = delta
  35. const rect = operatingLayers.reduce<[number, number, number, number]>(
  36. ([minX, maxX, minY, maxY], layer) => {
  37. const { positionX, positionY, width, height } = layer.params
  38. return [
  39. Math.min(minX, positionX + deltaX),
  40. Math.max(maxX, positionX + deltaX + width + deltaWidth),
  41. Math.min(minY, positionY + deltaY),
  42. Math.max(maxY, positionY + deltaY + height + deltaHeight)
  43. ]
  44. },
  45. [Infinity, -Infinity, Infinity, -Infinity]
  46. )
  47. const baselinesSlide = computeSlideBaselines(
  48. rect,
  49. slideSize,
  50. grid,
  51. scale,
  52. adjustType
  53. )
  54. const baselinesLayers = computeLayersBaselines(
  55. rect,
  56. slideSize,
  57. grid,
  58. scale,
  59. adjustType,
  60. otherLayers
  61. )
  62. const baselineVertical = [
  63. ...baselinesSlide.vertical,
  64. ...baselinesLayers.vertical
  65. ].reduce(
  66. (acc, baseline) =>
  67. !acc || acc.adjust[0] > baseline.adjust[0] ? baseline : acc,
  68. null
  69. )
  70. const baselineHorizontal = [
  71. ...baselinesSlide.horizontal,
  72. ...baselinesLayers.horizontal
  73. ].reduce(
  74. (acc, baseline) =>
  75. !acc || acc.adjust[1] > baseline.adjust[1] ? baseline : acc,
  76. null
  77. )
  78. const baselines = [baselineVertical, baselineHorizontal].filter((bl) => !!bl)
  79. return baselines
  80. }
  81. function computeSlideBaselines(
  82. [minX, maxX, minY, maxY]: [number, number, number, number],
  83. slideSize: Pick<ISlideParams, 'width' | 'height'>,
  84. grid: [number, number],
  85. scale: number,
  86. adjustType: IBaseline['adjustType']
  87. ) {
  88. const { width: slideWidth, height: slideHeight } = slideSize
  89. const middleX = (minX + maxX) / 2
  90. const middleY = (minY + maxY) / 2
  91. const baselinesVertical: IBaseline[] = []
  92. const baselinesHorizontal: IBaseline[] = []
  93. DEFAULT_BASELINE_DIVISIONS.some((division) => {
  94. let step = 0
  95. while (step < division) {
  96. const baseX = step ? Math.round((slideWidth / division) * step) : 0
  97. const baseY = step ? Math.round((slideHeight / division) * step) : 0
  98. step++
  99. const marginX = Math.round(baseX - middleX)
  100. const marginY = Math.round(baseY - middleY)
  101. if (Math.abs(marginX) < grid[0] && baselinesVertical.length === 0) {
  102. // may not accurate when lacking of slideWidth
  103. baselinesVertical.push({
  104. top: 0,
  105. right: slideWidth - baseX - DEFAULT_BASELINE_THICKNESS / scale,
  106. bottom: 0,
  107. left: baseX,
  108. adjust: [marginX, 0],
  109. adjustType
  110. })
  111. }
  112. if (Math.abs(marginY) < grid[1] && baselinesHorizontal.length === 0) {
  113. baselinesHorizontal.push({
  114. top: baseY,
  115. right: 0,
  116. bottom: slideHeight - baseY - DEFAULT_BASELINE_THICKNESS / scale,
  117. left: 0,
  118. adjust: [0, marginY],
  119. adjustType
  120. })
  121. }
  122. if (baselinesVertical.length && baselinesHorizontal.length) {
  123. return true
  124. }
  125. }
  126. return false
  127. })
  128. const baselines = {
  129. vertical: baselinesVertical,
  130. horizontal: baselinesHorizontal
  131. }
  132. return baselines
  133. }
  134. function computeLayersBaselines(
  135. [minX, maxX, minY, maxY]: [number, number, number, number],
  136. slideSize: Pick<ISlideParams, 'width' | 'height'>,
  137. grid: [number, number],
  138. scale: number,
  139. adjustType: IBaseline['adjustType'],
  140. otherLayers: ILayerFormed[]
  141. ) {
  142. const { width: slideWidth, height: slideHeight } = slideSize
  143. const middleX = (minX + maxX) / 2
  144. const middleY = (minY + maxY) / 2
  145. const baselinesVertical: IBaseline[] = []
  146. const baselinesHorizontal: IBaseline[] = []
  147. otherLayers.forEach((layer) => {
  148. const { positionX, positionY, width, height } = layer.params
  149. const middleBaseX = positionX + width / 2
  150. const middleBaseY = positionY + height / 2
  151. const marginX = Math.round(middleBaseX - middleX)
  152. const marginY = Math.round(middleBaseY - middleY)
  153. if (Math.abs(marginX) < grid[0]) {
  154. if (
  155. baselinesVertical.length === 0 ||
  156. Math.abs(baselinesVertical[0].adjust[0]) > Math.abs(marginX)
  157. ) {
  158. baselinesVertical.push({
  159. top: Math.min(positionY, minY),
  160. right: slideWidth - middleBaseX - DEFAULT_BASELINE_THICKNESS / scale,
  161. bottom: slideHeight - Math.max(positionY + height, maxY),
  162. left: middleBaseX,
  163. adjust: [marginX, 0],
  164. adjustType
  165. })
  166. }
  167. }
  168. if (Math.abs(marginY) < grid[1]) {
  169. if (
  170. baselinesHorizontal.length === 0 ||
  171. Math.abs(baselinesHorizontal[0].adjust[1]) > Math.abs(marginY)
  172. ) {
  173. baselinesHorizontal.push({
  174. top: middleY,
  175. right: slideWidth - Math.max(positionX + width, maxX),
  176. bottom: slideHeight - middleY - DEFAULT_BASELINE_THICKNESS / scale,
  177. left: Math.min(positionX, minX),
  178. adjust: [0, marginY],
  179. adjustType
  180. })
  181. }
  182. }
  183. })
  184. const baselines = {
  185. vertical: baselinesVertical,
  186. horizontal: baselinesHorizontal
  187. }
  188. return baselines
  189. }