feat:下划线、删除线
This commit is contained in:
+1
-1
@@ -42,7 +42,7 @@
|
|||||||
<div class="menu-item__underline">
|
<div class="menu-item__underline">
|
||||||
<i></i>
|
<i></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item__deleteline">
|
<div class="menu-item__strikeout">
|
||||||
<i></i>
|
<i></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item__color">
|
<div class="menu-item__color">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -10,6 +10,8 @@ export class Command {
|
|||||||
private static sizeMinus: Function
|
private static sizeMinus: Function
|
||||||
private static bold: Function
|
private static bold: Function
|
||||||
private static italic: Function
|
private static italic: Function
|
||||||
|
private static underline: Function
|
||||||
|
private static strikeout: Function
|
||||||
private static search: Function
|
private static search: Function
|
||||||
private static print: Function
|
private static print: Function
|
||||||
|
|
||||||
@@ -22,6 +24,8 @@ export class Command {
|
|||||||
Command.sizeMinus = adapt.sizeMinus.bind(adapt)
|
Command.sizeMinus = adapt.sizeMinus.bind(adapt)
|
||||||
Command.bold = adapt.bold.bind(adapt)
|
Command.bold = adapt.bold.bind(adapt)
|
||||||
Command.italic = adapt.italic.bind(adapt)
|
Command.italic = adapt.italic.bind(adapt)
|
||||||
|
Command.underline = adapt.underline.bind(adapt)
|
||||||
|
Command.strikeout = adapt.strikeout.bind(adapt)
|
||||||
Command.search = adapt.search.bind(adapt)
|
Command.search = adapt.search.bind(adapt)
|
||||||
Command.print = adapt.print.bind(adapt)
|
Command.print = adapt.print.bind(adapt)
|
||||||
}
|
}
|
||||||
@@ -60,6 +64,14 @@ export class Command {
|
|||||||
return Command.italic()
|
return Command.italic()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public executeUnderline() {
|
||||||
|
return Command.underline()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executeStrikeout() {
|
||||||
|
return Command.strikeout()
|
||||||
|
}
|
||||||
|
|
||||||
// 搜索、打印
|
// 搜索、打印
|
||||||
public executeSearch(payload: string | null) {
|
public executeSearch(payload: string | null) {
|
||||||
return Command.search(payload)
|
return Command.search(payload)
|
||||||
|
|||||||
@@ -110,6 +110,26 @@ export class CommandAdapt {
|
|||||||
this.draw.render({ isSetCursor: false })
|
this.draw.render({ isSetCursor: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public underline() {
|
||||||
|
const selection = this.range.getSelection()
|
||||||
|
if (!selection) return
|
||||||
|
const noUnderlineIndex = selection.findIndex(s => !s.underline)
|
||||||
|
selection.forEach(el => {
|
||||||
|
el.underline = !!~noUnderlineIndex
|
||||||
|
})
|
||||||
|
this.draw.render({ isSetCursor: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
public strikeout() {
|
||||||
|
const selection = this.range.getSelection()
|
||||||
|
if (!selection) return
|
||||||
|
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
|
||||||
|
selection.forEach(el => {
|
||||||
|
el.strikeout = !!~noStrikeoutIndex
|
||||||
|
})
|
||||||
|
this.draw.render({ isSetCursor: false })
|
||||||
|
}
|
||||||
|
|
||||||
public search(payload: string | null) {
|
public search(payload: string | null) {
|
||||||
if (payload) {
|
if (payload) {
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { RangeManager } from "../range/RangeManager"
|
|||||||
import { Background } from "./Background"
|
import { Background } from "./Background"
|
||||||
import { Margin } from "./Margin"
|
import { Margin } from "./Margin"
|
||||||
import { Search } from "./Search"
|
import { Search } from "./Search"
|
||||||
|
import { Strikeout } from "./Strikeout"
|
||||||
|
import { Underline } from "./Underline"
|
||||||
|
|
||||||
export class Draw {
|
export class Draw {
|
||||||
|
|
||||||
@@ -27,6 +29,8 @@ export class Draw {
|
|||||||
private margin: Margin
|
private margin: Margin
|
||||||
private background: Background
|
private background: Background
|
||||||
private search: Search
|
private search: Search
|
||||||
|
private underline: Underline
|
||||||
|
private strikeout: Strikeout
|
||||||
private historyManager: HistoryManager
|
private historyManager: HistoryManager
|
||||||
|
|
||||||
private rowCount: number
|
private rowCount: number
|
||||||
@@ -45,6 +49,8 @@ export class Draw {
|
|||||||
this.margin = new Margin(ctx, options)
|
this.margin = new Margin(ctx, options)
|
||||||
this.background = new Background(ctx)
|
this.background = new Background(ctx)
|
||||||
this.search = new Search(ctx, options, this)
|
this.search = new Search(ctx, options, this)
|
||||||
|
this.underline = new Underline(ctx, options)
|
||||||
|
this.strikeout = new Strikeout(ctx, options)
|
||||||
|
|
||||||
const canvasEvent = new CanvasEvent(canvas, this)
|
const canvasEvent = new CanvasEvent(canvas, this)
|
||||||
this.cursor = new Cursor(canvas, this, canvasEvent)
|
this.cursor = new Cursor(canvas, this, canvasEvent)
|
||||||
@@ -204,6 +210,14 @@ export class Draw {
|
|||||||
if (startIndex < index && index <= endIndex) {
|
if (startIndex < index && index <= endIndex) {
|
||||||
this.range.drawRange(x, y, metrics.width, curRow.height)
|
this.range.drawRange(x, y, metrics.width, curRow.height)
|
||||||
}
|
}
|
||||||
|
// 下划线绘制
|
||||||
|
if (element.underline) {
|
||||||
|
this.underline.render(x, y + curRow.height, metrics.width)
|
||||||
|
}
|
||||||
|
// 删除线绘制
|
||||||
|
if (element.strikeout) {
|
||||||
|
this.strikeout.render(x, y + curRow.height / 2, metrics.width)
|
||||||
|
}
|
||||||
index++
|
index++
|
||||||
x += metrics.width
|
x += metrics.width
|
||||||
this.ctx.restore()
|
this.ctx.restore()
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { IEditorOption } from "../../interface/Editor"
|
||||||
|
|
||||||
|
export class Strikeout {
|
||||||
|
|
||||||
|
private ctx: CanvasRenderingContext2D
|
||||||
|
private options: Required<IEditorOption>
|
||||||
|
|
||||||
|
constructor(ctx: CanvasRenderingContext2D, options: Required<IEditorOption>) {
|
||||||
|
this.ctx = ctx
|
||||||
|
this.options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
render(x: number, y: number, width: number) {
|
||||||
|
const { strikeoutColor } = this.options
|
||||||
|
this.ctx.save()
|
||||||
|
this.ctx.strokeStyle = strikeoutColor
|
||||||
|
this.ctx.beginPath()
|
||||||
|
this.ctx.moveTo(x, y)
|
||||||
|
this.ctx.lineTo(x + width, y)
|
||||||
|
this.ctx.stroke()
|
||||||
|
this.ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { IEditorOption } from "../../interface/Editor"
|
||||||
|
|
||||||
|
export class Underline {
|
||||||
|
|
||||||
|
private ctx: CanvasRenderingContext2D
|
||||||
|
private options: Required<IEditorOption>
|
||||||
|
|
||||||
|
constructor(ctx: CanvasRenderingContext2D, options: Required<IEditorOption>) {
|
||||||
|
this.ctx = ctx
|
||||||
|
this.options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
render(x: number, y: number, width: number) {
|
||||||
|
const { underlineColor } = this.options
|
||||||
|
this.ctx.save()
|
||||||
|
this.ctx.strokeStyle = underlineColor
|
||||||
|
this.ctx.beginPath()
|
||||||
|
this.ctx.moveTo(x, y)
|
||||||
|
this.ctx.lineTo(x + width, y)
|
||||||
|
this.ctx.stroke()
|
||||||
|
this.ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,6 +15,8 @@ export default class Editor {
|
|||||||
defaultType: 'TEXT',
|
defaultType: 'TEXT',
|
||||||
defaultFont: 'Yahei',
|
defaultFont: 'Yahei',
|
||||||
defaultSize: 16,
|
defaultSize: 16,
|
||||||
|
underlineColor: '#000000',
|
||||||
|
strikeoutColor: '#FF0000',
|
||||||
rangeAlpha: 0.6,
|
rangeAlpha: 0.6,
|
||||||
rangeColor: '#AECBFA',
|
rangeColor: '#AECBFA',
|
||||||
searchMatchAlpha: 0.6,
|
searchMatchAlpha: 0.6,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ export interface IEditorOption {
|
|||||||
defaultType?: string;
|
defaultType?: string;
|
||||||
defaultFont?: string;
|
defaultFont?: string;
|
||||||
defaultSize?: number;
|
defaultSize?: number;
|
||||||
|
underlineColor?: string;
|
||||||
|
strikeoutColor?: string;
|
||||||
rangeColor?: string;
|
rangeColor?: string;
|
||||||
rangeAlpha?: number;
|
rangeAlpha?: number;
|
||||||
searchMatchColor?: string;
|
searchMatchColor?: string;
|
||||||
|
|||||||
@@ -80,6 +80,14 @@ window.onload = function () {
|
|||||||
console.log('italic')
|
console.log('italic')
|
||||||
instance.command.executeItalic()
|
instance.command.executeItalic()
|
||||||
}
|
}
|
||||||
|
document.querySelector<HTMLDivElement>('.menu-item__underline')!.onclick = function () {
|
||||||
|
console.log('underline')
|
||||||
|
instance.command.executeUnderline()
|
||||||
|
}
|
||||||
|
document.querySelector<HTMLDivElement>('.menu-item__strikeout')!.onclick = function () {
|
||||||
|
console.log('strikeout')
|
||||||
|
instance.command.executeStrikeout()
|
||||||
|
}
|
||||||
|
|
||||||
// 搜索、打印
|
// 搜索、打印
|
||||||
const collspanDom = document.querySelector<HTMLDivElement>('.menu-item__search__collapse')
|
const collspanDom = document.querySelector<HTMLDivElement>('.menu-item__search__collapse')
|
||||||
|
|||||||
+2
-2
@@ -100,8 +100,8 @@ body {
|
|||||||
background-image: url('./assets/images/underline.svg');
|
background-image: url('./assets/images/underline.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item__deleteline i {
|
.menu-item__strikeout i {
|
||||||
background-image: url('./assets/images/deleteline.svg');
|
background-image: url('./assets/images/strikeout.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item__color,
|
.menu-item__color,
|
||||||
|
|||||||
Reference in New Issue
Block a user