how to sync position & zoom level for different viewer window sizes / client resolutions

325 views
Skip to first unread message

Danny Mendel

unread,
Jun 10, 2016, 4:36:58 PM6/10/16
to PDFTron WebViewer
hi Matt,

i would like to have your advise
if there is an elegant way to sync the "drag" inner doc positioning of content display and zoom level
when dealing with different viewer sizes and PC resolutions.
A typicial use case
a. user A viewer window dimension: widthX1, heightY1
b. user B viewer window dimension: widthX2, heightY2
for both users the doc is larger than the window sizes, so each user can use mouse drag
to view any part of the content in specific viewport display.

i would like to sync perfectly the position of content view by both users.
so ideally userA drag the viewport via mouse, to let say left/bottom of page
i can instruct viewerB via api, to calculate position display to show a display of similar content area/viewport 
resulting in both displays look identical even if users having different or similar window dimensions.
same tricks goes without saying to the synchronized to calculated zoom level relative to the window size

is this calculation & direct access to imitate drag operation doable? 
and if so can you suggest a sample code how to do that ?

Many Many thanks.
Danny 


Matt Parizeau

unread,
Jun 13, 2016, 2:11:12 PM6/13/16
to PDFTron WebViewer
Hi Danny,

You can access the scrollable view like var scrollView = $('#DocumentViewer');
This is just a jQuery object so you can get and set the scroll position and the width/height like scrollView.scrollLeft(), scrollView.scrollTop(), scrollView.scrollTop(1500), scrollView.width(), scrollView.height()
You can access the total scrollable area size like scrollView[0].scrollHeight, scrollView[0].scrollWidth

With these values and functions I think you should be able to make the calculations you need and update the values for the other user.

Matt Parizeau
Software Developer
PDFTron Systems Inc.

Danny Mendel

unread,
Jun 15, 2016, 9:07:04 PM6/15/16
to PDFTron WebViewer
hi Matt seems like a decent way to research what needed for proper calculation,
however you didn't mention how to treat zoom levels? as there any valuable information to start with ? 

Danny Mendel

unread,
Jun 16, 2016, 4:13:29 PM6/16/16
to PDFTron WebViewer
hi Matt
another interesting question
how can i detect a user drag the view, as this need to be the initial invoker for the instant sync 
kindly provide a sample showing how this can be done.

thanks.
Danny

Danny Mendel

unread,
Jun 16, 2016, 8:43:40 PM6/16/16
to PDFTron WebViewer
hi Matt
i found a sample code of yours

$(document).on('documentLoaded', function(){
    
var docViewer = readerControl.docViewer;
    docViewer
.on('mouseLeftUp',function(){
        
var toolbarOffset = $('#control').outerHeight();
        
var sidePanelWidth = readerControl.sidePanelVisible() ? $('#sidePanel').width() : 0;
        docViewer
.zoomToMouse(8, sidePanelWidth, toolbarOffset);
    
}); 
});

however in my case i don't use the config.js but direct access from main javascript

so i want to convert your above code to run under

$(document).on('documentLoaded', function () {
                   
                    myWebViewer.instance.docViewer.on('mouseLeftUp', function () {
                        var toolbarOffset = $('#control').outerHeight();
                        var sidePanelWidth = myWebViewer.instance.sidePanelVisible() ? $('#sidePanel').width() : 0;
                        myWebViewer.instance.docViewer.zoomToMouse(8, sidePanelWidth, toolbarOffset);
                    });     


so the issue is that i don't have access to $('#control') & $('#sidePanel') as it hidden under inner iframe ...
can you please instruct me how to provide the proper jquery selector for both $('#control') & $('#sidePanel')
when calling from main root javascript scope ?

many many thanks.
Danny

Danny Mendel

unread,
Jun 16, 2016, 8:43:40 PM6/16/16
to PDFTron WebViewer
hi Matt
so i manage to run this code

myWebViewer.instance.docViewer.on('mouseLeftUp', function () {
                        var toolbarOffset = $('iframe').contents().find('#control').outerHeight();
                        var sidePanelWidth = myWebViewer.instance.sidePanelVisible() ? $('iframe').contents().find('#sidePanel').width() : 0;
                        myWebViewer.instance.docViewer.zoomToMouse(8, sidePanelWidth, toolbarOffset);
                    });

is there more elegant "api" way to access the #control & #sidePanel rather than call "generic" selector ?


back to my original question
1. how can i track someone click or drag to new coords X,Y on the viewer ? is there simple jQuery handler i can catch relative x,y offset to the scrollable view ?  if so i'm half way so i can calculate the relative x1*ratioX, y1*ratioY
2. zoomTo() seems to be the way to control both mouse level and wanted x,y coords, 

any thoughts is most welcome here
many many thanks!
Danny



On Monday, June 13, 2016 at 9:11:12 PM UTC+3, Matt Parizeau wrote:

Danny Mendel

unread,
Jun 16, 2016, 8:43:40 PM6/16/16
to PDFTron WebViewer
hi Matt,
i guess you mean 
var scrollView = $('#id of your viewer '); ?
if so getter/setter on this element doesn't work you get (0) and setting those values have no effects.

if you mean another hidden element, let me know how to access this element.

scrollView[0].scrollHeight/Width a getter actually works,

i still don't understand what was your suggestion to manipulate the internal area of the viewer directly,

can you provide perhaps a working sample, which show how can you 
a. react to user dragging/moving to specific area, with specific handler ?
b. how can you programmatically instruct the viewer to show other part by moving to specific x,y coords with specific zoom level ?

this will be a good starting point to make more investigation and proper calculation.

many many thanks
Danny



On Monday, June 13, 2016 at 9:11:12 PM UTC+3, Matt Parizeau wrote:

Danny Mendel

unread,
Jun 17, 2016, 2:15:26 PM6/17/16
to PDFTron WebViewer
hi Matt i think i manage to do this,

if anyone interested i tried to imitate zoomToMouse() like behavior
I read the internal implementation of mouseX/Y captured by docviewer tb(x,y) rect object (takes the mouse event clientX/Y  of jQuery with some tweaking) and send it to other peers which in turn use 

setZoomLevel(new zoomlevel)
docViewer.scrollTo(x,y)

many many thanks.
Danny

On Monday, June 13, 2016 at 9:11:12 PM UTC+3, Matt Parizeau wrote:

Danny Mendel

unread,
Jun 17, 2016, 2:15:26 PM6/17/16
to PDFTron WebViewer
ok i know how to access the $('#DocumentViewer')

i guess i need to see sample code which looks similar to zoomToMouse() but gives you X,Y coords based on user click/drag event.

this can be a great reference.
thanks
Danny

Matt Parizeau

unread,
Jun 17, 2016, 6:46:50 PM6/17/16
to PDFTron WebViewer
Hi Danny,

Yes if you want to select elements in the iframe from the outer page then the code you have is the way to do it. Maybe a slightly nicer way to have it would be:
var inner$ = $('iframe')[0].contentWindow.$;
var scrollView = inner$('#DocumentViewer');

I'm not sure sure if you were able to get everything that you wanted working, but you may want to try using the scroll event:
$('#DocumentViewer').on('scroll', function() {
  console
.log('scrolled');
});
This can be fired a lot by browsers so the debounce function on underscorejs might be useful http://underscorejs.org/#debounce.

Matt Parizeau
Software Developer
PDFTron Systems Inc.

Danny Mendel

unread,
Jun 20, 2016, 1:07:48 PM6/20/16
to PDFTron WebViewer
hi Matt
thanks to your advise
i have implemented throttle every 500ms send the scrollTop to other peers and it works nicely
using this code

$('iframe').contents().find("#DocumentViewer").on('scroll', throttledScroller);

var throttledScroller = _.throttle(function () {
            if (app.remoteSyncCommand) {
                app.remoteSyncCommand = false;
                return;
            }
            app.last_sync = app.sync;
            app.sync.invoker = app.username;
            app.sync.ts = new Date();
            if (app.sync.syncmap.length > 2)
                app.sync.syncmap.splice(2, app.sync.syncmap.length - 2);
            app.sync.synctype = 13;
            app.sync.syncmap[2] = { Key: "scroll", Value: this.scrollTop };
            if (app.sync.playback)
                app.sync.playback = false;
            else
                app.sendData("viewer", app.sync, "viewer");
        }, 500, {
            leading: false
        });


however i notice the "scroll" event effect the DocumentViewer on both sender and also on the receiver, the effect is intervention with the rendering of the smooth scroll, as if it miscalculate the exact rendering  (swap to other area) and than invalidate with right calc, offcourse increasing the frequency of call to 100ms become annoying to the eyesight, 
the question is there anything i can do to avoid this phenomena, or this is what it is if i use the "scroll" handler it has its own penalty.
 
many thanks
Danny

Danny Mendel

unread,
Jun 20, 2016, 1:07:48 PM6/20/16
to PDFTron WebViewer
Hi Matt,
$('#DocumentViewer').on('scroll', function() {
  console
.log('scrolled');
});
is a great idea, how ever in order to use it properly i think i will need a way to trigger docViewer.on('mouseLeftUp'....)
so with debounce i can control the event firing, and than i would simulate 'mouseLeftUp' with any mosuex/y, doesnt mater for me the coords so i can sync with other peers while scrolling on the invoker display, 
just need a quick guidance of yours, how to trigger this docViewer.on('mouseLeftUp'..) manually.

thanks
Danny

Matt Parizeau

unread,
Jun 21, 2016, 3:47:05 PM6/21/16
to PDFTron WebViewer
Hi Danny,

For smoother scrolling you could try using jQuery's animate function http://api.jquery.com/animate/.

For example:
var newScrollPosition = 1000;
var scrollTime = 1000;

$
('#DocumentViewer').animate({
    scrollTop
: newScrollPosition
 
}, scrollTime);

Matt Parizeau
Software Developer
PDFTron Systems Inc.

Reply all
Reply to author
Forward
0 new messages