|
@@ -0,0 +1,214 @@
|
|
|
+import {
|
|
|
+ getAbsoluteCoordinate,
|
|
|
+ createElement,
|
|
|
+ getInitialPoint,
|
|
|
+ getSvgPathFromStroke
|
|
|
+} from '../annotation/utils';
|
|
|
+
|
|
|
+export default class AddText {
|
|
|
+ constructor ({
|
|
|
+ tool,
|
|
|
+ color,
|
|
|
+ container,
|
|
|
+ viewport,
|
|
|
+ page,
|
|
|
+ eventBus,
|
|
|
+ contentContainer
|
|
|
+ }) {
|
|
|
+ this._tool = tool
|
|
|
+ this.color = color
|
|
|
+ this.container = container
|
|
|
+ this.viewport = viewport
|
|
|
+ this.page = page
|
|
|
+ this.eventBus = eventBus
|
|
|
+ this.contentContainer = contentContainer
|
|
|
+
|
|
|
+ this.path = []
|
|
|
+ this.initStartPoint = null
|
|
|
+ this.initEndPoint = null
|
|
|
+ this.shapeEle = null
|
|
|
+
|
|
|
+ this.onMousedown = this.handleMouseDown.bind(this)
|
|
|
+ this.onMouseup = this.handleMouseUp.bind(this)
|
|
|
+ this.onMousemove = this.handleMouseMove.bind(this)
|
|
|
+
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
+
|
|
|
+ init () {
|
|
|
+ this.container.addEventListener('mousedown', this.onMousedown)
|
|
|
+ this.container.addEventListener('touchstart', this.onMousedown)
|
|
|
+ this.container.style.cursor = 'crosshair'
|
|
|
+ this.container.style.touchAction = 'none'
|
|
|
+ document.removeEventListener('mousemove', this.onMousemove)
|
|
|
+ document.removeEventListener('mouseup', this.onMouseup)
|
|
|
+ document.removeEventListener('touchmove', this.onMousemove)
|
|
|
+ document.removeEventListener('touchend', this.onMouseup)
|
|
|
+ }
|
|
|
+
|
|
|
+ get tool () {
|
|
|
+ return this._tool
|
|
|
+ }
|
|
|
+
|
|
|
+ set tool (toolType) {
|
|
|
+ if (toolType === this._tool) return
|
|
|
+ if (!toolType) {
|
|
|
+ this.reset()
|
|
|
+ this.container.style.touchAction = ''
|
|
|
+
|
|
|
+ this.container.removeEventListener('mousedown', this.onMousedown)
|
|
|
+ this.container.removeEventListener('touchstart', this.onMousedown)
|
|
|
+ }
|
|
|
+ this._tool = toolType
|
|
|
+ }
|
|
|
+
|
|
|
+ reset () {
|
|
|
+ this.initStartPoint = null
|
|
|
+ this.initEndPoint = null
|
|
|
+ if (this.shapeEle) this.shapeEle.remove()
|
|
|
+ this.shapeEle = null
|
|
|
+ this.path = []
|
|
|
+ document.removeEventListener('mousemove', this.onMousemove)
|
|
|
+ document.removeEventListener('mouseup', this.onMouseup)
|
|
|
+
|
|
|
+ document.removeEventListener('touchmove', this.onMousemove)
|
|
|
+ document.removeEventListener('touchend', this.onMouseup)
|
|
|
+
|
|
|
+ this.container.removeEventListener('mousedown', this.onMousedown)
|
|
|
+ this.container.removeEventListener('touchstart', this.onMousedown)
|
|
|
+ }
|
|
|
+
|
|
|
+ handleMouseDown (event) {
|
|
|
+ if (!event.target.className && !event.target.className.includes('contentContainer')) return
|
|
|
+ const { x, y } = getAbsoluteCoordinate(this.container, event)
|
|
|
+ this.initStartPoint = { x, y }
|
|
|
+
|
|
|
+ document.addEventListener('mousemove', this.onMousemove)
|
|
|
+ document.addEventListener('mouseup', this.onMouseup)
|
|
|
+
|
|
|
+ document.addEventListener('touchmove', this.onMousemove)
|
|
|
+ document.addEventListener('touchend', this.onMouseup)
|
|
|
+ }
|
|
|
+
|
|
|
+ handleMouseUp () {
|
|
|
+ let initStartPoint = this.initStartPoint
|
|
|
+ let initEndPoint = this.initEndPoint
|
|
|
+ if (initEndPoint && initStartPoint.x !== initEndPoint.x && initStartPoint.y !== initEndPoint.y) {
|
|
|
+ let start = getInitialPoint(initStartPoint, this.viewport, this.viewport.scale)
|
|
|
+ let end = getInitialPoint(initEndPoint, this.viewport, this.viewport.scale)
|
|
|
+
|
|
|
+ const newStart = {
|
|
|
+ x: Math.min(start.x, end.x),
|
|
|
+ y: Math.min(start.y, end.y)
|
|
|
+ }
|
|
|
+ const newEnd = {
|
|
|
+ x: Math.max(start.x, end.x),
|
|
|
+ y: Math.max(start.y, end.y)
|
|
|
+ }
|
|
|
+
|
|
|
+ const rect = {
|
|
|
+ left: newStart.x,
|
|
|
+ top: newStart.y,
|
|
|
+ right: newEnd.x,
|
|
|
+ bottom: newEnd.y
|
|
|
+ }
|
|
|
+
|
|
|
+ const data = {
|
|
|
+ rect,
|
|
|
+ fontData: {
|
|
|
+ fontName: 'Helvetica',
|
|
|
+ fontSize: 14,
|
|
|
+ r: 0,
|
|
|
+ g: 0,
|
|
|
+ b: 0,
|
|
|
+ opacity: 1,
|
|
|
+ isBold: 0,
|
|
|
+ italic: 0,
|
|
|
+ },
|
|
|
+ alignType: 2
|
|
|
+ }
|
|
|
+ this.contentContainer.addTextEditor(data)
|
|
|
+ }
|
|
|
+ // this.reset()
|
|
|
+ this.initStartPoint = null
|
|
|
+ this.initEndPoint = null
|
|
|
+ if (this.shapeEle) this.shapeEle.remove()
|
|
|
+ this.shapeEle = null
|
|
|
+ this.path = []
|
|
|
+ document.removeEventListener('mousemove', this.onMousemove)
|
|
|
+ document.removeEventListener('mouseup', this.onMouseup)
|
|
|
+
|
|
|
+ document.removeEventListener('touchmove', this.onMousemove)
|
|
|
+ document.removeEventListener('touchend', this.onMouseup)
|
|
|
+ }
|
|
|
+
|
|
|
+ handleMouseMove (event) {
|
|
|
+ let { x, y } = getAbsoluteCoordinate(this.container, event)
|
|
|
+ const { width, height } = this.viewport
|
|
|
+ const scale = this.viewport.scale
|
|
|
+ x = Math.min(width, x)
|
|
|
+ x = Math.max(0, x)
|
|
|
+ y = Math.min(height, y)
|
|
|
+ y = Math.max(0, y)
|
|
|
+ this.initEndPoint = { x, y }
|
|
|
+ if (this.initStartPoint.x !== this.initEndPoint.x && this.initStartPoint.y !== this.initEndPoint.y) {
|
|
|
+ if (!this.shapeEle) {
|
|
|
+ const shapeEle = createElement('div', {
|
|
|
+ 'backgroundColor': '#DDE9FF',
|
|
|
+ 'position': "absolute",
|
|
|
+ 'z-index': 3
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: 'add-text'
|
|
|
+ })
|
|
|
+ this.shapeEle = shapeEle
|
|
|
+ this.container.append(this.shapeEle)
|
|
|
+ } else {
|
|
|
+ if (event.shiftKey) {
|
|
|
+ const { initStartPoint, initEndPoint } = this
|
|
|
+ const distanceX = Math.abs(initEndPoint.x - initStartPoint.x)
|
|
|
+ const distanceY = Math.abs(initEndPoint.y - initStartPoint.y)
|
|
|
+ const distance = Math.min(distanceX, distanceY)
|
|
|
+ if (initStartPoint.x < initEndPoint.x) {
|
|
|
+ initEndPoint.x = initStartPoint.x + distance
|
|
|
+ } else {
|
|
|
+ initEndPoint.x = initStartPoint.x - distance
|
|
|
+ }
|
|
|
+ if (initStartPoint.y < initEndPoint.y) {
|
|
|
+ initEndPoint.y = initStartPoint.y + distance
|
|
|
+ } else {
|
|
|
+ initEndPoint.y = initStartPoint.y - distance
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const rect = this.calculate(this.initStartPoint, this.initEndPoint)
|
|
|
+
|
|
|
+ const shapeEle = this.shapeEle
|
|
|
+ shapeEle.style.top = `${rect.top}px`;
|
|
|
+ shapeEle.style.left = `${rect.left}px`;
|
|
|
+ shapeEle.style.width = `${Math.abs(rect.width - 1)}px`;
|
|
|
+ shapeEle.style.height = `${Math.abs(rect.height - 1)}px`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ rectCalc ({ start, end }) {
|
|
|
+ return {
|
|
|
+ top: start.y < end.y ? start.y : end.y,
|
|
|
+ left: start.x < end.x ? start.x : end.x,
|
|
|
+ width: Math.abs(end.x - start.x),
|
|
|
+ height: Math.abs(end.y - start.y),
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ calculate (start, end) {
|
|
|
+ const initRect = this.rectCalc({ start, end });
|
|
|
+ const actualbdwidth = 1 * this.viewport.scale
|
|
|
+
|
|
|
+ return {
|
|
|
+ top: initRect.top - actualbdwidth,
|
|
|
+ left: initRect.left - actualbdwidth,
|
|
|
+ width: initRect.width + actualbdwidth * 2,
|
|
|
+ height: initRect.height + actualbdwidth * 2,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|