feat:增加格式刷

pr675
黄云飞 4 years ago
parent e9607674c7
commit 6cef3f096b

@ -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,

@ -54,6 +54,10 @@ window.onload = function () {
console.log('redo')
instance.command.executeRedo()
}
document.querySelector<HTMLDivElement>('.menu-item__painter')!.onclick = function () {
console.log('painter')
instance.command.executePainter()
}
document.querySelector<HTMLDivElement>('.menu-item__format')!.onclick = function () {
console.log('format')
instance.command.executeFormat()

Loading…
Cancel
Save