Revise canvas management
This commit is contained in:
parent
661449c2b7
commit
a5db3099c6
@ -10,8 +10,8 @@
|
||||
<script src="../service.js"></script>
|
||||
<script src="common.js"></script>
|
||||
</head>
|
||||
<body style="background-color: gray;">
|
||||
<!-- <p class="my-block">This is an example of a simple <code><div contenteditable="true"></code> edit control. Edit the text, resize the control or browser window, scroll around, click...</p> -->
|
||||
<body>
|
||||
<p class="my-block">This is an example of a simple <code><div contenteditable="true"></code> edit control. Edit the text, resize the control or browser window, scroll around, click...</p>
|
||||
<div id="my-editor" class="my-block my-control" contenteditable="true">
|
||||
<p>Tukaj vpišite besedilo ki ga želite popraviti.</p>
|
||||
<p>Prišla je njena lepa hčera. Smatram da tega nebi bilo potrebno storiti. Predavanje je trajalo dve ure. S njim grem v Kamnik. Janez jutri nebo prišel. Prišel je z 100 idejami.</p>
|
||||
|
178
service.js
178
service.js
@ -279,6 +279,7 @@ class BesService {
|
||||
// Scroll panel is "position: absolute", we need to keep it aligned with the host element.
|
||||
this.scrollPanel.style.top = `${-this.hostElement.scrollTop}px`
|
||||
this.scrollPanel.style.left = `${-this.hostElement.scrollLeft}px`
|
||||
|
||||
if (this.hostElement !== this.textElement) {
|
||||
this.textElement.scrollTop = this.hostElement.scrollTop
|
||||
this.textElement.scrollLeft = this.hostElement.scrollLeft
|
||||
@ -314,11 +315,7 @@ class BesService {
|
||||
rect.left !== this.hostBoundingClientRect.left
|
||||
)
|
||||
this.onReposition()
|
||||
if (
|
||||
rect.width !== this.hostBoundingClientRect.width ||
|
||||
rect.height !== this.hostBoundingClientRect.height
|
||||
)
|
||||
this.onResize()
|
||||
this.onResize()
|
||||
this.hostBoundingClientRect = rect
|
||||
}
|
||||
|
||||
@ -330,62 +327,29 @@ class BesService {
|
||||
* @returns {Array} Grammar mistake highlight elements
|
||||
*/
|
||||
addMistakeMarkup(range, ruleId) {
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
const highlights = []
|
||||
this.canvasPanel.classList.add('bes-canvas')
|
||||
|
||||
this.ctx.lineWidth = 1
|
||||
const scrollPanelRect = this.scrollPanel.getBoundingClientRect()
|
||||
let highlights = []
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.lineWidth = 1 * dpr
|
||||
this.ctx.strokeStyle = ruleId.startsWith('MORFOLOGIK_RULE')
|
||||
? '#e91313'
|
||||
: '#269b26'
|
||||
|
||||
for (let rect of range.getClientRects()) {
|
||||
const x = rect.left - canvasPanelRect.left
|
||||
const y = rect.top - canvasPanelRect.top + rect.height
|
||||
const width = rect.width
|
||||
const height = rect.height
|
||||
|
||||
const globalX = rect.left + window.scrollX
|
||||
const globalY = rect.top + window.scrollY
|
||||
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)
|
||||
this.ctx.lineTo(x + width, y)
|
||||
this.ctx.moveTo(x, y + height)
|
||||
this.ctx.lineTo(x + width, y + height)
|
||||
this.ctx.stroke()
|
||||
const rectCoords = { x, y, width, height, globalX, globalY }
|
||||
highlights.push(rectCoords)
|
||||
highlights.push(rect)
|
||||
}
|
||||
|
||||
return highlights
|
||||
}
|
||||
|
||||
// addMistakeMarkup(range, ruleId) {
|
||||
// const scrollPanelRect = this.scrollPanel.getBoundingClientRect()
|
||||
// let highlights = []
|
||||
// for (let rect of range.getClientRects()) {
|
||||
// const highlight = document.createElement('div')
|
||||
// highlight.classList.add(
|
||||
// ruleId.startsWith('MORFOLOGIK_RULE')
|
||||
// ? 'bes-spelling-mistake'
|
||||
// : 'bes-grammar-mistake'
|
||||
// )
|
||||
// highlight.style.left = `${rect.left - scrollPanelRect.left}px`
|
||||
// highlight.style.top = `${rect.top - scrollPanelRect.top}px`
|
||||
// highlight.style.width = `${rect.width}px`
|
||||
// highlight.style.height = `${rect.height}px`
|
||||
// this.scrollPanel.appendChild(highlight)
|
||||
// highlights.push(highlight)
|
||||
// }
|
||||
// return highlights
|
||||
// }
|
||||
// highlight.style.left = `${rect.left - scrollPanelRect.left}px`
|
||||
// highlight.style.top = `${rect.top - scrollPanelRect.top}px`
|
||||
// highlight.style.width = `${rect.width}px`
|
||||
// highlight.style.height = `${rect.height}px`
|
||||
// this.scrollPanel.appendChild(highlight)
|
||||
// highlights.push(highlight)
|
||||
|
||||
/**
|
||||
* Tests if given coordinate is inside of a rectangle.
|
||||
*
|
||||
@ -394,28 +358,8 @@ class BesService {
|
||||
* @param {DOMRect} rect Rectangle
|
||||
* @returns
|
||||
*/
|
||||
static isPointInRect(x, y, rect, canvasPanel) {
|
||||
const canvasRect = canvasPanel.getBoundingClientRect()
|
||||
const globalWidth = rect.x + rect.width
|
||||
const globalHeight = rect.y - rect.height
|
||||
|
||||
const newX = x - canvasRect.left
|
||||
const newY = y - canvasRect.top
|
||||
console.log(
|
||||
'x:',
|
||||
newX,
|
||||
'y:',
|
||||
newY,
|
||||
'globalWidth:',
|
||||
globalWidth,
|
||||
'globalHeight:',
|
||||
globalHeight
|
||||
)
|
||||
console.log(rect)
|
||||
return (
|
||||
rect.x <= newX && newX < globalWidth && globalHeight <= newY && newY < y
|
||||
)
|
||||
// return rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom
|
||||
static isPointInRect(x, y, rect) {
|
||||
return rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom
|
||||
}
|
||||
|
||||
/**
|
||||
@ -432,6 +376,9 @@ class BesService {
|
||||
this.scrollPanel.classList.add('bes-correction-panel-scroll')
|
||||
|
||||
this.canvasPanel = document.createElement('canvas')
|
||||
this.canvasPanel.classList.add('bes-canvas')
|
||||
this.ctx = this.canvasPanel.getContext('2d')
|
||||
this.ctx.scale(1, 1)
|
||||
|
||||
panelParent.appendChild(this.correctionPanel)
|
||||
this.correctionPanel.appendChild(this.scrollPanel)
|
||||
@ -446,6 +393,7 @@ class BesService {
|
||||
clearCorrectionPanel() {
|
||||
this.correctionPanel.remove()
|
||||
this.scrollPanel.remove()
|
||||
this.canvasPanel.remove()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -465,8 +413,16 @@ class BesService {
|
||||
this.scrollPanel.style.height = `${this.hostElement.scrollHeight}px`
|
||||
this.canvasPanel.style.width = `${this.hostElement.scrollWidth}px`
|
||||
this.canvasPanel.style.height = `${this.hostElement.scrollHeight}px`
|
||||
this.ctx = this.canvasPanel.getContext('2d')
|
||||
this.setCanvasDpr()
|
||||
const dpr = window.devicePixelRatio
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
if (
|
||||
this.canvasPanel.width !== canvasPanelRect.width * dpr ||
|
||||
this.canvasPanel.height !== canvasPanelRect.height * dpr
|
||||
) {
|
||||
this.canvasPanel.width = canvasPanelRect.width * dpr
|
||||
this.canvasPanel.height = canvasPanelRect.height * dpr
|
||||
this.repositionAllMarkup()
|
||||
}
|
||||
if (this.isHostElementInline()) {
|
||||
const totalWidth =
|
||||
parseFloat(styles.paddingLeft) +
|
||||
@ -482,21 +438,6 @@ class BesService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets canvas panel device pixel ratio.
|
||||
*/
|
||||
setCanvasDpr() {
|
||||
const dpr = window.devicePixelRatio || 1
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
this.canvasPanel.width = canvasPanelRect.width * dpr
|
||||
this.canvasPanel.height = canvasPanelRect.height * dpr
|
||||
this.ctx.scale(dpr, dpr)
|
||||
if (!this.ctx) {
|
||||
this.ctx = this.canvasPanel.getContext('2d')
|
||||
}
|
||||
this.ctx.scale(dpr, dpr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays correction panel.
|
||||
*
|
||||
@ -544,16 +485,16 @@ class BesService {
|
||||
* Updates all grammar mistake markup positions.
|
||||
*/
|
||||
repositionAllMarkup() {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.clearRect(
|
||||
0,
|
||||
0,
|
||||
this.canvasPanel.width * dpr,
|
||||
this.canvasPanel.height * dpr
|
||||
)
|
||||
this.results.forEach(result => {
|
||||
result.matches.forEach(match => {
|
||||
if (match.highlights) {
|
||||
match.highlights.forEach(h => {
|
||||
this.ctx.clearRect(h.x - 2, h.y - 2, h.width + 4, h.height)
|
||||
})
|
||||
|
||||
delete match.highlights
|
||||
// match.highlights.forEach(h => h.remove())
|
||||
}
|
||||
if (match.highlights) delete match.highlights
|
||||
match.highlights = this.addMistakeMarkup(
|
||||
match.range,
|
||||
match.match.rule.id
|
||||
@ -812,22 +753,22 @@ class BesTreeService extends BesService {
|
||||
* @param {Element} el DOM element we want to clean markup for
|
||||
*/
|
||||
clearMarkup(el) {
|
||||
const dpr = window.devicePixelRatio
|
||||
this.results
|
||||
.filter(result => BesTreeService.isSameParagraph(result.element, el))
|
||||
.forEach(result =>
|
||||
result.matches.forEach(match => {
|
||||
console.log(match)
|
||||
if (match.highlights) {
|
||||
// match.highlights.forEach(h => h.remove())
|
||||
match.highlights.forEach(h => {
|
||||
console.log(h)
|
||||
// Figure out why i need to add 2px to width
|
||||
this.ctx.clearRect(h.x - 2, h.y - 2, h.width + 4, h.height)
|
||||
})
|
||||
delete match.highlights
|
||||
}
|
||||
})
|
||||
)
|
||||
.forEach(result => {
|
||||
let sourceRect = result.element.getBoundingClientRect()
|
||||
let targetRect = this.canvasPanel.getBoundingClientRect()
|
||||
let newX = sourceRect.left - targetRect.left
|
||||
let newY = sourceRect.top - targetRect.top
|
||||
this.ctx.clearRect(
|
||||
newX * dpr,
|
||||
newY * dpr,
|
||||
sourceRect.width * dpr,
|
||||
sourceRect.height * dpr
|
||||
)
|
||||
delete result.matches
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -967,14 +908,7 @@ class BesTreeService extends BesService {
|
||||
for (let result of this.results) {
|
||||
for (let m of result.matches) {
|
||||
for (let h of m.highlights) {
|
||||
if (
|
||||
BesService.isPointInRect(
|
||||
source.clientX,
|
||||
source.clientY,
|
||||
h,
|
||||
this.canvasPanel
|
||||
)
|
||||
) {
|
||||
if (BesService.isPointInRect(source.clientX, source.clientY, h)) {
|
||||
this.popupCorrectionPanel(el, m, source)
|
||||
return
|
||||
}
|
||||
@ -1647,13 +1581,7 @@ class BesPlainTextService extends BesService {
|
||||
for (let result of this.results) {
|
||||
for (let m of result.matches) {
|
||||
for (let h of m.highlights) {
|
||||
if (
|
||||
BesService.isPointInRect(
|
||||
source.clientX,
|
||||
source.clientY,
|
||||
h.getBoundingClientRect()
|
||||
)
|
||||
) {
|
||||
if (BesService.isPointInRect(source.clientX, source.clientY, h)) {
|
||||
this.popupCorrectionPanel(result.range, m, source)
|
||||
return
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
/* TODO: Cleanup */
|
||||
.bes-grammar-mistake {
|
||||
border-bottom: 2px solid #007bff;
|
||||
position: absolute;
|
||||
@ -21,11 +22,13 @@
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
/* TODO: Cleanup */
|
||||
.bes-spelling-mistake.bes-mistake-highlight-selected {
|
||||
background: #cc7024;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* TODO: Cleanup */
|
||||
.bes-grammar-mistake.bes-mistake-highlight-selected {
|
||||
background: #3691f3;
|
||||
opacity: 0.5;
|
||||
|
Loading…
x
Reference in New Issue
Block a user