diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index 2aeff15..2892726 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -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() } diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index df97d9d..d62e2dd 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -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 }) } diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index ebd0cd5..4661ff0 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -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, 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 || {} // 清除光标 diff --git a/src/editor/core/event/CanvasEvent.ts b/src/editor/core/event/CanvasEvent.ts index ded1818..c84ca10 100644 --- a/src/editor/core/event/CanvasEvent.ts +++ b/src/editor/core/event/CanvasEvent.ts @@ -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) { diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index 50ddb23..faac0e5 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -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 private range: IRange - constructor(ctx: CanvasRenderingContext2D, options: Required,) { + constructor(ctx: CanvasRenderingContext2D, elementList: IElement[], options: Required,) { 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 diff --git a/src/editor/dataset/enum/ElementStyle.ts b/src/editor/dataset/enum/ElementStyle.ts new file mode 100644 index 0000000..294852a --- /dev/null +++ b/src/editor/dataset/enum/ElementStyle.ts @@ -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' +} \ No newline at end of file diff --git a/src/editor/interface/Element.ts b/src/editor/interface/Element.ts index 9111d7a..b034eb2 100644 --- a/src/editor/interface/Element.ts +++ b/src/editor/interface/Element.ts @@ -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, diff --git a/src/main.ts b/src/main.ts index 564f561..8c4a5bf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -54,6 +54,10 @@ window.onload = function () { console.log('redo') instance.command.executeRedo() } + document.querySelector('.menu-item__painter')!.onclick = function () { + console.log('painter') + instance.command.executePainter() + } document.querySelector('.menu-item__format')!.onclick = function () { console.log('format') instance.command.executeFormat()