feat:增加格式刷
This commit is contained in:
@@ -4,6 +4,7 @@ export class Command {
|
||||
|
||||
private static undo: Function
|
||||
private static redo: Function
|
||||
private static painter: Function
|
||||
private static format: Function
|
||||
private static bold: Function
|
||||
private static print: Function
|
||||
@@ -11,6 +12,7 @@ export class Command {
|
||||
constructor(adapt: CommandAdapt) {
|
||||
Command.undo = adapt.undo.bind(adapt)
|
||||
Command.redo = adapt.redo.bind(adapt)
|
||||
Command.painter = adapt.painter.bind(adapt)
|
||||
Command.print = adapt.print.bind(adapt)
|
||||
Command.format = adapt.format.bind(adapt)
|
||||
Command.bold = adapt.bold.bind(adapt)
|
||||
@@ -25,6 +27,10 @@ export class Command {
|
||||
return Command.redo()
|
||||
}
|
||||
|
||||
public executePainter() {
|
||||
return Command.painter()
|
||||
}
|
||||
|
||||
public executeFormat() {
|
||||
return Command.format()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { ElementStyleKey } from "../../dataset/enum/ElementStyle"
|
||||
import { IElementStyle } from "../../interface/Element"
|
||||
import { printImageBase64 } from "../../utils/print"
|
||||
import { Draw } from "../draw/Draw"
|
||||
import { HistoryManager } from "../history/HistoryManager"
|
||||
@@ -23,30 +25,42 @@ export class CommandAdapt {
|
||||
return this.historyManager.redo()
|
||||
}
|
||||
|
||||
public format() {
|
||||
const { startIndex, endIndex } = this.range.getRange()
|
||||
if (startIndex === endIndex) return
|
||||
const elementList = this.draw.getElementList()
|
||||
elementList.slice(startIndex + 1, endIndex + 1)
|
||||
.forEach(el => {
|
||||
el.font = ''
|
||||
el.color = ''
|
||||
el.bold = false
|
||||
el.italic = false
|
||||
el.underline = false
|
||||
el.strikeout = false
|
||||
public painter() {
|
||||
const selection = this.range.getSelection()
|
||||
if (!selection) return
|
||||
const painterStyle: IElementStyle = {}
|
||||
selection.forEach(s => {
|
||||
const painterStyleKeys = ['bold', 'color', 'font', 'size', 'italic', 'underline', 'strikeout']
|
||||
painterStyleKeys.forEach(p => {
|
||||
const key = p as keyof typeof ElementStyleKey
|
||||
if (painterStyle[key] === undefined && s[key] !== undefined) {
|
||||
painterStyle[key] = s[key] as any
|
||||
}
|
||||
})
|
||||
})
|
||||
this.draw.setPainterStyle(painterStyle)
|
||||
}
|
||||
|
||||
public format() {
|
||||
const selection = this.range.getSelection()
|
||||
if (!selection) return
|
||||
selection.forEach(el => {
|
||||
el.font = ''
|
||||
el.color = ''
|
||||
el.bold = false
|
||||
el.italic = false
|
||||
el.underline = false
|
||||
el.strikeout = false
|
||||
})
|
||||
this.draw.render({ isSetCursor: false })
|
||||
}
|
||||
|
||||
public bold() {
|
||||
const { startIndex, endIndex } = this.range.getRange()
|
||||
if (startIndex === endIndex) return
|
||||
const elementList = this.draw.getElementList()
|
||||
elementList.slice(startIndex + 1, endIndex + 1)
|
||||
.forEach(el => {
|
||||
el.bold = true
|
||||
})
|
||||
const selection = this.range.getSelection()
|
||||
if (!selection) return
|
||||
selection.forEach(el => {
|
||||
el.bold = true
|
||||
})
|
||||
this.draw.render({ isSetCursor: false })
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ZERO } from "../../dataset/constant/Common"
|
||||
import { IDrawOption } from "../../interface/Draw"
|
||||
import { IEditorOption } from "../../interface/Editor"
|
||||
import { IElement, IElementPosition } from "../../interface/Element"
|
||||
import { IElement, IElementPosition, IElementStyle } from "../../interface/Element"
|
||||
import { IRow } from "../../interface/Row"
|
||||
import { deepClone } from "../../utils"
|
||||
import { Cursor } from "../cursor/Cursor"
|
||||
@@ -28,6 +28,7 @@ export class Draw {
|
||||
private historyManager: HistoryManager
|
||||
|
||||
private rowCount: number
|
||||
private painterStyle: IElementStyle | null
|
||||
|
||||
constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, options: Required<IEditorOption>, elementList: IElement[]) {
|
||||
this.canvas = canvas
|
||||
@@ -37,7 +38,7 @@ export class Draw {
|
||||
|
||||
this.historyManager = new HistoryManager()
|
||||
this.position = new Position(this)
|
||||
this.range = new RangeManager(ctx, options)
|
||||
this.range = new RangeManager(ctx, elementList, options)
|
||||
this.margin = new Margin(ctx, options)
|
||||
this.background = new Background(ctx)
|
||||
|
||||
@@ -48,6 +49,7 @@ export class Draw {
|
||||
globalEvent.register()
|
||||
|
||||
this.rowCount = 0
|
||||
this.painterStyle = null
|
||||
}
|
||||
|
||||
public getHistoryManager(): HistoryManager {
|
||||
@@ -78,6 +80,17 @@ export class Draw {
|
||||
return this.canvas.toDataURL()
|
||||
}
|
||||
|
||||
public getPainterStyle(): IElementStyle | null {
|
||||
return this.painterStyle && Object.keys(this.painterStyle).length ? this.painterStyle : null
|
||||
}
|
||||
|
||||
public setPainterStyle(payload: IElementStyle | null) {
|
||||
this.painterStyle = payload
|
||||
if (this.getPainterStyle()) {
|
||||
this.canvas.style.cursor = 'copy'
|
||||
}
|
||||
}
|
||||
|
||||
public render(payload?: IDrawOption) {
|
||||
let { curIndex, isSubmitHistory = true, isSetCursor = true } = payload || {}
|
||||
// 清除光标
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ZERO } from "../../dataset/constant/Common"
|
||||
import { ElementStyleKey } from "../../dataset/enum/ElementStyle"
|
||||
import { KeyMap } from "../../dataset/enum/Keymap"
|
||||
import { IElement } from "../../interface/Element"
|
||||
import { writeText } from "../../utils/clipboard"
|
||||
@@ -45,6 +46,23 @@ export class CanvasEvent {
|
||||
|
||||
public setIsAllowDrag(payload: boolean) {
|
||||
this.isAllowDrag = payload
|
||||
if (payload === false) {
|
||||
this.canvas.style.cursor = 'text'
|
||||
// 应用格式刷样式
|
||||
const painterStyle = this.draw.getPainterStyle()
|
||||
if (!painterStyle) return
|
||||
const selection = this.range.getSelection()
|
||||
if (!selection) return
|
||||
const painterStyleKeys = Object.keys(painterStyle)
|
||||
selection.forEach(s => {
|
||||
painterStyleKeys.forEach(pKey => {
|
||||
const key = pKey as keyof typeof ElementStyleKey
|
||||
s[key] = painterStyle[key] as any
|
||||
})
|
||||
})
|
||||
this.draw.setPainterStyle(null)
|
||||
this.draw.render({ isSetCursor: false })
|
||||
}
|
||||
}
|
||||
|
||||
public mousemove(evt: MouseEvent) {
|
||||
@@ -75,7 +93,7 @@ export class CanvasEvent {
|
||||
// 是否还在canvas内部
|
||||
const { x, y, width, height } = this.canvas.getBoundingClientRect()
|
||||
if (evt.x >= x && evt.x <= x + width && evt.y >= y && evt.y <= y + height) return
|
||||
this.isAllowDrag = false
|
||||
this.setIsAllowDrag(false)
|
||||
}
|
||||
|
||||
public keydown(evt: KeyboardEvent) {
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { IEditorOption } from "../../interface/Editor"
|
||||
import { IElement } from "../../interface/Element"
|
||||
import { IRange } from "../../interface/Range"
|
||||
|
||||
export class RangeManager {
|
||||
|
||||
private ctx: CanvasRenderingContext2D
|
||||
private elementList: IElement[]
|
||||
private options: Required<IEditorOption>
|
||||
private range: IRange
|
||||
|
||||
constructor(ctx: CanvasRenderingContext2D, options: Required<IEditorOption>,) {
|
||||
constructor(ctx: CanvasRenderingContext2D, elementList: IElement[], options: Required<IEditorOption>,) {
|
||||
this.ctx = ctx
|
||||
this.elementList = elementList
|
||||
this.options = options
|
||||
this.range = {
|
||||
startIndex: 0,
|
||||
@@ -20,6 +23,12 @@ export class RangeManager {
|
||||
return this.range
|
||||
}
|
||||
|
||||
public getSelection(): IElement[] | null {
|
||||
const { startIndex, endIndex } = this.range
|
||||
if (startIndex === endIndex) return null
|
||||
return this.elementList.slice(startIndex + 1, endIndex + 1)
|
||||
}
|
||||
|
||||
public setRange(startIndex: number, endIndex: number) {
|
||||
this.range.startIndex = startIndex
|
||||
this.range.endIndex = endIndex
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export enum ElementStyleKey {
|
||||
font = 'font',
|
||||
size = 'size',
|
||||
width = 'width',
|
||||
height = 'height',
|
||||
bold = 'bold',
|
||||
color = 'color',
|
||||
italic = 'italic',
|
||||
underline = 'underline',
|
||||
strikeout = 'strikeout'
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
export interface IElement {
|
||||
type?: 'TEXT' | 'IMAGE';
|
||||
value: string;
|
||||
export interface IElementStyle {
|
||||
font?: string;
|
||||
size?: number;
|
||||
width?: number;
|
||||
@@ -12,6 +10,13 @@ export interface IElement {
|
||||
strikeout?: boolean;
|
||||
}
|
||||
|
||||
export interface IElementBasic {
|
||||
type?: 'TEXT' | 'IMAGE';
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type IElement = IElementBasic & IElementStyle
|
||||
|
||||
export interface IElementPosition {
|
||||
index: number;
|
||||
value: string,
|
||||
|
||||
Reference in New Issue
Block a user