Commit a368b0e6 by ramdayalmunda

focus when adding list or bullets

parent 5ce24a3b
...@@ -52,6 +52,9 @@ ...@@ -52,6 +52,9 @@
.toolbar .item:hover { .toolbar .item:hover {
background: #5fad5f; background: #5fad5f;
} }
[adc-type="popover"] {
pointer-events: none;
}
.option { .option {
border: 1px solid black; border: 1px solid black;
padding: 5px; padding: 5px;
......
...@@ -46,6 +46,7 @@ var ADocEditor = function (customConfig) { ...@@ -46,6 +46,7 @@ var ADocEditor = function (customConfig) {
style: { ...dataList[0].style, x: config.format.margin, y: config.format.margin + (3 * config.style.fontSize / 4) }, style: { ...dataList[0].style, x: config.format.margin, y: config.format.margin + (3 * config.style.fontSize / 4) },
} }
var pageList = [] var pageList = []
var pageScrollingDiv = null
var focussedPage = null var focussedPage = null
var lastFocussedPage = null var lastFocussedPage = null
var isRendering = false var isRendering = false
...@@ -67,7 +68,7 @@ var ADocEditor = function (customConfig) { ...@@ -67,7 +68,7 @@ var ADocEditor = function (customConfig) {
</div> </div>
</div> </div>
</div> </div>
<div class="page-list"></div> <div class="page-list" adc="page-list"></div>
<div class="footer"> <div class="footer">
<div class="toolbar"> <div class="toolbar">
...@@ -114,6 +115,7 @@ var ADocEditor = function (customConfig) { ...@@ -114,6 +115,7 @@ var ADocEditor = function (customConfig) {
header: shadow.querySelector('.header'), header: shadow.querySelector('.header'),
pageList: shadow.querySelector('page-list') pageList: shadow.querySelector('page-list')
} }
pageScrollingDiv = shadow.querySelector('[adc="page-list"]')
!(function zoomHandles() { !(function zoomHandles() {
...@@ -132,10 +134,7 @@ var ADocEditor = function (customConfig) { ...@@ -132,10 +134,7 @@ var ADocEditor = function (customConfig) {
...caretData.style, ...caretData.style,
fontFamily: e.target.value, fontFamily: e.target.value,
} }
if (lastFocussedPage) { focusOnPage()
lastFocussedPage.focus()
lastFocussedPage.scrollIntoView({ behavior: 'manual' })
}
}) })
addFonts(["./assets/fonts/Afacad-VariableFont_wght.woff2", "./assets/fonts/Afacad-VariableFont_wght.ttf"], 'Afacad') addFonts(["./assets/fonts/Afacad-VariableFont_wght.woff2", "./assets/fonts/Afacad-VariableFont_wght.ttf"], 'Afacad')
addFonts(["./assets/fonts/ArchitectsDaughter-Regular.woff2", "./assets/fonts/ArchitectsDaughter-Regular.ttf"], 'Architects Daughter') addFonts(["./assets/fonts/ArchitectsDaughter-Regular.woff2", "./assets/fonts/ArchitectsDaughter-Regular.ttf"], 'Architects Daughter')
...@@ -148,11 +147,15 @@ var ADocEditor = function (customConfig) { ...@@ -148,11 +147,15 @@ var ADocEditor = function (customConfig) {
!(function handleList(){ !(function handleList(){
let toggleNumber = shadow.querySelector('[adc-toggle="list-number"]') let toggleNumber = shadow.querySelector('[adc-toggle="list-number"]')
let toggleBullet = shadow.querySelector('[adc-toggle="list-bullet"]') let toggleBullet = shadow.querySelector('[adc-toggle="list-bullet"]')
let popover = shadow.querySelector('[adc-type="popover"]')
toggleNumber.addEventListener('click', (e)=>{ toggleNumber.addEventListener('click', (e)=>{
if (caretData.activeData){ if (caretData.activeData){
caretData.activeData.type = caretData.activeData.type==1?0:1 caretData.activeData.type = caretData.activeData.type==1?0:1
caretData.blink=false caretData.blink=false
reRenderCanvas() reRenderCanvas()
popover.classList.remove('show')
focusOnPage()
} }
}) })
toggleBullet.addEventListener('click', (e)=>{ toggleBullet.addEventListener('click', (e)=>{
...@@ -160,6 +163,8 @@ var ADocEditor = function (customConfig) { ...@@ -160,6 +163,8 @@ var ADocEditor = function (customConfig) {
caretData.activeData.type = caretData.activeData.type==1?0:1 caretData.activeData.type = caretData.activeData.type==1?0:1
caretData.blink=false caretData.blink=false
reRenderCanvas() reRenderCanvas()
popover.classList.remove('show')
focusOnPage()
} }
}) })
})() })()
...@@ -259,7 +264,9 @@ var ADocEditor = function (customConfig) { ...@@ -259,7 +264,9 @@ var ADocEditor = function (customConfig) {
let tempWordWidth = 0 let tempWordWidth = 0
for (c = 0; c < dataBlock.plainContent.length; c++) { for (c = 0; c < dataBlock.plainContent.length; c++) {
let style = dataBlock?.formatedText?.[c] let style = dataBlock?.formatedText?.[c]
if (/\s/.test(dataBlock.plainContent[c])) { if (/\s/.test(dataBlock.plainContent[c])) {
// condition to check if a blank character is found.
wordEndIndex = c wordEndIndex = c
lineObj.charEndIndex = c lineObj.charEndIndex = c
tempWordWidth = 0 tempWordWidth = 0
...@@ -271,13 +278,19 @@ var ADocEditor = function (customConfig) { ...@@ -271,13 +278,19 @@ var ADocEditor = function (customConfig) {
...style, ...style,
width: charWidth width: charWidth
} }
// // if with the current char the string could not fit on one line
if (tempLineWidth + charWidth > maxLineWidth){ if (tempLineWidth + charWidth > maxLineWidth){
// cannot add this// new line should be added// // cannot add this// new line should be added//
if (tempWordWidth+charWidth>=maxLineWidth){ if (tempWordWidth+charWidth>=maxLineWidth){
// this is to manage the casse where there is a set of long string without any blank space. In that case the text is broken and moved to next line.
wordEndIndex = c wordEndIndex = c
lineObj.charEndIndex = c lineObj.charEndIndex = c
tempWordWidth = 0 tempWordWidth = 0
} }
lineObj.plainContent = dataBlock.plainContent.slice(lineObj.charStartIndex, lineObj.charEndIndex + 1) lineObj.plainContent = dataBlock.plainContent.slice(lineObj.charStartIndex, lineObj.charEndIndex + 1)
lines.push(lineObj) lines.push(lineObj)
lineObj = new getLineObj() lineObj = new getLineObj()
...@@ -293,6 +306,7 @@ var ADocEditor = function (customConfig) { ...@@ -293,6 +306,7 @@ var ADocEditor = function (customConfig) {
tempLineWidth = tempWordWidth tempLineWidth = tempWordWidth
} }
else{ else{
// if the char can fit in the same line. then it is well and good
tempLineWidth += charWidth tempLineWidth += charWidth
tempWordWidth += charWidth tempWordWidth += charWidth
} }
...@@ -325,6 +339,10 @@ var ADocEditor = function (customConfig) { ...@@ -325,6 +339,10 @@ var ADocEditor = function (customConfig) {
lines[l].y = y lines[l].y = y
ctx.save() ctx.save()
// this is to render the numbering and bullets etc
let setData = dataList[lines[l].dataIndex] let setData = dataList[lines[l].dataIndex]
for (let c = lines[l].charStartIndex; c <= lines[l].charEndIndex; c++) { for (let c = lines[l].charStartIndex; c <= lines[l].charEndIndex; c++) {
let char = setData?.plainContent[c] let char = setData?.plainContent[c]
...@@ -348,57 +366,6 @@ var ADocEditor = function (customConfig) { ...@@ -348,57 +366,6 @@ var ADocEditor = function (customConfig) {
return return
} }
function renderCaret(toLoop) {
clearTimeout(caretData.timeout)
let ctx = pageList[0].el.getContext('2d', { willReadFrequently: true })
ctx.save()
if (caretData.previousCaret) {
ctx.putImageData(caretData.previousCaret.imageData, caretData.previousCaret.x, caretData.previousCaret.y);
caretData.previousCaret = null
}
if (!caretData.blink) {
let x = config.format.margin * pxMmRatio
let y = (config.format.margin) * pxMmRatio
let height = config.style.fontSize * pxMmRatio * 5 / 4
let charData = caretData.activeData.formatedText[caretData.index - 1]
if (charData) {
x = charData.x + charData.width
y = charData.y - charData.fontSize * pxMmRatio
} else {
let dataIndex = dataList.findIndex(item => item.id == caretData.activeData.id)
let lineObj = lines.find(item => item.dataIndex == dataIndex && caretData.index >= item.charStartIndex)
if (lineObj) {
x += lineObj.tabWidth
y = lineObj.y - lineObj.maxFontSize * pxMmRatio
}
}
let width = height / 10
const imageData = ctx.getImageData(x, y, width, height);
const data = imageData.data;
caretData.previousCaret = { imageData: structuredClone(imageData), x, y }
// Invert the color of the rectangular region
for (let i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i]; // Red
data[i + 1] = 255 - data[i + 1]; // Green
data[i + 2] = 255 - data[i + 2]; // Blue
// Alpha channel remains unchanged (data[i + 3])
}
ctx.putImageData(imageData, x, y);
caretData.blink = true
} else {
caretData.blink = false
}
ctx.restore()
if (toLoop) {
caretData.timeout = setTimeout(() => {
renderCaret(true)
}, caretData.timeoutDuration)
}
return
}
function getCharacterWidth(char, style) { function getCharacterWidth(char, style) {
let canvas = pageList[0].el let canvas = pageList[0].el
let ctx = canvas.getContext('2d', { willReadFrequently: true }) let ctx = canvas.getContext('2d', { willReadFrequently: true })
...@@ -653,7 +620,7 @@ var ADocEditor = function (customConfig) { ...@@ -653,7 +620,7 @@ var ADocEditor = function (customConfig) {
function globalMouseDownHandler(e){ function globalMouseDownHandler(e){
var elem = e.target var elem = e.target
var targetId = elem.getAttribute('adc-target') var targetId = elem.getAttribute('adc-target')
if (elem.getAttribute('adc-type')=='popover') return if (elem.getAttribute('adc-type')=='popover'){ return }
while(!targetId && elem){ while(!targetId && elem){
elem = elem.parentNode elem = elem.parentNode
if (elem?.getAttribute?.('adc-type')=='popover') return if (elem?.getAttribute?.('adc-type')=='popover') return
...@@ -666,6 +633,67 @@ var ADocEditor = function (customConfig) { ...@@ -666,6 +633,67 @@ var ADocEditor = function (customConfig) {
} ) } )
} }
function renderCaret(toLoop) {
clearTimeout(caretData.timeout)
let ctx = pageList[0].el.getContext('2d', { willReadFrequently: true })
ctx.save()
if (caretData.previousCaret) {
ctx.putImageData(caretData.previousCaret.imageData, caretData.previousCaret.x, caretData.previousCaret.y);
caretData.previousCaret = null
}
if (!caretData.blink) {
let x = config.format.margin * pxMmRatio
let y = (config.format.margin) * pxMmRatio
let height = config.style.fontSize * pxMmRatio * 5 / 4
let charData = caretData.activeData.formatedText[caretData.index - 1]
if (charData) {
x = charData.x + charData.width
y = charData.y - charData.fontSize * pxMmRatio
} else {
let dataIndex = dataList.findIndex(item => item.id == caretData.activeData.id)
let lineObj = lines.find(item => item.dataIndex == dataIndex && caretData.index >= item.charStartIndex)
if (lineObj) {
x += lineObj.tabWidth
y = lineObj.y - lineObj.maxFontSize * pxMmRatio
}
}
let width = height / 10
const imageData = ctx.getImageData(x, y, width, height);
const data = imageData.data;
caretData.previousCaret = { imageData: structuredClone(imageData), x, y }
// Invert the color of the rectangular region
for (let i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i]; // Red
data[i + 1] = 255 - data[i + 1]; // Green
data[i + 2] = 255 - data[i + 2]; // Blue
// Alpha channel remains unchanged (data[i + 3])
}
ctx.putImageData(imageData, x, y);
caretData.blink = true
} else {
caretData.blink = false
}
ctx.restore()
if (toLoop) {
caretData.timeout = setTimeout(() => {
renderCaret(true)
}, caretData.timeoutDuration)
}
return
}
function focusOnPage(){
caretData.blink = false
if (lastFocussedPage){
const scrollTop = pageScrollingDiv.scrollTop
lastFocussedPage.focus()
pageScrollingDiv.scrollTop = scrollTop
}
}
var returnObj = { var returnObj = {
addFonts, addFonts,
getConfiguration() { return JSON.parse(JSON.stringify(config)) }, getConfiguration() { return JSON.parse(JSON.stringify(config)) },
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
<body> <body>
<div class="body"></div> <div class="body"></div>
<p style="font-family: 'Calibri';">Click on the <span>canvas</span> and start typing <p style="font-family: 'Calibri';">Click on the <span>canvas</span> and start typing
<input />
<button onclick="log()">Log</button> <button onclick="log()">Log</button>
<button onclick="setData()">Set Data</button> <button onclick="setData()">Set Data</button>
<button onclick="generatePDF()">Generate PDF</button> <button onclick="generatePDF()">Generate PDF</button>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment