feat:图片拖拽选区

pr675
黄云飞 4 years ago
parent 3a07ed82df
commit 711b07d670

@ -71,3 +71,40 @@
border: 2px solid #ffffff;
box-sizing: border-box;
}
.resizer-selection .handle-0 {
cursor: nw-resize;
}
.resizer-selection .handle-1 {
cursor: n-resize;
}
.resizer-selection .handle-2 {
cursor: ne-resize;
}
.resizer-selection .handle-3 {
cursor: e-resize;
}
.resizer-selection .handle-4 {
cursor: se-resize;
}
.resizer-selection .handle-5 {
cursor: s-resize;
}
.resizer-selection .handle-6 {
cursor: sw-resize;
}
.resizer-selection .handle-7 {
cursor: w-resize;
}
.resizer-image {
position: absolute;
opacity: 0.5;
}

@ -67,7 +67,7 @@ export class Draw {
this.underline = new Underline(ctx, options)
this.strikeout = new Strikeout(ctx, options)
this.highlight = new Highlight(ctx, options)
this.imageParticle = new ImageParticle(canvas, ctx, options)
this.imageParticle = new ImageParticle(canvas, ctx, options, this)
const canvasEvent = new CanvasEvent(canvas, this)
this.cursor = new Cursor(canvas, this, canvasEvent)

@ -1,27 +1,49 @@
import { IImageParticleCreateResult } from "../../../interface/Draw";
import { IEditorOption } from "../../../interface/Editor";
import { IElement, IElementPosition } from "../../../interface/Element";
import { IImageParticleCreateResult } from "../../../interface/Draw"
import { IEditorOption } from "../../../interface/Editor"
import { IElement, IElementPosition } from "../../../interface/Element"
import { Draw } from "../Draw"
export class ImageParticle {
private canvas: HTMLCanvasElement
private ctx: CanvasRenderingContext2D
private draw: Draw
private options: Required<IEditorOption>
private curElement: IElement | null
private curPosition: IElementPosition | null
private imageCache: Map<string, HTMLImageElement>
private resizerSelection: HTMLDivElement
private resizerHandleList: HTMLDivElement[]
private resizerImageContainer: HTMLDivElement
private resizerImage: HTMLImageElement
private width: number
private height: number
private mousedownX: number
private mousedownY: number
private curHandleIndex: number
constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, options: Required<IEditorOption>) {
constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, options: Required<IEditorOption>, draw: Draw) {
this.canvas = canvas
this.ctx = ctx
this.draw = draw
this.options = options
this.curElement = null
this.curPosition = null
this.imageCache = new Map()
const { resizerSelection, resizerHandleList } = this.createResizerDom()
const { resizerSelection, resizerHandleList, resizerImageContainer, resizerImage } = this.createResizerDom()
this.resizerSelection = resizerSelection
this.resizerHandleList = resizerHandleList
this.resizerImageContainer = resizerImageContainer
this.resizerImage = resizerImage
this.width = 0
this.height = 0
this.mousedownX = 0
this.mousedownY = 0
this.curHandleIndex = 0 // 默认右下角
}
private createResizerDom(): IImageParticleCreateResult {
// 拖拽边框
const resizerSelection = document.createElement('div')
resizerSelection.classList.add('resizer-selection')
resizerSelection.style.display = 'none'
@ -31,11 +53,101 @@ export class ImageParticle {
const handleDom = document.createElement('div')
handleDom.style.background = this.options.resizerColor
handleDom.classList.add(`handle-${i}`)
handleDom.setAttribute('data-index', String(i))
handleDom.onmousedown = this.handleMousedown.bind(this)
resizerSelection.append(handleDom)
resizerHandleList.push(handleDom)
}
this.canvas.parentNode!.append(resizerSelection)
return { resizerSelection, resizerHandleList }
// 拖拽镜像
const resizerImageContainer = document.createElement('div')
resizerImageContainer.classList.add('resizer-image')
resizerImageContainer.style.display = 'none'
const resizerImage = document.createElement('img')
resizerImageContainer.append(resizerImage)
this.canvas.parentNode!.append(resizerImageContainer)
return { resizerSelection, resizerHandleList, resizerImageContainer, resizerImage }
}
private handleMousedown(evt: MouseEvent) {
if (!this.curPosition || !this.curElement) return
this.mousedownX = evt.x
this.mousedownY = evt.y
const target = evt.target as HTMLDivElement
this.curHandleIndex = Number(target.dataset.index)
// 改变光标
const cursor = window.getComputedStyle(target).cursor
document.body.style.cursor = cursor
this.canvas.style.cursor = cursor
// 拖拽图片镜像
this.resizerImage.src = this.curElement?.value!
this.resizerImageContainer.style.display = 'block'
const { coordinate: { leftTop: [left, top] } } = this.curPosition
this.resizerImageContainer.style.left = `${left}px`
this.resizerImageContainer.style.top = `${top}px`
this.resizerImage.style.width = `${this.curElement.width}px`
this.resizerImage.style.height = `${this.curElement.height}px`
// 追加全局事件
const mousemoveFn = this.mousemove.bind(this)
document.addEventListener('mousemove', mousemoveFn)
document.addEventListener('mouseup', () => {
// 改变尺寸
if (this.curElement && this.curPosition) {
this.curElement.width = this.width
this.curElement.height = this.height
this.draw.render({ isSetCursor: false })
this.drawResizer(this.curElement, this.curPosition)
}
// 还原副作用
this.resizerImageContainer.style.display = 'none'
document.removeEventListener('mousemove', mousemoveFn)
document.body.style.cursor = ''
this.canvas.style.cursor = 'text'
}, {
once: true
})
evt.preventDefault()
}
private mousemove(evt: MouseEvent) {
if (!this.curElement) return
let dx = 0
let dy = 0
switch (this.curHandleIndex) {
case 0:
dx = this.mousedownX - evt.x
dy = this.mousedownY - evt.y
break
case 1:
dy = this.mousedownY - evt.y
break
case 2:
dx = evt.x - this.mousedownX
dy = this.mousedownY - evt.y
break
case 3:
dx = evt.x - this.mousedownX
break
case 5:
dy = evt.y - this.mousedownY
break
case 6:
dx = this.mousedownX - evt.x
dy = evt.y - this.mousedownY
break
case 7:
dx = this.mousedownX - evt.x
break
default:
dx = evt.x - this.mousedownX
dy = evt.y - this.mousedownY
break
}
this.width = this.curElement.width! + dx
this.height = this.curElement.height! + dy
this.resizerImage.style.width = `${this.width}px`
this.resizerImage.style.height = `${this.height}px`
evt.preventDefault()
}
public getImageCache(): Map<string, HTMLImageElement> {
@ -68,6 +180,10 @@ export class ImageParticle {
this.resizerHandleList[i].style.top = `${top}px`
}
this.resizerSelection.style.display = 'block'
this.curElement = element
this.curPosition = position
this.width = this.curElement.width!
this.height = this.curElement.height!
}
public clearResizer() {

@ -13,4 +13,6 @@ export interface IDrawImagePayload {
export interface IImageParticleCreateResult {
resizerSelection: HTMLDivElement;
resizerHandleList: HTMLDivElement[];
resizerImageContainer: HTMLDivElement;
resizerImage: HTMLImageElement;
}
Loading…
Cancel
Save