From bb2341e9f7fb3d0e5ede6453963b06f6daa8ca4b Mon Sep 17 00:00:00 2001 From: Alexey Matveev <34643750+AlexeyMatveev686@users.noreply.github.com> Date: Fri, 11 Feb 2022 10:30:26 +0300 Subject: [PATCH] zoom in native viewer (#2537) * Zoom has been changed (now it works like in documents) * Fix zoom for native viewer in mobile web * Release/v7.1.0 (#2560) * [se] Fix bug 54999 * [se] Fix bug 54956 * [bug] fix applying changes in AnimMotion * [bug] fix bug 55068: recalculate bounds after changing group position * [bug] fix incorrect collaborative change type * [se] Fix bug 55091 * [se] For bug 55091 * [se] Fix bug 55218 * [se] By bug 55121 * Fix bug #55179 Fix setting up the numbering of paragraphs * Fix bug #55149 Fix messed up setting "case sensitive" * [de][pe] Refactor spell check * Fix bug 55216 * Fix bug 55219 * Fix bug 55243 * FIx bug 55206 Search started from begin of current page * Fix bug 55129 * For bug 55205 * Fix bugs 55213, 55205 * For bug 55240 * Fix bug 55225 * Implement the ability to force render/hide of forms highlight and placeholders * Added returns value to "pluginMethod_ReplaceTextSmart" method (#2527) * [se] Fix bug 55282 * Fix the problem with document redrawing due to spell checking * Add option isPrint for native print * Make work with context menu * Fix bug 55306 * Fix bug 55307 * Fix bug 55312 * [bug] fix bug 55305 * Fix bug #55288 Fix the problem with calculating position of flow table in case of several columns in the current section * Fix bug 55318 * Fix bug with links with browser scaling * [bug] fix bug 55293, 55263 * Fix bug 55327 * Fix bug 55313 * Fix bug 55224 * Fix bug #55288 Fix the problem with table width calculation in case of section with multiple columns of different widths * Fix bug#55278 * [bug] fix bug 55279 * fix: name for refPtType field * Migrate unit test from `node-qunit-phantomjs` to `node-qunit-puppeteer` (#2540) * [se] ->Migrate unit test from `node-qunit-phantomjs` to `node-qunit-puppeteer` Migrate formula tests to qunit-2.16.0, fix formula tests * [se] Fix calculate y position log base * Refactoring TextAssociation types * Rebuild module with new version native code * Fix bug #55280 * Fix bug #51933 Fix the problem with calculating the position of flow objects lying in a table cell * Fix for passing tests * [de] For bug 55284 * [se] Fix bug 53561 * Fix bug #55380 Fix the problem with search function in the equation object * ole-objects fixes: add ability to set natural sizes of ole-objects; use image size as default size for ole-object; do not account zoom on calculating pix to mm coefficient; * [de] Fix c_oAscTextAssociation export * add methods for working with ole-objects in plugins * [se] By bug 55218 There is nothing to print because the table is empty * Fix issue with isLayoutInCell setting depending on compatibility mode * Fix bug #55383 Do autocorrect a double space with a dot only when preceded by a text element * [se] Fix bug 54845 * [se] By bug 55411 * Added missing method to export. * [de] Implement ability to generate previews for table styles in small portions * Implement ability to get preview for selected style * Fix previous commit * Add ability to receive previews for specified table styles * [UserInfoParser] Add userInfo permissions: hide users not in userInfo groups * Fix/stroke cone charts (#2555) * [se] Fix bug 55421 Co-authored-by: Kvaigone * Fix/bug 51902 (#2556) * [se] Fix bug 51902 * Fix bug #55398 Fix the problem with calculating the position of a drawing object in the header * Fix bug #55403 Fix the problem with calculating header/footer. Forbid to change the page number of a header when calculation in progress * Fix bug #55406 Fix the problem with calculating the position of a drawing lying in a table cell with vertical alignment to the bottom or center * Fix calculation of the position of drawings in a table cell depending one the compatibility mode * Fix bug #55410 Add check for incorrect values of the maxCharacters parameter for text forms * Fix for passing builder tests * Fix presentation editor crash * Fix bug #55458 Fix the problem with calculating page count stage Co-authored-by: GoshaZotov Co-authored-by: Sergey Luzyanin Co-authored-by: Sergey Konovalov Co-authored-by: KirillovIlya Co-authored-by: Nikita Khromov Co-authored-by: Vladimir Privezenov Co-authored-by: Pavel Lobashov Co-authored-by: Kvaigone Co-authored-by: Julia Radzhabova Co-authored-by: Oleg Korshul Co-authored-by: GoshaZotov Co-authored-by: Sergey Luzyanin Co-authored-by: Sergey Konovalov Co-authored-by: KirillovIlya Co-authored-by: Nikita Khromov Co-authored-by: Vladimir Privezenov Co-authored-by: Pavel Lobashov Co-authored-by: Kvaigone Co-authored-by: Julia Radzhabova --- common/Scrolls/mobileTouchManagerBase.js | 20 +++++- pdf/src/viewer.js | 81 ++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 8 deletions(-) diff --git a/common/Scrolls/mobileTouchManagerBase.js b/common/Scrolls/mobileTouchManagerBase.js index 4d514317ea..3b59b221d2 100644 --- a/common/Scrolls/mobileTouchManagerBase.js +++ b/common/Scrolls/mobileTouchManagerBase.js @@ -2012,7 +2012,7 @@ { this.delegate.HtmlPage.NoneRepaintPages = true; - this.ZoomDistance = this.getPointerDistance(e); + this.ZoomDistance = this.getPointerDistance(e, true); this.ZoomValue = this.delegate.GetZoom(); break; @@ -2102,7 +2102,12 @@ this.delegate.HtmlPage.NoneRepaintPages = false; if (this.delegate.IsNativeViewer && this.delegate.IsNativeViewer()) + { this.delegate.DrawingDocument.m_oDocumentRenderer.paint(); + // очищаем координаты зума для мобильного веба + this.delegate.DrawingDocument.m_oDocumentRenderer.skipClearZoomCoord = false; + this.delegate.DrawingDocument.m_oDocumentRenderer.clearZoomCoord(); + } this.delegate.HtmlPage.m_bIsFullRepaint = true; this.delegate.HtmlPage.OnScroll(); @@ -2204,7 +2209,7 @@ return true; }; - CMobileTouchManagerBase.prototype.getPointerDistance = function(e) + CMobileTouchManagerBase.prototype.getPointerDistance = function(e, bFixZoomCoord) { var isPointers = this.checkPointerEvent(e); if (e.touches && (e.touches.length > 1) && !isPointers) @@ -2215,6 +2220,12 @@ var _x2 = (e.touches[1].pageX !== undefined) ? e.touches[1].pageX : e.touches[1].clientX; var _y2 = (e.touches[1].pageY !== undefined) ? e.touches[1].pageY : e.touches[1].clientY; + // запоминаем координаты между тачами только на старте + if (bFixZoomCoord && this.delegate.IsNativeViewer && this.delegate.IsNativeViewer()) { + this.delegate.DrawingDocument.m_oDocumentRenderer.fixZoomCoord( ( ( _x1 + _x2 ) / 2 ), ( ( _y1 + _y2 ) / 2 ) ); + this.delegate.DrawingDocument.m_oDocumentRenderer.skipClearZoomCoord = true; + } + return Math.sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2)); } else if (isPointers) @@ -2233,6 +2244,11 @@ if (_counter > 1) break; } + // запоминаем координаты между тачами только на старте + if (bFixZoomCoord && this.delegate.IsNativeViewer && this.delegate.IsNativeViewer()) { + this.delegate.DrawingDocument.m_oDocumentRenderer.fixZoomCoord( ( ( _touch1.X + _touch2.X ) / 2 ), ( ( _touch1.Y + _touch2.Y ) / 2 ) ); + this.delegate.DrawingDocument.m_oDocumentRenderer.skipClearZoomCoord = true; + } return Math.sqrt((_touch1.X - _touch2.X) * (_touch1.X - _touch2.X) + (_touch1.Y - _touch2.Y) * (_touch1.Y - _touch2.Y)); } diff --git a/pdf/src/viewer.js b/pdf/src/viewer.js index 551aa85008..6d51043586 100644 --- a/pdf/src/viewer.js +++ b/pdf/src/viewer.js @@ -148,6 +148,8 @@ this.zoomMode = ZoomMode.Custom; this.zoom = 1; + this.zoomCoordinate = null; + this.skipClearZoomCoord = false; this.drawingPages = []; this.isRepaint = false; @@ -441,12 +443,18 @@ { this.scrollX = pos; this.scrollMaxX = maxPos; + if (this.Api.WordControl.MobileTouchManager && this.Api.WordControl.MobileTouchManager.iScroll) + this.Api.WordControl.MobileTouchManager.iScroll.x = - Math.max(0, Math.min(pos, maxPos)); + this.paint(); }; this.scrollVertical = function(pos, maxPos) { this.scrollY = pos; this.scrollMaxY = maxPos; + if (this.Api.WordControl.MobileTouchManager && this.Api.WordControl.MobileTouchManager.iScroll) + this.Api.WordControl.MobileTouchManager.iScroll.y = - Math.max(0, Math.min(pos, maxPos)); + this.paint(); }; @@ -458,6 +466,7 @@ this.x = rect.x; this.y = rect.y; + var oldsize = {w: this.width, h: this.height}; this.width = this.parent.offsetWidth - this.scrollWidth; this.height = this.parent.offsetHeight; @@ -466,7 +475,10 @@ else if (this.zoomMode === ZoomMode.Page) this.zoom = this.calculateZoomToHeight(); - var lastPosition = this.getFirstPagePosition(); + // в мобильной версии мы будем получать координаты от MobileTouchManager (до этого момента они уже должны быть) и не нужно их запоминать, так как мы перетрём нужные нам значения + // ну а если их нет и зум произошёл не от тача, то запоминаем их как при обычном зуме + if (!this.zoomCoordinate) + this.fixZoomCoord( (this.width >> 1), (this.height >> 1) ); this.sendEvent("onZoom", this.zoom, this.zoomMode); @@ -551,13 +563,21 @@ if (this.scrollY >= this.scrollMaxY) this.scrollY = this.scrollMaxY; - if (lastPosition) + if (this.zoomCoordinate) { - var drawingPage = this.drawingPages[lastPosition.page]; - var newScrollY = drawingPage.Y + lastPosition.scrollY - lastPosition.y; + var newPoint = this.ConvertCoordsToCursor(this.zoomCoordinate.x, this.zoomCoordinate.y, this.zoomCoordinate.index); + // oldsize используется чтобы при смене ориентации экрана был небольшой скролл + var shiftX = this.Api.isMobileVersion ? ( (oldsize.w - this.width) >> 1) : 0; + var shiftY = this.Api.isMobileVersion ? ( (oldsize.h - this.height) >> 1) : 0; + var newScrollX = this.scrollX + newPoint.x - this.zoomCoordinate.xShift + shiftX; + var newScrollY = this.scrollY + newPoint.y - this.zoomCoordinate.yShift + shiftY; + newScrollX = Math.max(0, Math.min(newScrollX, this.scrollMaxX) ); + newScrollY = Math.max(0, Math.min(newScrollY, this.scrollMaxY) ); + if (this.scrollY == 0 && !this.Api.isMobileVersion) + newScrollY = 0; - if (newScrollY < this.scrollMaxY) - this.m_oScrollVerApi.scrollToY(newScrollY); + this.m_oScrollVerApi.scrollToY(newScrollY); + this.m_oScrollHorApi.scrollToX(newScrollX); } if (this.thumbnails) @@ -567,6 +587,9 @@ if (this.Api.WordControl.MobileTouchManager) this.Api.WordControl.MobileTouchManager.Resize(); + + if (!this.Api.isMobileVersion || !this.skipClearZoomCoord) + this.clearZoomCoord(); }; this.onLoadModule = function() @@ -833,6 +856,26 @@ return Math.min(zoom1, zoom2); }; + this.fixZoomCoord = function(x, y) + { + if (this.Api.isMobileVersion) + { + x -= this.x; + y -= this.y; + } + this.zoomCoordinate = this.getPageByCoords2(x, y); + if (this.zoomCoordinate) + { + this.zoomCoordinate['xShift'] = x; + this.zoomCoordinate['yShift'] = y; + } + }; + + this.clearZoomCoord = function() + { + // нужно очищать, чтобы при любом ресайзе мы не скролились к последней сохранённой точке + this.zoomCoordinate = null; + }; this.getFirstPagePosition = function() { @@ -1939,6 +1982,32 @@ }; }; + this.ConvertCoordsToCursor = function(x, y, pageIndex) + { + var dKoef = (this.zoom * g_dKoef_mm_to_pix); + var rPR = 1;//AscCommon.AscBrowser.retinaPixelRatio; + let yPos = this.scrollY >> 0; + let xCenter = this.width >> 1; + if (this.documentWidth > this.width) + { + xCenter = (this.documentWidth >> 1) - (this.scrollX) >> 0; + } + + let page = this.drawingPages[pageIndex]; + + let _w = (page.W * rPR) >> 0; + let _h = (page.H * rPR) >> 0; + let _x = ( (xCenter * rPR) >> 0) - (_w >> 1); + let _y = ( (page.Y - yPos) * rPR) >> 0; + + var x_pix = (_x + x * dKoef) >> 0; + var y_pix = (_y + y * dKoef) >> 0; + var w_pix = (_w * dKoef) >> 0; + var h_pix = (_h * dKoef) >> 0 + + return ( {x : x_pix, y : y_pix, w : w_pix, h: h_pix} ); + }; + this.Copy = function(_text_format) { return this.file.copy(_text_format);