document.getElementById("info").innerHTML += "paper width (px)" + document.getElementById("paper").offsetWidth + "
"; function css( element : HTMLElement, property : string ) { return window.getComputedStyle( element, null ).getPropertyValue( property ); } let paper = document.getElementById('paper'); let paperPage1 = document.getElementById('paper-page1'); var font_family = css( paper, 'font-family') var font_size = css(paper, 'font-size') paper.addEventListener('input', getWordsWidth); paper.addEventListener('keydown', (e)=>{ if(e.key==" "){ //enter e.preventDefault(); //Prevent default browser behavior var sel : Selection; var range : Range; sel = window.getSelection(); range = sel.getRangeAt(0); range.deleteContents(); var textNode = document.createTextNode('\u00A0'); // no linebreaking-space range.insertNode(textNode); range.setStartAfter(textNode); sel.addRange(range); getWordsWidth(); // paper.innerHTML+= paper.innerHTML; //var currentPage = document.getElementById(getCaretCurrentPageId()); //var currentRange = getCursorLengthRange(currentPage); //var HTMLBeforeCaret = rangeToHTMLFragement(currentRange); } }); // 如果游標在 contentdiveditable id "paper-page1" 裡面, // 該函數返回 "paper-page1" function getCaretCurrentPageId(){ var anchorNode = window.getSelection().anchorNode; var currentNode = anchorNode; while((currentNode as Element).id === undefined || !((currentNode as Element).id.match(/^paper-page\d+/))){ currentNode = currentNode.parentNode; } return (currentNode as Element).id; } // 得到子節點(文字物件) // ["dolore", [ "m ips", ["um si"], "t am"], "et"] function getChildNodes(ele : HTMLElement){ var res_array res_array = []; if (ele.nodeType == Node.TEXT_NODE){ return ele; }else{ for (var i =0; i (ele.childNodes[i]))) } return res_array } } // 平坦化陣列 // [a, [b, c, d], [[e]]] => [a, b, c, d, e] function flatten(arr){ if (!Array.isArray(arr)){ return arr; } else{ var result = []; for (var i=0;iele)); range.selectNodeContents((ele)); var ran_start = i var ran_end = j var ran_start_is_set = false for (var i=0; i< flattened_ar.length;i++){ var fragement_text_length = flattened_ar[i].textContent.length; // 如果 ran_start > 碎片長度 if(ran_start > fragement_text_length){ ran_start -= fragement_text_length; ran_end -= fragement_text_length; // 如果 ran_start <= 碎片長度 }else if(ran_start <= fragement_text_length && ran_start_is_set == false){ range.setStart(flattened_ar[i], ran_start); ran_start_is_set = true // 如果 ran_end > 碎片長度 if (ran_end > fragement_text_length){ ran_end -= fragement_text_length; // 如果 ran_end <= 碎片長度,setEnd 中止迴圈 }else{ range.setEnd(flattened_ar[i], ran_end); break; } // 如果 ran_end > 碎片長度 }else if (ran_end > fragement_text_length && ran_start_is_set == true){ ran_end -= fragement_text_length; } // 如果 ran_end <= 碎片長度,setEnd 中止迴圈 else{ range.setEnd(flattened_ar[i], ran_end); break; } } var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); return range } /* 設置游標位置於 ele 要素的第 col 個字(不含標籤),例子: HTML
dolorem ipsum sit amet 1234
setCaret(document.getElementById('paper-page1'),10) V CARET
dolorem ip|sum sit amet 1234
*/ function setCaret(ele: ElementContentEditable, col : number){ var range = document.createRange(); var sel = document.getSelection(); var flattened_ar = flatten(getChildNodes(ele)); // flattened array range.selectNodeContents((ele)); var ran_start = col for (var i=0; i< flattened_ar.length;i++){ var fragement_text_length = flattened_ar[i].textContent.length; if(ran_start > fragement_text_length){ ran_start -= fragement_text_length; }else{ range.setEnd(flattened_ar[i], ran_start); range.collapse(); break; } } var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } // 將座標轉成座標所在位置的 range function getCursorLengthRange(ele: HTMLElement){ let win = ele.ownerDocument.defaultView; let range = win.getSelection().getRangeAt(0); let cloneRange = range.cloneRange(); cloneRange.selectNodeContents(ele); cloneRange.setEnd(range.endContainer, range.endOffset); return cloneRange; } // 將座標 range 轉成字串的長度 function rangeToStringLen(range : Range){ return range.toString().length; } // 將座標位置 range 轉成 html 斷片 function rangeToHTMLFragement(range : Range){ var nodes =range.cloneContents().childNodes; var result = "" for(var i=0;i nodes[i].parentNode); let div=document.createElement("div"); div.appendChild(parentNode); if (typeof (( nodes[i]).outerHTML) === "undefined"){ result += nodes[i].textContent;} else{ result += ( nodes[i]).outerHTML;} console.log("Parent Node"+div.outerHTML); } return result; } // 得到一個 word 或是 character 的寬度 function getTextWidth(text, fontfamily, fontsize) { console.log(text) var decodedText = decodeEntities(text) let canvas = document.createElement("canvas"); var context = canvas.getContext("2d"); context.font = fontsize + " " + fontfamily; let width = context.measureText(decodedText).width; return width; } // 得到字寬 function getWordsWidth(){ document.getElementById('line-info').innerHTML = ""; var array = paper.childNodes; var res = []; for (var i=0;ix.innerHTML); var innerHTMLTotal = innerArray.reduce((x,y)=>(x+y)); var innerHTMLRemoveTags = innerHTMLTotal.replace(/[<][\/]?[^<]+[\/]?[>]/gi,"") // 移除標籤 var innerHTMLSplitted = innerHTMLRemoveTags.split(/( |\s| |[⺀-\u2efe\u3000-〾㇀-\u31ee㌀-㏾㐀-\u4dbe一-\u9ffe豈-\ufafe︰-﹎]|[\ud840-\ud868\ud86a-\ud86c][\udc00-\udfff]|\ud869[\udc00-\udede\udf00-\udfff]|\ud86d[\udc00-\udf3e\udf40-\udfff]|\ud86e[\udc00-\udc1e]|\ud87e[\udc00-\ude1e])/).filter(item => item != "") console.log(innerHTMLSplitted); //var innerHTMLSplittedLength = innerHTMLSplitted.map((x)=>x.length) //var innerHTMLSelectedRange = []; /*var sum = 0 for (var i=0; i rangeToHTMLFragement(selecRengeFromCharToChar(x[0],x[1],paper))) console.log("Range 結果"+innerHTMLSplittedRange);*/ let textWidthList = innerHTMLSplitted.map(x => getTextWidth(x,font_family, font_size)); var lineInfoLength = []; for (var i=0; i getrealcol(5, "example") > 5 > getrealcol(5, "example") > 14 */ function getrealcol(n, str) { var arr = str.split(RegExp("(<[^<>]+>)")).map((x) => ({ cont: x, len: x.length })); var j = 0; var k = 0; for (var i = 0; i < arr.length; i++) { if (arr[i].cont.match(/^[<]/)) { continue; } else { if (n > arr[i].len) { n = n - arr[i].len; } else { j = i; k = n; break; } }; } var res_col = 0; for (var i = 0; i < j; i++) { res_col += arr[i].len; } res_col += k; return res_col; } // 解碼 &1234; 這種東西用 function decodeEntities(encodedString) { var textArea = document.createElement('textarea'); textArea.innerHTML = encodedString; return textArea.value; }