Extend grammar markup style continued
This commit is contained in:
parent
53fc05a2f8
commit
bb822f0bbc
18
Readme.md
18
Readme.md
@ -87,6 +87,24 @@ Kategorije pravopisnih pravil so:
|
||||
| BESANA_CAT_5 | slovnične napake |
|
||||
| BESANA_CAT_6 | nomotehnične napake (potrebuje posebno licenco) |
|
||||
|
||||
### 4. Nastavljanje videza korekturnih znamenj
|
||||
|
||||
Privzeto servis uporablja podčrtovanje pravopisnih napak (nastavitev `'underline'`). Videz lahko spreminjamo.
|
||||
|
||||
<img src="samples/markup_underline.png" alt="underline" width="448"/>
|
||||
<img src="samples/markup_lector.png" alt="lector" width="448"/>
|
||||
|
||||
Levo `'underline'`, desno `'lector'`.
|
||||
|
||||
Primer:
|
||||
|
||||
```JavaScript
|
||||
// Registriramo servis za naš urejevalnik.
|
||||
BesService
|
||||
.registerByElement(el)
|
||||
.setMarkupStyle('lector')
|
||||
```
|
||||
|
||||
## Navodila za razvijalce
|
||||
|
||||
Programsko kodo v tem repozitoriju razvijamo s programom Visual Studio Code. Potrebna je namestitev vtičnika `esbenp.prettier-vscode`.
|
||||
|
BIN
samples/markup_lector.png
Normal file
BIN
samples/markup_lector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 174 KiB |
BIN
samples/markup_underline.png
Normal file
BIN
samples/markup_underline.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 151 KiB |
518
service.js
518
service.js
@ -362,50 +362,36 @@ class BesService {
|
||||
*/
|
||||
addMistakeMarkup(match) {
|
||||
const range = match.range
|
||||
const ruleId = match.match.rule.id
|
||||
const scrollPanelRect = this.scrollPanel.getBoundingClientRect()
|
||||
const dpr = window.devicePixelRatio
|
||||
const markerX = this.canvasPanel.width * dpr
|
||||
const scrollX = scrollPanelRect.left
|
||||
const scrollY = scrollPanelRect.top
|
||||
match.highlights = Array.from(range.getClientRects())
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.lineWidth = 2 * dpr // Use 2 for clearer visibility
|
||||
const ruleId = match.match.rule.id
|
||||
this.ctx.strokeStyle = ruleId.startsWith('MORFOLOGIK_RULE')
|
||||
? 'rgba(255, 115, 0, 0.5)'
|
||||
: 'rgba(0, 123, 255, 0.5)'
|
||||
const drawSideMarker = (y1, y2) => {
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(markerX, y1 * dpr)
|
||||
this.ctx.lineTo(markerX, y2 * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
? 'rgba(0, 123, 255, 0.8)'
|
||||
: 'rgba(255, 115, 0, 0.8)'
|
||||
this.ctx.fillStyle = ruleId.startsWith('MORFOLOGIK_RULE')
|
||||
? 'rgba(0, 123, 255, 0.8)'
|
||||
: 'rgba(255, 115, 0, 0.8)'
|
||||
let markerY1, markerY2
|
||||
switch (this.markupStyle) {
|
||||
case 'lector':
|
||||
if (match.match.replacements && match.match.replacements.length) {
|
||||
const drawMissingComma = (x, y) => {
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo((x - 2) * dpr, y * dpr)
|
||||
this.ctx.lineTo((x + 2) * dpr, y * dpr)
|
||||
this.ctx.lineTo((x + 2) * dpr, (y - 4) * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
const drawWrongSpacing = (x, y1, y2) => {
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo((x - 4) * dpr, (y1 + 4) * dpr)
|
||||
this.ctx.lineTo(x * dpr, y1 * dpr)
|
||||
this.ctx.lineTo((x + 4) * dpr, (y1 + 4) * dpr)
|
||||
this.ctx.moveTo(x * dpr, y1 * dpr)
|
||||
this.ctx.lineTo(x * dpr, y2 * dpr)
|
||||
this.ctx.moveTo((x - 4) * dpr, (y2 - 4) * dpr)
|
||||
this.ctx.lineTo(x * dpr, y2 * dpr)
|
||||
this.ctx.lineTo((x + 4) * dpr, (y2 - 4) * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
const drawExcessiveText = (x1, y1, x2, y2) => {
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(x1 * dpr, y1 * dpr)
|
||||
this.ctx.lineTo(x2 * dpr, y2 * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
if (ruleId === 'BESANA_6' /*PR_VNAP_V_STAVKU_MANJKA_VEJICA*/) {
|
||||
// Thou we should draw ┘ after the word before match.match.offset, if there is a line break inbetween,
|
||||
// the correction markup would be drawn in one line and the highlight rectangle for onClick would reside
|
||||
// in another line, making a confusing UX.
|
||||
markerY1 = match.highlights[0].top
|
||||
markerY2 = match.highlights[0].bottom
|
||||
const scale = (markerY2 - markerY1) / 18
|
||||
const x = match.highlights[0].left
|
||||
const y = match.highlights[0].bottom
|
||||
this.drawMissingComma(x - scrollX, y - scrollY, scale, '?')
|
||||
break
|
||||
}
|
||||
|
||||
if (match.match.replacements && match.match.replacements.length === 1) {
|
||||
const context = match.match.context.text.substr(
|
||||
match.match.context.offset,
|
||||
match.match.context.length
|
||||
@ -418,52 +404,81 @@ class BesService {
|
||||
) {
|
||||
// Something to insert before
|
||||
const toInsert = replacement.substr(0, lengthDiff)
|
||||
markerY1 = match.highlights[0].top
|
||||
markerY2 = match.highlights[0].bottom
|
||||
const scale = (markerY2 - markerY1) / 18
|
||||
|
||||
if (toInsert === ',') {
|
||||
const x = match.highlights[0].left - scrollPanelRect.left
|
||||
const y = match.highlights[0].bottom - scrollPanelRect.top
|
||||
drawMissingComma(x, y)
|
||||
// Thou we should draw ┘ after the word before match.match.offset, if there is a line break inbetween,
|
||||
// the correction markup would be drawn in one line and the highlight rectangle for onClick would reside
|
||||
// in another line, making a confusing UX.
|
||||
const x = match.highlights[0].left
|
||||
const y = match.highlights[0].bottom
|
||||
this.drawMissingComma(x - scrollX, y - scrollY, scale)
|
||||
} else if (/^\s+$/.test(toInsert)) {
|
||||
const x = match.highlights[0].left - scrollPanelRect.left
|
||||
const y1 = match.highlights[0].bottom - scrollPanelRect.top - 2
|
||||
const y2 = match.highlights[0].top - scrollPanelRect.top + 2
|
||||
drawWrongSpacing(x, y1, y2)
|
||||
const x = match.highlights[0].left
|
||||
const y1 = match.highlights[0].bottom - 2 * scale
|
||||
const y2 = match.highlights[0].top + 2 * scale
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
// TODO
|
||||
const x = match.highlights[0].left - 1 * scale
|
||||
const y1 = match.highlights[0].bottom
|
||||
const y2 = match.highlights[0].top
|
||||
this.drawMissingText(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale,
|
||||
replacement.substr(lengthDiff).trim()
|
||||
)
|
||||
}
|
||||
|
||||
drawSideMarker(
|
||||
match.highlights[0].top - scrollPanelRect.top,
|
||||
match.highlights[0].bottom - scrollPanelRect.top
|
||||
)
|
||||
} else if (replacement.substr(0, context.length) === context) {
|
||||
// Something to insert after
|
||||
const toInsert = replacement.substr(-lengthDiff)
|
||||
markerY1 = match.highlights.at(-1).top
|
||||
markerY2 = match.highlights.at(-1).bottom
|
||||
const scale = (markerY2 - markerY1) / 18
|
||||
|
||||
if (toInsert === ',') {
|
||||
const x = match.highlights.at(-1).right - scrollPanelRect.left
|
||||
const y = match.highlights.at(-1).bottom - scrollPanelRect.top
|
||||
drawMissingComma(x, y)
|
||||
const x = match.highlights.at(-1).right
|
||||
const y = match.highlights.at(-1).bottom
|
||||
this.drawMissingComma(x - scrollX, y - scrollY, scale)
|
||||
} else if (/^\s+$/.test(toInsert)) {
|
||||
const x = match.highlights.at(-1).right - scrollPanelRect.left
|
||||
const y1 =
|
||||
match.highlights.at(-1).bottom - scrollPanelRect.top - 2
|
||||
const y2 = match.highlights.at(-1).top - scrollPanelRect.top + 2
|
||||
drawWrongSpacing(x, y1, y2)
|
||||
const x = match.highlights.at(-1).right
|
||||
const y1 = match.highlights.at(-1).bottom - 2 * scale
|
||||
const y2 = match.highlights.at(-1).top + 2 * scale
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
// TODO
|
||||
const x = match.highlights.at(-1).right + 1 * scale
|
||||
const y1 = match.highlights.at(-1).bottom
|
||||
const y2 = match.highlights.at(-1).top
|
||||
this.drawMissingText(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale,
|
||||
replacement.substr(-lengthDiff).trim()
|
||||
)
|
||||
}
|
||||
|
||||
drawSideMarker(
|
||||
match.highlights.at(-1).top - scrollPanelRect.top,
|
||||
match.highlights.at(-1).bottom - scrollPanelRect.top
|
||||
)
|
||||
} else if (
|
||||
lengthDiff < 0 &&
|
||||
context.substr(-replacement.length) === replacement
|
||||
) {
|
||||
// Something to remove before
|
||||
const toRemove = context.substr(0, -lengthDiff)
|
||||
markerY1 = match.highlights[0].top
|
||||
markerY2 = match.highlights[0].bottom
|
||||
const scale = (markerY2 - markerY1) / 18
|
||||
|
||||
if (/^\s+$/.test(toRemove)) {
|
||||
const rect = this.makeRange(
|
||||
@ -471,31 +486,34 @@ class BesService {
|
||||
match.match.offset,
|
||||
match.match.offset - lengthDiff
|
||||
)?.getClientRects()[0]
|
||||
const x = (rect.left + rect.right) / 2 - scrollPanelRect.left
|
||||
const y1 = rect.top - scrollPanelRect.top
|
||||
const y2 = rect.bottom - scrollPanelRect.top
|
||||
drawWrongSpacing(x, y1, y2)
|
||||
const x = (rect.left + rect.right) / 2
|
||||
const y1 = rect.top
|
||||
const y2 = rect.bottom
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
for (let rect of this.makeRange(
|
||||
match.data,
|
||||
match.match.offset,
|
||||
match.match.offset - lengthDiff
|
||||
)?.getClientRects())
|
||||
drawExcessiveText(
|
||||
rect.left - scrollPanelRect.left,
|
||||
rect.bottom - scrollPanelRect.top,
|
||||
rect.right - scrollPanelRect.left,
|
||||
rect.top - scrollPanelRect.top
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
)
|
||||
}
|
||||
|
||||
drawSideMarker(
|
||||
match.highlights[0].top - scrollPanelRect.top,
|
||||
match.highlights[0].bottom - scrollPanelRect.top
|
||||
)
|
||||
} else if (context.substr(0, replacement.length) === replacement) {
|
||||
// Something to remove after
|
||||
const toRemove = context.substr(lengthDiff)
|
||||
markerY1 = match.highlights.at(-1).top
|
||||
markerY2 = match.highlights.at(-1).bottom
|
||||
const scale = (markerY2 - markerY1) / 18
|
||||
|
||||
if (/^\s+$/.test(toRemove)) {
|
||||
const rect = this.makeRange(
|
||||
@ -503,86 +521,308 @@ class BesService {
|
||||
match.match.offset + match.match.length + lengthDiff,
|
||||
match.match.offset + match.match.length
|
||||
)?.getClientRects()[0]
|
||||
const x = (rect.left + rect.right) / 2 - scrollPanelRect.left
|
||||
const y1 = rect.top - scrollPanelRect.top
|
||||
const y2 = rect.bottom - scrollPanelRect.top
|
||||
drawWrongSpacing(x, y1, y2)
|
||||
const x = (rect.left + rect.right) / 2
|
||||
const y1 = rect.top
|
||||
const y2 = rect.bottom
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
for (let rect of this.makeRange(
|
||||
match.data,
|
||||
match.match.offset + match.match.length + lengthDiff,
|
||||
match.match.offset + match.match.length
|
||||
)?.getClientRects())
|
||||
drawExcessiveText(
|
||||
rect.left - scrollPanelRect.left,
|
||||
rect.bottom - scrollPanelRect.top,
|
||||
rect.right - scrollPanelRect.left,
|
||||
rect.top - scrollPanelRect.top
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
)
|
||||
}
|
||||
|
||||
drawSideMarker(
|
||||
match.highlights.at(-1).top - scrollPanelRect.top,
|
||||
match.highlights.at(-1).bottom - scrollPanelRect.top
|
||||
)
|
||||
} else {
|
||||
// Sugesstion and context are different.
|
||||
// TODO
|
||||
const lengthL = BesService.commonPrefixLength(context, replacement)
|
||||
const lengthR = BesService.commonSuffixLength(context, replacement)
|
||||
if (
|
||||
lengthL + lengthR <
|
||||
Math.min(context.length, replacement.length) * 0.6
|
||||
) {
|
||||
// Replace everything.
|
||||
markerY1 = Math.min(...match.highlights.map(rect => rect.top))
|
||||
markerY2 = Math.max(...match.highlights.map(rect => rect.bottom))
|
||||
const scale =
|
||||
(match.highlights[0].bottom - match.highlights[0].top) / 18
|
||||
let first = true
|
||||
for (let rect of match.highlights) {
|
||||
if (first) {
|
||||
this.drawWrongText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY,
|
||||
scale,
|
||||
replacement
|
||||
)
|
||||
first = false
|
||||
} else {
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Patch differences.
|
||||
const rects = Array.from(
|
||||
this.makeRange(
|
||||
match.data,
|
||||
match.match.offset + lengthL,
|
||||
match.match.offset + match.match.length - lengthR
|
||||
)?.getClientRects()
|
||||
)
|
||||
markerY1 = Math.min(...rects.map(rect => rect.top))
|
||||
markerY2 = Math.max(...rects.map(rect => rect.bottom))
|
||||
|
||||
drawSideMarker(
|
||||
Math.min(...match.highlights.map(rect => rect.top)) -
|
||||
scrollPanelRect.top,
|
||||
Math.max(...match.highlights.map(rect => rect.bottom)) -
|
||||
scrollPanelRect.top
|
||||
)
|
||||
if (lengthL + lengthR === context.length) {
|
||||
// Something to insert
|
||||
const toInsert = replacement.substring(
|
||||
lengthL,
|
||||
replacement.length - lengthR
|
||||
)
|
||||
const scale = (rects[0].bottom - rects[0].top) / 18
|
||||
const x = rects[0].left
|
||||
|
||||
if (/^\s+$/.test(toInsert)) {
|
||||
const y1 = rects[0].bottom - 2 * scale
|
||||
const y2 = rects[0].top + 2 * scale
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
const y1 = rects[0].bottom
|
||||
const y2 = rects[0].top
|
||||
this.drawMissingText(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale,
|
||||
toInsert.trim()
|
||||
)
|
||||
}
|
||||
} else if (lengthL + lengthR === replacement.length) {
|
||||
// Something to remove
|
||||
const toRemove = context.substring(
|
||||
lengthL,
|
||||
replacement.length - lengthR
|
||||
)
|
||||
const scale = (rects[0].bottom - rects[0].top) / 18
|
||||
|
||||
if (/^\s+$/.test(toRemove)) {
|
||||
const x = (rects[0].left + rects[0].right) / 2
|
||||
const y1 = rects[0].top
|
||||
const y2 = rects[0].bottom
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
} else {
|
||||
for (let rect of rects)
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// Something to replace
|
||||
const toReplace = replacement.substring(
|
||||
lengthL,
|
||||
replacement.length - lengthR
|
||||
)
|
||||
const scale = (rects[0].bottom - rects[0].top) / 18
|
||||
let first = true
|
||||
for (let rect of rects) {
|
||||
if (first) {
|
||||
this.drawWrongText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY,
|
||||
scale,
|
||||
toReplace
|
||||
)
|
||||
first = false
|
||||
} else {
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TODO
|
||||
|
||||
drawSideMarker(
|
||||
Math.min(...match.highlights.map(rect => rect.top)) -
|
||||
scrollPanelRect.top,
|
||||
Math.max(...match.highlights.map(rect => rect.bottom)) -
|
||||
scrollPanelRect.top
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
// for (let rect of match.highlights) {
|
||||
// const x = (rect.left - scrollPanelRect.left) * dpr
|
||||
// const y = (rect.top - scrollPanelRect.top) * dpr
|
||||
// const width = rect.width * dpr
|
||||
// const height = rect.height * dpr
|
||||
|
||||
// // MOCKUP text drawing
|
||||
// this.ctx.font = `5px ${this.textFont}` // Font se lahko doda na sledeč način: `25px 'Times New Roman', serif`
|
||||
// const text = 'To je izmišljeno besedilo'
|
||||
// const textLength = this.ctx.measureText(text)
|
||||
// console.log(`Dolžina texta: ${textLength.width}px`) // Dolžina texta
|
||||
// this.ctx.fillText(text, x, y)
|
||||
// }
|
||||
break
|
||||
|
||||
default:
|
||||
for (let rect of match.highlights) {
|
||||
const x = (rect.left - scrollPanelRect.left) * dpr
|
||||
const y = (rect.top - scrollPanelRect.top) * dpr
|
||||
const width = rect.width * dpr
|
||||
const height = rect.height * dpr
|
||||
|
||||
// Draw the underline.
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(x, y + height)
|
||||
this.ctx.lineTo(x + width, y + height)
|
||||
this.ctx.stroke()
|
||||
const x1 = rect.left
|
||||
const x2 = rect.right
|
||||
const y = rect.bottom
|
||||
const scale = (rect.bottom - rect.top) / 18
|
||||
this.drawAttentionRequired(
|
||||
x1 - scrollX,
|
||||
x2 - scrollX,
|
||||
y - scrollY,
|
||||
scale
|
||||
)
|
||||
}
|
||||
|
||||
drawSideMarker(
|
||||
Math.min(...match.highlights.map(rect => rect.top)) -
|
||||
scrollPanelRect.top,
|
||||
Math.max(...match.highlights.map(rect => rect.bottom)) -
|
||||
scrollPanelRect.top
|
||||
)
|
||||
markerY1 = Math.min(...match.highlights.map(rect => rect.top))
|
||||
markerY2 = Math.max(...match.highlights.map(rect => rect.bottom))
|
||||
}
|
||||
|
||||
this.drawSideMarker(markerY1 - scrollY, markerY2 - scrollY)
|
||||
}
|
||||
|
||||
static commonPrefixLength(s1, s2) {
|
||||
let i = 0
|
||||
let len = Math.min(s1.length, s2.length)
|
||||
while (i < len && s1[i] === s2[i]) i++
|
||||
return i
|
||||
}
|
||||
|
||||
static commonSuffixLength(s1, s2) {
|
||||
let i = 0
|
||||
let i1 = s1.length
|
||||
let i2 = s2.length
|
||||
while (0 < i1-- && 0 < i2-- && s1[i1] === s2[i2]) i++
|
||||
return i
|
||||
}
|
||||
|
||||
drawSideMarker(y1, y2) {
|
||||
const dpr = window.devicePixelRatio
|
||||
const markerX = this.canvasPanel.width - 5 * dpr
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(markerX, y1 * dpr)
|
||||
this.ctx.lineTo(markerX, y2 * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
|
||||
drawMissingComma(x, y, scale, comment) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo((x - 2 * scale) * dpr, y * dpr)
|
||||
this.ctx.lineTo((x + 2 * scale) * dpr, y * dpr)
|
||||
this.ctx.lineTo((x + 2 * scale) * dpr, (y - 4 * scale) * dpr)
|
||||
this.ctx.stroke()
|
||||
|
||||
if (comment) {
|
||||
this.ctx.font = `${12 * scale * dpr}px ${this.textFont}`
|
||||
this.ctx.textAlign = 'center'
|
||||
this.ctx.textBaseline = 'bottom'
|
||||
this.ctx.fillText('?', (x + 2 * scale) * dpr, (y - 6 * scale) * dpr)
|
||||
}
|
||||
}
|
||||
|
||||
drawWrongSpacing(x, y1, y2, scale) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo((x - 4 * scale) * dpr, (y1 + 4 * scale) * dpr)
|
||||
this.ctx.lineTo(x * dpr, y1 * dpr)
|
||||
this.ctx.lineTo((x + 4 * scale) * dpr, (y1 + 4 * scale) * dpr)
|
||||
this.ctx.moveTo(x * dpr, y1 * dpr)
|
||||
this.ctx.lineTo(x * dpr, y2 * dpr)
|
||||
this.ctx.moveTo((x - 4 * scale) * dpr, (y2 - 4 * scale) * dpr)
|
||||
this.ctx.lineTo(x * dpr, y2 * dpr)
|
||||
this.ctx.lineTo((x + 4 * scale) * dpr, (y2 - 4 * scale) * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
|
||||
drawExcessiveText(x1, y1, x2, y2) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(x1 * dpr, y1 * dpr)
|
||||
this.ctx.lineTo(x2 * dpr, y2 * dpr)
|
||||
this.ctx.stroke()
|
||||
}
|
||||
|
||||
drawWrongText(x1, y1, x2, y2, scale, text) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(x1 * dpr, (y1 - 6 * scale) * dpr)
|
||||
this.ctx.lineTo(x2 * dpr, (y2 + 6 * scale) * dpr)
|
||||
this.ctx.stroke()
|
||||
|
||||
this.ctx.font = `${12 * scale * dpr}px ${this.textFont}`
|
||||
this.ctx.textAlign = 'left' // Thou we want the text to be centered, we align it manually to prevent it getting off canvas.
|
||||
this.ctx.textBaseline = 'bottom'
|
||||
const textMetrics = this.ctx.measureText(text)
|
||||
this.ctx.fillText(
|
||||
text,
|
||||
Math.max(
|
||||
Math.min(
|
||||
((x1 + x2) / 2) * dpr - textMetrics.width / 2,
|
||||
this.canvasPanel.width - textMetrics.width
|
||||
),
|
||||
0
|
||||
),
|
||||
(y2 + 6 * scale) * dpr
|
||||
)
|
||||
}
|
||||
|
||||
drawMissingText(x, y1, y2, scale, text) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo((x - 6 * scale) * dpr, y1 * dpr)
|
||||
this.ctx.lineTo((x + 6 * scale) * dpr, y1 * dpr)
|
||||
this.ctx.moveTo(x * dpr, y1 * dpr)
|
||||
this.ctx.lineTo(x * dpr, (y2 + 6 * scale) * dpr)
|
||||
this.ctx.stroke()
|
||||
|
||||
this.ctx.font = `${12 * scale * dpr}px ${this.textFont}`
|
||||
this.ctx.textAlign = 'left' // Thou we want the text to be centered, we align it manually to prevent it getting off canvas.
|
||||
this.ctx.textBaseline = 'bottom'
|
||||
const textMetrics = this.ctx.measureText(text)
|
||||
this.ctx.fillText(
|
||||
text,
|
||||
Math.max(
|
||||
Math.min(
|
||||
x * dpr - textMetrics.width / 2,
|
||||
this.canvasPanel.width - textMetrics.width
|
||||
),
|
||||
0
|
||||
),
|
||||
(y2 + 6 * scale) * dpr
|
||||
)
|
||||
}
|
||||
|
||||
drawAttentionRequired(x1, x2, y, scale) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.beginPath()
|
||||
this.ctx.moveTo(x1 * dpr, (y - scale) * dpr)
|
||||
for (let x = x1; ; ) {
|
||||
if (x >= x2) break
|
||||
this.ctx.lineTo((x += 2 * scale) * dpr, (y + scale) * dpr)
|
||||
if (x >= x2) break
|
||||
this.ctx.lineTo((x += 2 * scale) * dpr, (y - scale) * dpr)
|
||||
}
|
||||
this.ctx.stroke()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,11 +15,11 @@
|
||||
}
|
||||
|
||||
.bes-highlight-spelling-rect {
|
||||
background: rgb(255, 115, 0);
|
||||
background: rgb(0, 123, 255);
|
||||
}
|
||||
|
||||
.bes-highlight-grammar-rect {
|
||||
background: rgb(0, 123, 255);
|
||||
background: rgb(255, 115, 0);
|
||||
}
|
||||
|
||||
.bes-canvas {
|
||||
|
Loading…
x
Reference in New Issue
Block a user