mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
text selection
This commit is contained in:
@ -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)
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user