text selection

This commit is contained in:
Kulikova Svetlana
2021-07-16 18:30:30 +03:00
parent 7abae785cb
commit f7a1773105
2 changed files with 119 additions and 91 deletions

View File

@ -108,13 +108,13 @@ window.onload = function()
this.zoom = 1;
this.drawingPages = [];
this.isRepaint = false;
this.canvas = document.getElementById("main");
this.canvas = document.getElementById("main");
this.scroller = document.getElementById("pos");
this.documentWidth = 0;
this.documentWidth = 0;
this.documentHeight = 0;
this.Selection = { IsSelection : false, Image : null, page : -1 };
this.file = new AscViewer.DjVuFile();
this.file.cacheManager = new CCacheManager();
/*
[TIMER START]
@ -161,8 +161,8 @@ window.onload = function()
};
window.onscroll = function(e) { if (window.Viewer) window.Viewer.scroll(e); };
window.onmousedown = function(e) { if (window.Viewer) window.Viewer.OnMouseDown(e); };
window.onmousemove = function(e) { if (window.Viewer) window.Viewer.OnMouseMove(e); };
window.onmousedown = function(e) { if (window.Viewer) window.Viewer.OnMouse(e, true); };
window.onmousemove = function(e) { if (window.Viewer) window.Viewer.OnMouse(e, false); };
window.onmouseup = function(e) { if (window.Viewer) window.Viewer.OnMouseUp(e); };
this.timerAnimation = function()
@ -249,6 +249,7 @@ window.onload = function()
if (this.file)
this.file.close();
this.file = window["AscViewer"].createFile(data);
this.Selection.Image = this.cacheManager ? this.cacheManager.lock(0, 0) : document.createElement("canvas");
document.scrollingElement.scrollLeft = 0;
document.scrollingElement.scrollTop = 0;
@ -322,60 +323,40 @@ window.onload = function()
this.paint();
};
this.OnMouseDown = function(e)
this.OnMouse = function(e, down)
{
if (!this.file.isValid())
return;
let yPos = e.clientY;
let yMax = yPos + this.height;
let lCurrentPage = -1;
let lPagesCount = this.drawingPages.length;
for (let i = 0; i < lPagesCount; i++)
for (let i = 0; i < this.drawingPages.length; i++)
{
let page = this.drawingPages[i];
let pageT = page.Y;
let pageB = page.Y + page.H;
if (yPos > pageT && yPos < pageB)
if (e.pageY > pageT && e.pageY < pageB)
{
lCurrentPage = i;
break;
}
}
// TODO: координаты относительно страницы
if (lCurrentPage >= 0)
this.file.OnMouseDown(lCurrentPage, e.clientX, e.clientY);
};
this.OnMouseMove = function(e)
{
if (!this.file.isValid())
return;
let yPos = e.clientY;
let yMax = yPos + this.height;
let lCurrentPage = -1;
let lPagesCount = this.drawingPages.length;
for (let i = 0; i < lPagesCount; i++)
{
let page = this.drawingPages[i];
let pageT = page.Y;
let pageB = page.Y + page.H;
if (yPos > pageT && yPos < pageB)
{
lCurrentPage = i;
break;
}
let yPos = (document.scrollingElement.scrollTop * this.zoom) >> 0;
let page = this.drawingPages[lCurrentPage];
let w = (page.W * this.retinaPixelRatio) >> 0;
let h = (page.H * this.retinaPixelRatio) >> 0;
let x = e.pageX - (Math.max(0, (this.width - this.documentWidth) >> 1) * this.retinaPixelRatio) >> 0;
let y = e.pageY - (page.Y * this.retinaPixelRatio) >> 0;
this.Selection.page = lCurrentPage;
if (down)
this.file.OnMouseDown(lCurrentPage, this.Selection, x, y, w, h);
else
this.file.OnMouseMove(lCurrentPage, this.Selection, x, y, w, h);
this.paint();
}
// TODO: координаты относительно страницы
if (lCurrentPage >= 0)
this.file.OnMouseMove(lCurrentPage, e.clientX, e.clientY);
};
this.OnMouseUp = function(e)
@ -395,8 +376,7 @@ window.onload = function()
if (!this.file.isValid())
return;
this.canvas.width = this.canvas.width;
let ctx = this.canvas.getContext("2d");
ctx.strokeStyle = "#000000";
let lineW = this.retinaPixelRatio >> 0;
@ -472,6 +452,8 @@ window.onload = function()
let y = ((page.Y - yPos) * this.retinaPixelRatio) >> 0;
ctx.drawImage(page.Image, 0, 0, w, h, x, y, w, h);
if (this.Selection.page == i && this.Selection.IsSelection)
ctx.drawImage(this.Selection.Image, 0, 0, w, h, x, y, w, h);
ctx.strokeRect(x + lineW / 2, y + lineW / 2, w - lineW, h - lineW);
}
@ -481,6 +463,7 @@ window.onload = function()
window.Viewer = new CHtmlPage();
window.Viewer.resize();
window.Viewer.startTimer();
window.CCacheManager = CCacheManager;
};
window.onresize = function(e)

View File

@ -84,98 +84,143 @@
var _glyph = -1;
var minDist = Number.MAX_SAFE_INTEGER;
// TODO: оптимизировать по горизонтальной линии
for (let i = 0; i < this.pages[pageIndex].Lines.length; i++)
{
for (let j = 0; j < this.pages[pageIndex].Lines[i].Glyphs.length; j++)
let Y = this.pages[pageIndex].Lines[i].Glyphs[0].Y;
if (Math.abs(Y - y) < minDist)
{
let glyph = this.pages[pageIndex].Lines[i].Glyphs[j];
let d = Math.sqrt(Math.pow(glyph.X - x, 2) + Math.pow(glyph.Y - y, 2));
if (d < minDist)
{
minDist = d;
_line = i;
_glyph = j;
}
minDist = Math.abs(Y - y);
_line = i;
}
}
minDist = Number.MAX_SAFE_INTEGER;
for (let j = 0; j < this.pages[pageIndex].Lines[_line].Glyphs.length; j++)
{
let X = this.pages[pageIndex].Lines[_line].Glyphs[j].X;
if (Math.abs(X - x) < minDist)
{
minDist = Math.abs(X - x);
_glyph = j;
}
}
return { Line : _line, Glyph : _glyph };
}
CFile.prototype.OnUpdateSelection = function()
CFile.prototype.OnUpdateSelection = function(Selection, width, height)
{
// TODO: выделять не после OnMouseUp
if (this.Selection.IsSelection)
if (!this.Selection.IsSelection)
return;
var sel = this.Selection;
var page1 = sel.Page1 < sel.Page2 ? sel.Page1 : sel.Page2;
var page2 = sel.Page1 > sel.Page2 ? sel.Page1 : sel.Page2;
var line1 = sel.Line1 < sel.Line2 ? sel.Line1 : sel.Line2;
var line2 = sel.Line1 > sel.Line2 ? sel.Line1 : sel.Line2;
var glyph1 = sel.Glyph1 < sel.Glyph2 ? sel.Glyph1 : sel.Glyph2;
var glyph2 = sel.Glyph1 > sel.Glyph2 ? sel.Glyph1 : sel.Glyph2;
var page1 = sel.Page1;
var page2 = sel.Page2;
var line1 = sel.Line1;
var line2 = sel.Line2;
var glyph1 = sel.Glyph1;
var glyph2 = sel.Glyph2;
if (page1 == page2 && line1 == line2 && glyph1 == glyph2)
{
Selection.IsSelection = false;
return;
}
else if (page1 == page2 && line1 == line2)
{
glyph1 = Math.min(sel.Glyph1, sel.Glyph2);
glyph2 = Math.max(sel.Glyph1, sel.Glyph2);
}
else if (page1 == page2)
{
if (line1 > line2)
{
line1 = sel.Line2;
line2 = sel.Line1;
glyph1 = sel.Glyph2;
glyph2 = sel.Glyph1;
}
}
if (this.cacheManager)
{
this.cacheManager.unlock(Selection.Image);
Selection.Image = this.cacheManager.lock(width, height);
}
else
{
delete Selection.Image;
Selection.Image = document.createElement("canvas");
Selection.Image.width = width;
Selection.Image.height = height;
}
let ctx = Selection.Image.getContext("2d");
// TODO: После изменения размера экрана наложение областей выделения
ctx.clearRect(0, 0, Selection.Image.width, Selection.Image.height);
ctx.globalAlpha = 0.4;
ctx.fillStyle = "#7070FF";
for (let page = page1; page <= page2; page++)
{
// TODO: если страница не последняя, то выделить целиком
for (let line = line1; line <= line2; line++)
let start = 0;
let end = this.pages[page].Lines.length;
if (page == page1)
start = line1;
if (page == page2)
end = line2;
for (let line = start; line <= end; line++)
{
let Glyphs = this.pages[page].Lines[line].Glyphs;
let x = Glyphs[0].X;
let y = Glyphs[0].Y;
let w = Glyphs[Glyphs.length - 1].X;
let h = x + Glyphs[0].fontSize;
// если последняя строка
if (line == line2)
w = Glyphs[glyph2].X;
// TODO: поступить аналогично _pixelsToCanvas2d
let canvas = document.getElementById("main");
let ctx = canvas.getContext("2d");
ctx.globalAlpha = 0.5;
ctx.fillStyle = "#0000FF";
let y = Glyphs[0].Y - Glyphs[0].fontSize;
// первая строка на первой странице
if (page == page1 && line == start)
x = Glyphs[glyph1].X;
let w = Glyphs[Glyphs.length - 1].X - x;
let h = Glyphs[0].fontSize;
// последняя строка на последней странице
if (page == page2 && line == end)
w = Glyphs[glyph2].X - x;
ctx.fillRect(x, y, w, h);
ctx.globalAlpha = 1;
}
}
ctx.globalAlpha = 1;
Selection.IsSelection = true;
}
CFile.prototype.OnMouseDown = function(pageIndex, x, y)
CFile.prototype.OnMouseDown = function(pageIndex, Selection, x, y, w, h)
{
var ret = this.GetNearestPos(pageIndex, x, y);
var sel = this.Selection;
sel.Page1 = pageIndex;
sel.Line1 = ret.Line;
sel.Page1 = pageIndex;
sel.Line1 = ret.Line;
sel.Glyph1 = ret.Glyph;
sel.Page2 = pageIndex;
sel.Line2 = ret.Line;
sel.Page2 = pageIndex;
sel.Line2 = ret.Line;
sel.Glyph2 = ret.Glyph;
sel.IsSelection = true;
//this.OnUpdateSelection();
this.OnUpdateSelection(Selection, w, h);
}
CFile.prototype.OnMouseMove = function(pageIndex, x, y)
CFile.prototype.OnMouseMove = function(pageIndex, Selection, x, y, w, h)
{
if (false === this.Selection.IsSelection)
return;
var ret = this.GetNearestPos(pageIndex, x, y);
var sel = this.Selection;
sel.Page2 = pageIndex;
sel.Line2 = ret.Line;
sel.Page2 = pageIndex;
sel.Line2 = ret.Line;
sel.Glyph2 = ret.Glyph;
//this.OnUpdateSelection();
this.OnUpdateSelection(Selection, w, h);
}
CFile.prototype.OnMouseUp = function()
{
this.Selection.IsSelection = false;
this.OnUpdateSelection();
}
CFile.prototype.getPageBase64 = function(pageIndex, width, height)
@ -222,7 +267,9 @@
return canvas;
};
var vs_source = "\
CFile.prototype._pixelsToCanvas3d = function(pixels, width, height)
{
var vs_source = "\
attribute vec2 aVertex;\n\
attribute vec2 aTex;\n\
varying vec2 vTex;\n\
@ -231,16 +278,13 @@ void main() {\n\
vTex = aTex;\n\
}";
var fs_source = "\
var fs_source = "\
precision mediump float;\n\
uniform sampler2D uTexture;\n\
varying vec2 vTex;\n\
void main() {\n\
gl_FragColor = texture2D(uTexture, vTex);\n\
}";
CFile.prototype._pixelsToCanvas3d = function(pixels, width, height)
{
var canvas = null;
if (this.cacheManager)
{
@ -403,6 +447,7 @@ void main() {\n\
}
file.loadFromData(data);
file.cacheManager = new window.CCacheManager();
return file;
};