feat:增加全局搜索
This commit is contained in:
@@ -7,15 +7,17 @@ export class Command {
|
||||
private static painter: Function
|
||||
private static format: Function
|
||||
private static bold: Function
|
||||
private static search: Function
|
||||
private static print: Function
|
||||
|
||||
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)
|
||||
Command.search = adapt.search.bind(adapt)
|
||||
Command.print = adapt.print.bind(adapt)
|
||||
}
|
||||
|
||||
// 撤销、重做、格式刷、清除格式
|
||||
@@ -41,6 +43,10 @@ export class Command {
|
||||
}
|
||||
|
||||
// 搜索、打印
|
||||
public executeSearch(payload: string | null) {
|
||||
return Command.search(payload)
|
||||
}
|
||||
|
||||
public executePrint() {
|
||||
return Command.print()
|
||||
}
|
||||
|
||||
@@ -64,6 +64,27 @@ export class CommandAdapt {
|
||||
this.draw.render({ isSetCursor: false })
|
||||
}
|
||||
|
||||
public search(payload: string | null) {
|
||||
if (payload) {
|
||||
const elementList = this.draw.getElementList()
|
||||
const text = elementList.map(e => !e.type || e.type === 'TEXT' ? e.value : null)
|
||||
.filter(Boolean)
|
||||
.join('')
|
||||
const matchStartIndexList = []
|
||||
let index = text.indexOf(payload)
|
||||
while (index !== -1) {
|
||||
matchStartIndexList.push(index)
|
||||
index = text.indexOf(payload, index + 1)
|
||||
}
|
||||
const searchMatch: number[][] = matchStartIndexList
|
||||
.map(i => Array(payload.length).fill(i).map((_, j) => i + j))
|
||||
this.draw.setSearchMatch(searchMatch.length ? searchMatch : null)
|
||||
} else {
|
||||
this.draw.setSearchMatch(null)
|
||||
}
|
||||
this.draw.render({ isSetCursor: false, isSubmitHistory: false })
|
||||
}
|
||||
|
||||
public print() {
|
||||
return printImageBase64(this.draw.getDataURL())
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Position } from "../position/Position"
|
||||
import { RangeManager } from "../range/RangeManager"
|
||||
import { Background } from "./Background"
|
||||
import { Margin } from "./Margin"
|
||||
import { Search } from "./Search"
|
||||
|
||||
export class Draw {
|
||||
|
||||
@@ -25,10 +26,12 @@ export class Draw {
|
||||
private range: RangeManager
|
||||
private margin: Margin
|
||||
private background: Background
|
||||
private search: Search
|
||||
private historyManager: HistoryManager
|
||||
|
||||
private rowCount: number
|
||||
private painterStyle: IElementStyle | null
|
||||
private searchMatchList: number[][] | null
|
||||
|
||||
constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, options: Required<IEditorOption>, elementList: IElement[]) {
|
||||
this.canvas = canvas
|
||||
@@ -41,6 +44,7 @@ export class Draw {
|
||||
this.range = new RangeManager(ctx, elementList, options)
|
||||
this.margin = new Margin(ctx, options)
|
||||
this.background = new Background(ctx)
|
||||
this.search = new Search(ctx, options, this)
|
||||
|
||||
const canvasEvent = new CanvasEvent(canvas, this)
|
||||
this.cursor = new Cursor(canvas, this, canvasEvent)
|
||||
@@ -50,6 +54,7 @@ export class Draw {
|
||||
|
||||
this.rowCount = 0
|
||||
this.painterStyle = null
|
||||
this.searchMatchList = null
|
||||
}
|
||||
|
||||
public getHistoryManager(): HistoryManager {
|
||||
@@ -91,6 +96,14 @@ export class Draw {
|
||||
}
|
||||
}
|
||||
|
||||
public getSearchMathch(): number[][] | null {
|
||||
return this.searchMatchList
|
||||
}
|
||||
|
||||
public setSearchMatch(payload: number[][] | null) {
|
||||
this.searchMatchList = payload
|
||||
}
|
||||
|
||||
public render(payload?: IDrawOption) {
|
||||
let { curIndex, isSubmitHistory = true, isSetCursor = true } = payload || {}
|
||||
// 清除光标
|
||||
@@ -189,6 +202,10 @@ export class Draw {
|
||||
x = leftTopPoint[0]
|
||||
y += curRow.height
|
||||
}
|
||||
// 搜索匹配绘制
|
||||
if (this.searchMatchList) {
|
||||
this.search.render()
|
||||
}
|
||||
// 光标重绘
|
||||
if (curIndex === undefined) {
|
||||
curIndex = positionList.length - 1
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { IEditorOption } from "../../interface/Editor"
|
||||
import { Position } from "../position/Position"
|
||||
import { Draw } from "./Draw"
|
||||
|
||||
export class Search {
|
||||
|
||||
private ctx: CanvasRenderingContext2D
|
||||
private options: Required<IEditorOption>
|
||||
private draw: Draw
|
||||
private position: Position
|
||||
|
||||
constructor(ctx: CanvasRenderingContext2D, options: Required<IEditorOption>, draw: Draw) {
|
||||
this.ctx = ctx
|
||||
this.options = options
|
||||
this.draw = draw
|
||||
this.position = draw.getPosition()
|
||||
}
|
||||
|
||||
render() {
|
||||
const searchMatch = this.draw.getSearchMathch()
|
||||
if (!searchMatch || !searchMatch.length) return
|
||||
const searchMatchList = searchMatch.flat()
|
||||
const positionList = this.position.getPositionList()
|
||||
this.ctx.save()
|
||||
this.ctx.globalAlpha = this.options.searchMatchAlpha
|
||||
this.ctx.fillStyle = this.options.searchMatchColor
|
||||
searchMatchList.forEach(s => {
|
||||
const position = positionList[s]
|
||||
const { leftTop, leftBottom, rightTop } = position.coordinate
|
||||
const x = leftTop[0]
|
||||
const y = leftTop[1]
|
||||
const width = rightTop[0] - leftTop[0]
|
||||
const height = leftBottom[1] - leftTop[1]
|
||||
this.ctx.fillRect(x, y, width, height)
|
||||
})
|
||||
this.ctx.restore()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export class RangeManager {
|
||||
private options: Required<IEditorOption>
|
||||
private range: IRange
|
||||
|
||||
constructor(ctx: CanvasRenderingContext2D, elementList: IElement[], options: Required<IEditorOption>,) {
|
||||
constructor(ctx: CanvasRenderingContext2D, elementList: IElement[], options: Required<IEditorOption>) {
|
||||
this.ctx = ctx
|
||||
this.elementList = elementList
|
||||
this.options = options
|
||||
|
||||
@@ -17,6 +17,8 @@ export default class Editor {
|
||||
defaultSize: 16,
|
||||
rangeAlpha: 0.6,
|
||||
rangeColor: '#AECBFA',
|
||||
searchMatchAlpha: 0.6,
|
||||
searchMatchColor: '#FFFF00',
|
||||
marginIndicatorSize: 35,
|
||||
marginIndicatorColor: '#BABABA',
|
||||
margins: [100, 120, 100, 120],
|
||||
|
||||
@@ -4,6 +4,8 @@ export interface IEditorOption {
|
||||
defaultSize?: number;
|
||||
rangeColor?: string;
|
||||
rangeAlpha?: number;
|
||||
searchMatchColor?: string;
|
||||
searchMatchAlpha?: number;
|
||||
marginIndicatorSize?: number;
|
||||
marginIndicatorColor?: string,
|
||||
margins?: [top: number, right: number, bootom: number, left: number]
|
||||
|
||||
Reference in New Issue
Block a user