Commit a04a308e by ramdayalmunda

managed library to work on both, node and browser

parent 4bea5711
let isModule = (typeof module != 'undefined') ? true : false
const { jsPDF } = require("jspdf");
const { createCanvas } = require('canvas')
var ADocEditor = function (customConfig) {
var counter = 7
var screen = { width: 1366, height: 720 }
var defaultConfig = {
element: "",
pageSetup: {
width: 210,
height: 110,
},
format: {
background: "#fff",
margin: 20,
border: "",
fontSize: 10,
tabWidth: 20,
},
style: {
fontSize: 30,
fontFamily: 'Arial',
bold: false,
italic: false,
fontColor: "#001"
},
}
var config = JSON.parse(JSON.stringify(defaultConfig));
var canvasList = []
const dataTypes = [
"paragraph", // simple text filled line by line
"list", // sequence of line that preserves indentation
]
var dataSet = [
{
id: ++counter,
type: 0,
formatedText: [],
plainContent: "",
tabCount: 0,
style: { ...config.style }
},
]
// // paragraphs // this line is added only for testing please remove this on completion
dataSet = JSON.parse('[{"id":1,"type":0,"formatedText":[],"plainContent":"Rendering text in HTML canvas involves using the CanvasRenderingContext2D interface to display text content within a canvas element. This process allows for dynamic text display, enabling the creation of custom text effects, labels, captions, or textual elements within the canvas.","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#001"}},{"id":2,"type":0,"plainContent":"To render text on a canvas, developers typically use the fillText() method provided by the Canvas API. This method allows the specification of text content, font styles, position, and color. Additionally, the measureText() method helps in determining the width of text, facilitating accurate positioning and layout arrangements.","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#001"}},{"id":3,"type":0,"plainContent":"Text in canvas can be customized by setting various font properties like font family, font size, style (bold, italic), alignment, and color. However, canvas text rendering lacks the text reflow and responsive layout capabilities inherent in HTML and CSS.","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#001"}},{"id":4,"type":0,"plainContent":"Despite its intricacies, canvas text rendering offers unparalleled creative freedom, enabling the development of immersive graphical experiences, custom typography, and visually stunning representations that enhance user engagement and interactivity within web-based applications and games.","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#001"}},{"id":5,"type":0,"plainContent":"Developers often use canvas text rendering to create graphical representations of text-based information, such as game interfaces, data visualizations, charts, and diagrams. Despite its flexibility in text manipulation and artistic possibilities, rendering text in canvas may require additional manual adjustments for formatting, spacing, and alignment compared to traditional HTML text rendering.","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#001"}}]')
// // lists // this line is added only for testing please remove this on completion
dataSet = JSON.parse('[{"id":1,"type":0,"plainContent":"Here is a list of household items you need to buy if you are relocating and don\'t have anything with you","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":2,"type":1,"tabCount":0,"plainContent":"Recipie book for vegetarian noodles","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":3,"type":1,"tabCount":0,"plainContent":"Noodles","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":5,"type":1,"tabCount":0,"plainContent":"Garlic","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":6,"type":1,"tabCount":0,"plainContent":"Some School stationaries for Arvind","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":7,"type":1,"tabCount":1,"plainContent":"Full pack of pen","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":8,"type":1,"tabCount":1,"plainContent":"Drawing kit","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":9,"type":1,"tabCount":1,"plainContent":"2 register size notebook","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":10,"type":1,"tabCount":0,"plainContent":"Window shields","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]},{"id":11,"type":1,"tabCount":0,"plainContent":"Mosquito repelant","style":{"fontSize":30,"fontFamily":"Arial","bold":false,"italic":false,"fontColor":"#003"},"formatedText":[]}]')
var lines = []
var caretData = {
activeData: dataSet[0],
index: 0,
interval: null,
intervalDuration: 800,
blink: false,
canvasIndex: 0,
caretSize: config.style.fontSize,
x: config.format.margin,
y: config.format.margin + (3 * config.style.fontSize / 4),
previousCaret: null,
}
var renderInProgress = false;
function inititalize(customConfig) {
config = { ...defaultConfig, ...customConfig }
config.pageSetup.canvasMultiplier = Math.round(screen.width / config.pageSetup.width)
config.pageSetup.canvasWidth = config.pageSetup.canvasMultiplier * config.pageSetup.width
config.pageSetup.canvasHeight = config.pageSetup.canvasMultiplier * config.pageSetup.height
reRenderPages(dataSet)
}
function reRenderPages(dataList, option) {
if (renderInProgress) return
renderInProgress = true
let canvasIndex = 0
if (!canvasList.length) canvasList[0] = { el: createNewCanvas(), dataIndex: 0 }
// to clear the canvases
for (let i = 0; i < canvasList.length; i++) {
let ctx = canvasList[i].el.getContext('2d', { willReadFrequently: true })
ctx.save()
ctx.clearRect(0, 0, canvasList[i].el.width, canvasList[i].el.height); // clears the canvas
ctx.fillStyle = config.format.background
ctx.fillRect(0, 0, canvasList[i].el.width, canvasList[i].el.height)
ctx.restore()
}
lines = []
for (let i = 0; i < dataList.length; i++) {
calculateTextSizeAndPosition(canvasIndex, i)
}
renderTheLines()
if (!caretData.blink && caretData.activeData) renderCaret()
function calculateTextSizeAndPosition(canvasIndex, dataSetIndex) {
let dataBlock = dataList[dataSetIndex]
let canvas = canvasList[canvasIndex].el
let ctx = canvas.getContext('2d', { willReadFrequently: true })
ctx.save()
// to calculate the lines
let dataLineArr = []
function getLineObj() {
return {
x: 0, // this is the starting point x; it will change based on the tabNumber
y: 0, // this is the starting y coordinate; it will change based on the max font size
plainContent: "",
fontSize: 30,
maxFontSize: 30,
dataSetIndex: dataSetIndex,
charStartIndex: 0, // index from where to check
charEndIndex: 0, // index till where to check// not including this index.
}
}
if (!dataBlock.formatedText) dataBlock.formatedText = []
let lineObj = new getLineObj()
dataLineArr.push(lineObj)
lineObj.type = dataBlock.type
lineObj.blockStart = true
let wordEndIndex = 0; // this stores the index of the word which can fit in the line;
let tempLineWidth = 0;
let maxLineWidth = config.pageSetup.canvasWidth - (config.format.margin * 2 * config.pageSetup.canvasMultiplier)
if (dataBlock.tabCount || dataBlock.type == 1) {
let finalTabCount = dataBlock.tabCount
if (dataBlock.type == 1) {
finalTabCount++
}
let tabDistance = finalTabCount * config.format.tabWidth * config.pageSetup.canvasMultiplier
if (tabDistance > maxLineWidth * 5 / 6) { tabDistance = 0 }
maxLineWidth = maxLineWidth - tabDistance
}
lineObj.maxLineWidth = maxLineWidth
lineObj.tabCount = dataBlock.tabCount
// // for checking the listIndex
if (dataBlock.type == 1) {
for (let i = dataSetIndex - 1; i >= 0; i--) {
if (dataList[i].type != 1) {
dataBlock.listIndex = 0
break;
} else if (dataList[i].tabCount == dataBlock.tabCount) {
dataBlock.listIndex = dataList[i].listIndex + 1
break
} else if (dataList[i].tabCount < dataBlock.tabCount) {
dataBlock.listIndex = 0
break;
}
}
}
lineObj.listIndex = dataBlock.listIndex
let i = 0
for (i = 0; i < dataBlock.plainContent.length; i++) {
let style = dataBlock?.formatedText?.[i]
if (!style) style = JSON.parse(JSON.stringify(config.style))
if (/\s/.test(dataBlock.plainContent[i])) {
wordEndIndex = i
lineObj.charEndIndex = wordEndIndex;
}
let charWidth = getCharacterWidth(canvasIndex, dataBlock.plainContent[i], style)
dataBlock.formatedText[i] = {
...config.style,
width: charWidth
}
lineObj.maxFontSize = style.fontSize
// lineObj.fontSize = style.fontSize
tempLineWidth += charWidth
if (tempLineWidth <= maxLineWidth) {
// can be added to the line //
} else {
// cannot add this// new line should be added//
i = wordEndIndex;
lineObj.plainContent = dataBlock.plainContent.slice(lineObj.charStartIndex, lineObj.charEndIndex + 1)
lineObj = new getLineObj()
lineObj.listIndex = dataBlock.listIndex
lineObj.maxLineWidth = maxLineWidth
lineObj.tabCount = dataBlock.tabCount
lineObj.charStartIndex = i
lineObj.charEndIndex = i
dataLineArr.push(lineObj)
tempLineWidth = 0
}
}
lineObj.plainContent = dataBlock.plainContent.slice(lineObj.charStartIndex, lineObj.charEndIndex + 1)
// there is chance that the last line is not at the width// so we need to handle the last line separately
if (lineObj.charEndIndex <= dataBlock.plainContent.length) {
lineObj.charEndIndex = dataBlock.plainContent.length - 1
}
lineObj.plainContent = dataBlock.plainContent.slice(lineObj.charStartIndex, lineObj.charEndIndex)
lines.push(...dataLineArr)
ctx.restore()
return true
}
function renderTheLines() {
let canvasIndex = 0
let ctx = canvasList[canvasIndex].el.getContext('2d', { willReadFrequently: true })
let x = 0
let y = (config.format.margin * config.pageSetup.canvasMultiplier)
let maxVericalWidth = (config.pageSetup.canvasHeight - config.format.margin * config.pageSetup.canvasMultiplier * 2)
for (let l = 0; l < lines.length; l++) {
x = (config.format.margin * config.pageSetup.canvasMultiplier);
y += lines[l].maxFontSize
if (lines[l].blockStart && l != 0) y += lines[l].maxFontSize
if ((maxVericalWidth + lines[l].maxFontSize) < (y - lines[l].maxFontSize)) {
canvasIndex++
if (!canvasList[canvasIndex]) {
canvasList[canvasIndex] = { id: ++counter, el: createNewCanvas(), dataIndex: lines[l].dataSetIndex, lineIndex: l }
}
ctx = canvasList[canvasIndex].el.getContext('2d', { willReadFrequently: true })
y = lines[l].maxFontSize + (config.format.margin * config.pageSetup.canvasMultiplier)
}
let setData = dataSet[lines[l].dataSetIndex]
lines[l].y = y
if (lines[l].listIndex >= 0) {
let totalTabDistance = config.format.tabWidth * config.pageSetup.canvasMultiplier * (lines[l].tabCount + 1)
x += totalTabDistance;
let numberX = x - config.format.tabWidth * config.pageSetup.canvasMultiplier / 2
if (lines[l].blockStart) {
let style = {
...config.style,
...setData.style
}
ctx.save()
ctx.fillStyle = `${style.fontColor}`
ctx.font = `${style.bold ? 'bold ' : ''}${style.italic ? 'italic ' : ''} ${style.fontSize}px ${style.fontFamily}`
ctx.fillText(`${lines[l].listIndex + 1}.`, numberX, y)
ctx.restore()
}
}
lines[l].x = x
lines[l].canvasIndex = canvasIndex
for (let c = lines[l].charStartIndex; c <= lines[l].charEndIndex; c++) {
let char = setData?.plainContent[c]
if (char) {
let style = setData.formatedText[c]
ctx.save()
ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize}px ${style.fontFamily}`
ctx.fillStyle = `${style?.fontColor}`
ctx.fillText(char, x, y)
setData.formatedText[c].x = x
setData.formatedText[c].y = y
ctx.restore()
if (setData.formatedText[c]?.width) {
x += setData.formatedText[c]?.width
}
}
}
}
}
// to render caret
function renderCaret() {
let ctx = canvasList[caretData.canvasIndex].el.getContext('2d', { willReadFrequently: true })
ctx.save()
let activeDataIndex = dataSet.findIndex(item => item.id == caretData.activeData.id)
let activeLine = lines.find((item, i) => {
if (item.dataSetIndex == activeDataIndex) {
if (item.charEndIndex == -1) return true
if (item.charEndIndex >= caretData.index) return true
if (!(lines[i + 1]?.dataSetIndex == activeDataIndex)) return true
else false
} else return false
})
// handle left right on multiple pages
if (activeLine) {
caretData.canvasIndex = activeLine.canvasIndex
ctx.restore()
ctx = canvasList[activeLine.canvasIndex].el.getContext('2d', { willReadFrequently: true })
ctx.save()
}
let characterData = dataSet[activeDataIndex].formatedText[caretData.index]
let rectX = characterData?.x,
rectY = activeLine.y - activeLine.maxFontSize,
rectWidth = 2,
rectHeight = 5 * activeLine.maxFontSize / 4;
if (!characterData && dataSet[activeDataIndex].formatedText?.[caretData.index - 1]) {
rectX = dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.x + dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.width
}
if (activeLine.charEndIndex == caretData.index) {
rectX = dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.x + dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.width
}
if (!(rectX > 0 || rectX == 0)) { rectX = activeLine.x }
const imageData = ctx.getImageData(rectX, rectY, rectWidth, rectHeight);
const data = imageData.data;
// 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, rectX, rectY);
}
ctx.restore()
}
function getCharacterWidth(canvasIndex, char, style) {
let canvas = canvasList[canvasIndex].el
let ctx = canvas.getContext('2d', { willReadFrequently: true })
ctx.save()
ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize}px ${style.fontFamily}`
ctx.fillStyle = `${style?.fontColor}`
let width = ctx.measureText(char).width
ctx.restore()
return width
}
function createNewCanvas() {
let canvas = createCanvas(config.pageSetup.canvasWidth, config.pageSetup.canvasHeight)
let ctx = canvas.getContext('2d', { willReadFrequently: true })
ctx.fillStyle = config.format.background
ctx.fillRect(0, 0, canvas.width, canvas.height)
return canvas
}
renderInProgress = false
}
function generatePDF(fileName) {
if (isModule) {
console.log('to generate PDF on Server side', config.pageSetup)
const doc = new jsPDF('l', 'px', [660, 1260]);
let canvasIndex = 0;
let x = 0
let y = (config.format.margin * config.pageSetup.canvasMultiplier)
let maxVericalWidth = (config.pageSetup.canvasHeight - config.format.margin * config.pageSetup.canvasMultiplier * 2)
for (let l = 0; l < lines.length; l++) {
x = (config.format.margin * config.pageSetup.canvasMultiplier);
y += lines[l].maxFontSize
if (lines[l].blockStart && l != 0) y += lines[l].maxFontSize
if ((maxVericalWidth + lines[l].maxFontSize) < (y - lines[l].maxFontSize)) {
canvasIndex++
doc.addPage()
console.log('new page added')
y = lines[l].maxFontSize + (config.format.margin * config.pageSetup.canvasMultiplier)
}
let setData = dataSet[lines[l].dataSetIndex]
lines[l].y = y
if (lines[l].listIndex >= 0) {
let totalTabDistance = config.format.tabWidth * config.pageSetup.canvasMultiplier * (lines[l].tabCount + 1)
x += totalTabDistance;
let numberX = x - config.format.tabWidth * config.pageSetup.canvasMultiplier / 2
if (lines[l].blockStart) {
let style = {
...config.style,
...setData.style
}
}
}
lines[l].x = x
lines[l].canvasIndex = canvasIndex
for (let c = lines[l].charStartIndex; c <= lines[l].charEndIndex; c++) {
let char = setData?.plainContent[c]
if (char) {
let style = setData.formatedText[c]
doc.setFont('times')
doc.setFontSize(style.fontSize)
doc.text( char, x, y )
// ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize}px ${style.fontFamily}`
// ctx.fillStyle = `${style?.fontColor}`
// ctx.fillText(char, x, y)
setData.formatedText[c].x = x
setData.formatedText[c].y = y
if (setData.formatedText[c]?.width) {
x += setData.formatedText[c]?.width
}
}
}
}
doc.save(fileName);
} else {
console.log('to generate PDF on browser')
}
}
inititalize(customConfig)
function destory() {
clearInterval(caretData.interval)
}
var returnObj = {
destory,
loadContent: function (data) {
dataSet = JSON.parse(JSON.stringify(data))
reRenderPages(dataSet)
caretData.activeData = null
caretData.activeData = dataSet[0]
caretData.index = 0
},
getContent: function () {
return JSON.parse(JSON.stringify(dataSet))
},
generatePDF,
}
return returnObj
}
if (isModule) module.exports = ADocEditor
\ No newline at end of file
let isModule = (typeof module != 'undefined') ? true : false let isModule = (typeof module != 'undefined') ? true : false
var ADocEditor = function (customConfig) { var ADocEditor = function (customConfig) {
var screenWidth = (typeof screen != 'undefined') ? screen.width : 1280
var counter = 7 var counter = 7
var container = null var container = null
var mainComponent = null var mainComponent = null
...@@ -66,11 +67,12 @@ var ADocEditor = function (customConfig) { ...@@ -66,11 +67,12 @@ var ADocEditor = function (customConfig) {
function inititalize(customConfig) { function inititalize(customConfig) {
config = { ...defaultConfig, ...customConfig } config = { ...defaultConfig, ...customConfig }
config.pageSetup.canvasMultiplier = Math.round(screen.width / config.pageSetup.width) config.pageSetup.canvasMultiplier = Math.round(screenWidth / config.pageSetup.width)
config.pageSetup.fontMultiplier = config.pageSetup.canvasMultiplier/3 config.pageSetup.fontMultiplier = config.pageSetup.canvasMultiplier / 3
config.pageSetup.canvasWidth = config.pageSetup.canvasMultiplier * config.pageSetup.width config.pageSetup.canvasWidth = config.pageSetup.canvasMultiplier * config.pageSetup.width
config.pageSetup.canvasHeight = config.pageSetup.canvasMultiplier * config.pageSetup.height config.pageSetup.canvasHeight = config.pageSetup.canvasMultiplier * config.pageSetup.height
if (!isModule) {
if (!config.element) throw "'container' not provided in the config" if (!config.element) throw "'container' not provided in the config"
if (typeof config.element == 'string') container = document.querySelector(config.element) if (typeof config.element == 'string') container = document.querySelector(config.element)
if (config.element instanceof HTMLElement) container = config.element if (config.element instanceof HTMLElement) container = config.element
...@@ -83,7 +85,7 @@ var ADocEditor = function (customConfig) { ...@@ -83,7 +85,7 @@ var ADocEditor = function (customConfig) {
let leftSidebarId = `left-sidebar-${new Date().getTime()}` let leftSidebarId = `left-sidebar-${new Date().getTime()}`
let rightSidebarId = `right-sidebar-${new Date().getTime()}` let rightSidebarId = `right-sidebar-${new Date().getTime()}`
let htmlSetup = /*html*/` let htmlSetup = /*html*/`
<div class="a-doc-editor" id="${mainComponentId}"> <div class="a-doc-editor" id="${mainComponentId}">
<div class="header" id="${headerComponentId}"> <div class="header" id="${headerComponentId}">
<div class="option-bar"> <div class="option-bar">
<span class="option">File</span> <span class="option">File</span>
...@@ -129,7 +131,7 @@ var ADocEditor = function (customConfig) { ...@@ -129,7 +131,7 @@ var ADocEditor = function (customConfig) {
<div class="footer" id="${footerComponentId}"> <div class="footer" id="${footerComponentId}">
<div>Footer Data</div> <div>Footer Data</div>
</div> </div>
</div> </div>
` `
container.innerHTML = htmlSetup container.innerHTML = htmlSetup
mainComponent = document.getElementById(mainComponentId) mainComponent = document.getElementById(mainComponentId)
...@@ -148,7 +150,9 @@ var ADocEditor = function (customConfig) { ...@@ -148,7 +150,9 @@ var ADocEditor = function (customConfig) {
}) })
let generatePDFBtn = document.querySelector('[a-doc-editor-action]') let generatePDFBtn = document.querySelector('[a-doc-editor-action]')
generatePDFBtn.addEventListener( 'click', generatePDF) generatePDFBtn.addEventListener('click', generatePDF)
}
reRenderPages(dataSet) reRenderPages(dataSet)
} }
...@@ -158,7 +162,7 @@ var ADocEditor = function (customConfig) { ...@@ -158,7 +162,7 @@ var ADocEditor = function (customConfig) {
renderInProgress = true renderInProgress = true
let canvasIndex = 0 let canvasIndex = 0
if (!canvasList.length) canvasList[0] = { el: createCanvas(), dataIndex: 0 } if (!canvasList.length) canvasList[0] = { el: createNewCanvas(), dataIndex: 0 }
// to clear the canvases // to clear the canvases
...@@ -289,8 +293,6 @@ var ADocEditor = function (customConfig) { ...@@ -289,8 +293,6 @@ var ADocEditor = function (customConfig) {
} }
function renderTheLines() { function renderTheLines() {
console.clear()
console.log('to render the lines')
let canvasIndex = 0 let canvasIndex = 0
let ctx = canvasList[canvasIndex].el.getContext('2d', { willReadFrequently: true }) let ctx = canvasList[canvasIndex].el.getContext('2d', { willReadFrequently: true })
let x = 0 let x = 0
...@@ -300,12 +302,12 @@ var ADocEditor = function (customConfig) { ...@@ -300,12 +302,12 @@ var ADocEditor = function (customConfig) {
x = (config.format.margin * config.pageSetup.canvasMultiplier); x = (config.format.margin * config.pageSetup.canvasMultiplier);
y += (lines[l].maxFontSize*config.pageSetup.fontMultiplier) y += (lines[l].maxFontSize * config.pageSetup.fontMultiplier)
if (lines[l].blockStart && l != 0) y += lines[l].maxFontSize if (lines[l].blockStart && l != 0) y += lines[l].maxFontSize
if ((maxVericalWidth + lines[l].maxFontSize) < (y - lines[l].maxFontSize)) { if ((maxVericalWidth + lines[l].maxFontSize) < (y - lines[l].maxFontSize)) {
canvasIndex++ canvasIndex++
if (!canvasList[canvasIndex]) { if (!canvasList[canvasIndex]) {
canvasList[canvasIndex] = { id: ++counter, el: createCanvas(), dataIndex: lines[l].dataSetIndex, lineIndex: l } canvasList[canvasIndex] = { id: ++counter, el: createNewCanvas(), dataIndex: lines[l].dataSetIndex, lineIndex: l }
} }
ctx = canvasList[canvasIndex].el.getContext('2d', { willReadFrequently: true }) ctx = canvasList[canvasIndex].el.getContext('2d', { willReadFrequently: true })
y = lines[l].maxFontSize + (config.format.margin * config.pageSetup.canvasMultiplier) y = lines[l].maxFontSize + (config.format.margin * config.pageSetup.canvasMultiplier)
...@@ -325,7 +327,7 @@ var ADocEditor = function (customConfig) { ...@@ -325,7 +327,7 @@ var ADocEditor = function (customConfig) {
} }
ctx.save() ctx.save()
ctx.fillStyle = `${style.fontColor}` ctx.fillStyle = `${style.fontColor}`
ctx.font = `${style.bold ? 'bold ' : ''}${style.italic ? 'italic ' : ''} ${style.fontSize*config.pageSetup.fontMultiplier}px ${style.fontFamily}` ctx.font = `${style.bold ? 'bold ' : ''}${style.italic ? 'italic ' : ''} ${style.fontSize * config.pageSetup.fontMultiplier}px ${style.fontFamily}`
ctx.fillText(`${lines[l].listIndex + 1}.`, numberX, y) ctx.fillText(`${lines[l].listIndex + 1}.`, numberX, y)
ctx.restore() ctx.restore()
} }
...@@ -339,7 +341,7 @@ var ADocEditor = function (customConfig) { ...@@ -339,7 +341,7 @@ var ADocEditor = function (customConfig) {
if (char) { if (char) {
let style = setData.formatedText[c] let style = setData.formatedText[c]
ctx.save() ctx.save()
ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize*config.pageSetup.fontMultiplier}px ${style.fontFamily}` ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize * config.pageSetup.fontMultiplier}px ${style.fontFamily}`
ctx.fillStyle = `${style?.fontColor}` ctx.fillStyle = `${style?.fontColor}`
ctx.fillText(char, x, y) ctx.fillText(char, x, y)
setData.formatedText[c].x = x setData.formatedText[c].x = x
...@@ -372,7 +374,7 @@ var ADocEditor = function (customConfig) { ...@@ -372,7 +374,7 @@ var ADocEditor = function (customConfig) {
// handle left right on multiple pages // handle left right on multiple pages
if (activeLine) { if (activeLine) {
canvasList[activeLine.canvasIndex].el.focus() if (!isModule) canvasList[activeLine.canvasIndex].el.focus()
caretData.canvasIndex = activeLine.canvasIndex caretData.canvasIndex = activeLine.canvasIndex
ctx.restore() ctx.restore()
ctx = canvasList[activeLine.canvasIndex].el.getContext('2d', { willReadFrequently: true }) ctx = canvasList[activeLine.canvasIndex].el.getContext('2d', { willReadFrequently: true })
...@@ -383,9 +385,9 @@ var ADocEditor = function (customConfig) { ...@@ -383,9 +385,9 @@ var ADocEditor = function (customConfig) {
let characterData = dataSet[activeDataIndex].formatedText[caretData.index] let characterData = dataSet[activeDataIndex].formatedText[caretData.index]
let rectX = characterData?.x, let rectX = characterData?.x,
rectY = activeLine.y - (activeLine.maxFontSize*config.pageSetup.fontMultiplier), rectY = activeLine.y - (activeLine.maxFontSize * config.pageSetup.fontMultiplier),
rectWidth = 2, rectWidth = 2,
rectHeight = 5 * (activeLine.maxFontSize*config.pageSetup.fontMultiplier) / 4; rectHeight = 5 * (activeLine.maxFontSize * config.pageSetup.fontMultiplier) / 4;
if (!characterData && dataSet[activeDataIndex].formatedText?.[caretData.index - 1]) { if (!characterData && dataSet[activeDataIndex].formatedText?.[caretData.index - 1]) {
rectX = dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.x + dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.width rectX = dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.x + dataSet[activeDataIndex].formatedText?.[caretData.index - 1]?.width
} }
...@@ -412,15 +414,20 @@ var ADocEditor = function (customConfig) { ...@@ -412,15 +414,20 @@ var ADocEditor = function (customConfig) {
let canvas = canvasList[canvasIndex].el let canvas = canvasList[canvasIndex].el
let ctx = canvas.getContext('2d', { willReadFrequently: true }) let ctx = canvas.getContext('2d', { willReadFrequently: true })
ctx.save() ctx.save()
ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize*config.pageSetup.fontMultiplier}px ${style.fontFamily}` ctx.font = `${style?.bold ? 'bold ' : ''}${style?.italic ? 'italic ' : ''} ${style.fontSize * config.pageSetup.fontMultiplier}px ${style.fontFamily}`
ctx.fillStyle = `${style?.fontColor}` ctx.fillStyle = `${style?.fontColor}`
let width = ctx.measureText(char).width let width = ctx.measureText(char).width
ctx.restore() ctx.restore()
return width return width
} }
function createCanvas() { function createNewCanvas() {
let canvas = document.createElement('canvas') let canvas;
if (isModule){
const { createCanvas } = require('canvas')
canvas = createCanvas(config.pageSetup.canvasWidth, config.pageSetup.canvasHeight)
}else{
canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d', { willReadFrequently: true }) let ctx = canvas.getContext('2d', { willReadFrequently: true })
canvas.setAttribute('class', 'page') canvas.setAttribute('class', 'page')
canvas.width = config.pageSetup.canvasWidth canvas.width = config.pageSetup.canvasWidth
...@@ -433,6 +440,7 @@ var ADocEditor = function (customConfig) { ...@@ -433,6 +440,7 @@ var ADocEditor = function (customConfig) {
// canvas.addEventListener("blur", onBlurHandler) // canvas.addEventListener("blur", onBlurHandler)
canvas.setAttribute("tabIndex", -1) canvas.setAttribute("tabIndex", -1)
scrollingComponent.append(canvas) scrollingComponent.append(canvas)
}
return canvas return canvas
} }
...@@ -562,39 +570,39 @@ var ADocEditor = function (customConfig) { ...@@ -562,39 +570,39 @@ var ADocEditor = function (customConfig) {
} }
function setCaretPosition(e) { function setCaretPosition(e) {
let canvasIndex = canvasList.findIndex( item => item.el == e.target ) let canvasIndex = canvasList.findIndex(item => item.el == e.target)
let rect = e.target.getBoundingClientRect() let rect = e.target.getBoundingClientRect()
let position = { let position = {
x: (e.offsetX / rect.width)*config.pageSetup.canvasWidth, x: (e.offsetX / rect.width) * config.pageSetup.canvasWidth,
y: (e.offsetY / rect.height)*config.pageSetup.canvasHeight, y: (e.offsetY / rect.height) * config.pageSetup.canvasHeight,
} }
let closestLine = lines.find( (item, i) => { let closestLine = lines.find((item, i) => {
let thisLine = (item.y+ item.maxFontSize/4)>position.y && canvasIndex==item.canvasIndex let thisLine = (item.y + item.maxFontSize / 4) > position.y && canvasIndex == item.canvasIndex
if (thisLine) return true if (thisLine) return true
else if ( !(lines[i+1]) || ( lines[i+1]?.canvasIndex>canvasIndex ) ) return true else if (!(lines[i + 1]) || (lines[i + 1]?.canvasIndex > canvasIndex)) return true
return false return false
} ) })
if (closestLine){ if (closestLine) {
caretData.activeData = dataSet[closestLine.dataSetIndex] caretData.activeData = dataSet[closestLine.dataSetIndex]
let charIndex = closestLine.charStartIndex let charIndex = closestLine.charStartIndex
let found = false let found = false
for(let i=charIndex; (i<=closestLine.charEndIndex && caretData.activeData.formatedText[i].y==closestLine.y); i++){ for (let i = charIndex; (i <= closestLine.charEndIndex && caretData.activeData.formatedText[i].y == closestLine.y); i++) {
let formatedText = caretData.activeData.formatedText[i] let formatedText = caretData.activeData.formatedText[i]
if (position.x<(formatedText.x+formatedText.width)){ if (position.x < (formatedText.x + formatedText.width)) {
charIndex = i charIndex = i
found= true found = true
break; break;
} }
charIndex = i+1 charIndex = i + 1
} }
if (/\s+/.test(caretData.activeData.plainContent[charIndex]) && caretData.activeData.plainContent[charIndex+1] && charIndex==closestLine.charStartIndex){ if (/\s+/.test(caretData.activeData.plainContent[charIndex]) && caretData.activeData.plainContent[charIndex + 1] && charIndex == closestLine.charStartIndex) {
charIndex++ charIndex++
} }
caretData.index = charIndex caretData.index = charIndex
} }
reRenderPages( dataSet ) reRenderPages(dataSet)
} }
...@@ -613,11 +621,11 @@ var ADocEditor = function (customConfig) { ...@@ -613,11 +621,11 @@ var ADocEditor = function (customConfig) {
} }
} }
function generatePDF(e){ function generatePDF(file) {
if (isModule){ if (isModule) {
console.log('to generate PDF on Server side') console.log('to generate PDF on Server side:', file)
}else{ } else {
console.log('to generate PDF on browser') console.log('to generate PDF on browser:', file)
} }
} }
...@@ -640,8 +648,8 @@ var ADocEditor = function (customConfig) { ...@@ -640,8 +648,8 @@ var ADocEditor = function (customConfig) {
getContent: function () { getContent: function () {
return JSON.parse(JSON.stringify(dataSet)) return JSON.parse(JSON.stringify(dataSet))
}, },
generatePDF,
} }
if (isModule) returnObj.generatePDF = generatePDF
return returnObj return returnObj
} }
......
let ADocEditor = require("./a-doc-editor-node.js") let ADocEditor = require("./dist/assets/a-doc-editor.js")
var counter = 0 var counter = 0
module.exports = async function(req, res){ module.exports = async function(req, res){
try{ try{
console.clear() console.clear()
console.log('generating PDF', ++counter)
let editor = new ADocEditor() let editor = new ADocEditor()
console.log('generating PDF', ++counter, editor)
editor.generatePDF('temp.pdf') editor.generatePDF('temp.pdf')
res.status(200).json( { success: true, message: "Successfull" } ) res.status(200).json( { success: true, message: "Successfull" } )
......
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