Giter Club home page Giter Club logo

Comments (29)

primalmotion avatar primalmotion commented on May 30, 2024

BTW, here is a small demo of the result:
http://www.youtube.com/watch?v=c5MzTc-dGs8

from novnc.

kanaka avatar kanaka commented on May 30, 2024

Nice demo.

It's a good idea. Unfortunately, zoom doesn't seem to do anything in firefox 3.5 and when zoom is set in Chrome, the 'offsetParent' value is missing on that element and mouse position calculation (in include/util.js:getPosition) breaks.

I'll keep the bug open as an enhancement idea, but I suspect the more browser compatible way to do this will be with the width and height styles of the canvas element rather than the zoom style.

Also, as a note to myself, mouse event scaling should be implemented in include/util.js:getEventPosition().

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

yup, I saw the offsetParent bug. I'm working on it.
But I have a question: If I play with height, and width, do the ratio will be kept by noVNC or screen will juste be cropped ?

from novnc.

kanaka avatar kanaka commented on May 30, 2024

Actually, I think the CSS3 transform capability is probably the right approach:
http://www.westciv.com/tools/transforms/index.html
https://developer.mozilla.org/en/CSS/-moz-transform
http://www.webresourcesdepot.com/cross-browser-css-transforms-csssandpaper/
http://www.zachstronaut.com/posts/2009/02/17/animate-css-transforms-firefox-webkit.html

I've actually coded up a prototype patch. It works on Chrome and firefox. The main remaining problem is that the element still occupies the same amount of space in the layout as if it were full size. Probably the solution is to make the canvas a floating element and anchor it inside a

that gets sized to the scaled size. I'll probably put this on the backburner for now, but primalmotion, if you want to tackle that piece that would be great.

diff --git a/include/canvas.js b/include/canvas.js
index af52227..e88b75d 100644
--- a/include/canvas.js
+++ b/include/canvas.js
@@ -33,6 +33,7 @@ force_canvas : false,
 true_color : false,
 colourMap  : [],

+scale: 1,
 c_wx : 0,
 c_wy : 0,
 ctx  : null,
@@ -47,7 +48,7 @@ mouseMove   : null,
 onMouseButton: function(e, down) {
     var evt, pos, bmask;
     evt = (e ? e : window.event);
-    pos = Util.getEventPosition(e, $(Canvas.id));
+    pos = Util.getEventPosition(e, $(Canvas.id), Canvas.scale);
     bmask = 1 << evt.button;
     //Util.Debug('mouse ' + pos.x + "," + pos.y + " down: " + down + " bmask: " + bmask);
     if (Canvas.mouseButton) {
@@ -68,7 +69,7 @@ onMouseUp: function (e) {
 onMouseWheel: function (e) {
     var evt, pos, bmask, wheelData;
     evt = (e ? e : window.event);
-    pos = Util.getEventPosition(e, $(Canvas.id));
+    pos = Util.getEventPosition(e, $(Canvas.id), Canvas.scale);
     wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40;
     if (wheelData > 0) {
         bmask = 1 << 3;
@@ -88,7 +89,7 @@ onMouseWheel: function (e) {
 onMouseMove: function (e) {
     var evt, pos;
     evt = (e ? e : window.event);
-    pos = Util.getEventPosition(e, $(Canvas.id));
+    pos = Util.getEventPosition(e, $(Canvas.id), Canvas.scale);
     //Util.Debug('mouse ' + evt.which + '/' + evt.button + ' up:' + pos.x + "," + pos.y);
     if (Canvas.mouseMove) {
         Canvas.mouseMove(pos.x, pos.y);
@@ -158,6 +159,8 @@ init: function (id) {

     Canvas.clear();

+    Canvas.rescale(0.5);
+
     /*
      * Determine browser Canvas feature support
      * and select fastest rendering methods
@@ -248,6 +251,33 @@ resize: function (width, height, true_color) {

     Canvas.c_wx = c.offsetWidth;
     Canvas.c_wy = c.offsetHeight;
+
+    Canvas.rescale(Canvas.scale);
+},
+
+rescale: function (factor) {
+    var c, tp, x, y,
+        properties = ['transform', 'WebkitTransform', 'MozTransform', null];
+    c = $(Canvas.id);
+    while (tp = properties.shift()) {
+        if (typeof c.style[tp] != 'undefined') {
+            break;
+        }
+    }
+
+    if (tp === null) {
+        Util.Debug("No scaling support");
+        return;
+    }
+
+    if (Canvas.scale === factor) {
+        Util.Debug("Canvas already scaled to '" + factor + "'");
+    }
+
+    Canvas.scale = factor;
+    x = c.width - c.width * factor;
+    y = c.height - c.height * factor;
+    c.style[tp] = "scale(" + Canvas.scale + ") translate(-" + x + "px, -" + y + "px)";
 },

 stop: function () {
diff --git a/include/util.js b/include/util.js
index 64e3f93..0b22472 100644
--- a/include/util.js
+++ b/include/util.js
@@ -171,7 +171,7 @@ Util.getPosition = function (obj) {
 };

 // Get mouse event position in DOM element
-Util.getEventPosition = function (e, obj) {
+Util.getEventPosition = function (e, obj, scale) {
     var evt, docX, docY, pos;
     //if (!e) evt = window.event;
     evt = (e ? e : window.event);
@@ -185,7 +185,10 @@ Util.getEventPosition = function (e, obj) {
             document.documentElement.scrollTop;
     }
     pos = Util.getPosition(obj);
-    return {'x': docX - pos.x, 'y': docY - pos.y};
+    if (typeof scale === "undefined") {
+        scale = 1;
+    }
+    return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale};
 };

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

Ok. I'm on it. I'll see this tomorow

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

her.. git is not my cup of tea.
I copy your patch in a patch.ptc and then from my fork, I did
git apply ./patch.ptc

It tells me that the patch is corrupted at line 104, (the last)

Any clue ?

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

ok.. problem with number of line. This is OK.

By the way, is it OK for you to remove the "var" keyword in variable declaration?

I'm actually working with Cappuccino, and putting var to a varialble make the variable scope only from the file it comes.
And as the include of vnc.js (using @import) is processed to Cappuccino, the Canvas, RFB etc are not accessible to my application.

from novnc.

kanaka avatar kanaka commented on May 30, 2024

It's okay, but I'm trying to keep it JSLint clean and JSLint.

Note that in the near future I'm going to be scoping all global variables using standard Javascript function scoping and the caller will instantiate them. That should solve both issues (easy importing and JSLint clean).

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

scoping would be good.
I've move the initialization function (that includes extra JS file) in another file, arbitrary call "init.js", (but maybe renaming it vnc.js and old vnc.js to rfb.js would be better) in order to be able to not automatically include other JS file.

From my Cappuccino point of view, I use @import directive that solve the path alone without the need to give the prefix variable (which is unpredictable).

Is that also ok to you ?

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

Or (I think to myself) it would be better to add a function includeExtra() in RFB namespace directly.

from novnc.

kanaka avatar kanaka commented on May 30, 2024

I've gone with the approach of doing the loading in vnc.js. rfb.js now just contains the RFB namespace. Separating core code from UI/DOM and loading mechanisms has always been a goal of mine so that makes a lot of sense.

You can skip pulling in vnc.js and just load the files using whatever mechanism works best for you.

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

Great! I've also notice a problem with the stop() procedure of Canvas. Sometimes the canvas is gone from the DOM before the the stop is terminate. So it fails with removeEvents and resize. In my fork, I add simple tests for that: if Canvas is gone, there no need to remove anything more.

EDIT: it works like a charm, by the way. The only things I need to change from your code is the var Canvas, var RFB, and add the if (!c) {return} to resize and Canvas.{resize,rescale,stop} and it works great with my VNCCappuccino http://bitbucket.org/primalmotion/vnccappuccino)

from novnc.

kanaka avatar kanaka commented on May 30, 2024

Can you expand a bit on how the canvas element is going away and Canvas.stop() is still getting called? What code is calling it? Is RFB code calling it, or in VNCCappuccino?

I don't dynamically create and destroy canvas elements so I've not seen this. I think instead of putting conditionals everywhere, it's probably better to have some sort of tear-down in whoever is calling it.

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

This is Cappuccino that dynamically destroys element. VNCCappucino is a framework used by a module (equivalent to NSBundle in Cocoa) that can be arbitrary loaded or unloaded. And I saw a timer in your code about disconnection. It is obvious that Cappuccino's bundle loading doesn't care about this timer :)

What do you mean by "tear-down" ?

from novnc.

kanaka avatar kanaka commented on May 30, 2024

For example, if you can hook the event that destroys the canvas element, the Canvas.ctx variable should really be set to null at that point since there is no longer a rendering context. When a disconnect happens, I check to make sure that Canvas.ctx is valid before calling the stop() and clear() methods.

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

Ok I think I've finally understood my problem. Random error (not width property to undefined, can't dettachEvent of null, obj is undefined, etc..) is due to all the timers.
Sometimes, timers are still in the loop. the module unload and destroy DOM canvas. Timer is triggered, and boom.

So I need to keep track of all timers and be able to stop them all if I need to.

What do you think ?

from novnc.

kanaka avatar kanaka commented on May 30, 2024

Yeah, that would be my suggestion. All timer and intervals should be cleared when no longer valid. For example, the native Javascript routines setTimeout and setInterval return numbers which can later be used to clear them using clearTimeout and clearInterval.

There are a couple of approaches: the timers can be cleared externally by the "tear-down" event, or the timer functions them selves can detect if they are still valid and terminate the timer themselves.

For example, often intervals are done with setTimeout (rather that setInterval) and in the timer function the function sets a timeout for itself before it returns using setTimeout again.

For example, the following fires once a second until statevalid is no longer true:

function periodic () {
  if (! statevalid) {
    return;
  }
  // do something
  setTimeout(periodic, 1000);
}
setTimeout(periodic, 1000);

from novnc.

primalmotion avatar primalmotion commented on May 30, 2024

ok it works fine and all errors are gone. This is pushed to my fork.

Oh, and I also pass oldstate to RFB.externalUpdateState() because it is usefull to follow the events flow :)

from novnc.

kanaka avatar kanaka commented on May 30, 2024

I've pushed a couple of fixes to the scaling hooks that were introduced by recent keyboard/mouse handling refactor into include/input.js.

I've not pushed a UI change to support scaling since the DOM alignment is still screwy but here is a gist patch that adds the UI functionality in buggy form:
https://gist.github.com/948826

from novnc.

danielkho avatar danielkho commented on May 30, 2024

Hi, I'm just beginning to try out NoVNC. I like the idea that it's Ajaxy and nothing needs to be installed at client side. And it's responsive and fast! Great job here.

One of the problems I face is client-side scaling. I need to auto-fit the VNC screen to my client display and not follow the server-side resolution.
What is the best way to do this? I tried UI.rfb.set_scale=0.7 but this didn't work.

Also, if I manually resize the width and height of VNC_canvas like this:
#VNC_canvas {
background: #eee;
width: 100%; height:1000px;
}

It works, but breaks the mouse pointer positioning.

I'll keep on trying, but if you have some quick tips, please let me know.

from novnc.

kanaka avatar kanaka commented on May 30, 2024

As part of working on small form factor support such as phones and tablets (#48) I have implemented experimental viewport support into the tests/viewport.html file and it seems to work fairly well. The viewport is sized to the screen/browser size and you can scroll around. I will probably be integrating that into noVNC itself in the next couple of weeks.

I may also implement some level of scaling at some point too, but that's not my most immediate priority. The current scaling code in noVNC is really just experimental and is not fully cross-browser yet.

from novnc.

danielkho avatar danielkho commented on May 30, 2024

Hi joel,
Thanks, I've tried it out, and ported the code from viewport.html to vnc.html and ui.js. Looks like it's working, except that I see the default "fabric-like" graphics after a resize. Hovering my mouse over the canvas will update some pixels.

So I need a screen refresh feature so that I can get back my whole screen after a resize operation.
Also, I'm not sure if resize(), drawArea(), and canvas.resize() are going to rescale the screen? Or will they clip parts of the screen?
I just notice the canvas size got resized, but not sure if my whole screen gets "fitted" (or auto-scaled) into that canvas area.
I can't be certain until I perform a screen refresh.

Any ideas on how to do this? Where do I find the code for initial screen update immediately after a "VNC connect"?

I'm willing to share my code back to this project.

-daniel

from novnc.

kanaka avatar kanaka commented on May 30, 2024

Yes, the repeating pattern in viewport.html is just for testing out the principle. In the real thing, rather than drawing the pattern I will issue a series of framebuffer requests for the "dirty" regions that need to be redrawn.

Now that @snorkeyg has solved the keyboard input issue for touch devices, I have a pretty clear idea in my mind how to integrate all the pieces together and I'm planning on doing so in the next couple weeks. You're welcome to play around with it in the meantime and post your code in a fork. If it lines up with the direction I want to go (or it's better than what I have in mind) then I will pull in your changes.

from novnc.

danielkho avatar danielkho commented on May 30, 2024

hi joel,
i've just played around abit, and made tiny UI changes (basically porting some of the nice features in vnc_auto.html to vnc.html).

I'm still stuck at finding how to get a screen refresh. I'm in the middle of setting up Git and stuff, so you can have a look at my fork once I've got everything set up.

regards, daniel

from novnc.

kanaka avatar kanaka commented on May 30, 2024

@danielkho, I'll look at your fork. However, @snorkeyg has some pending refactoring that will enable noVNC on iOS (iPhone and iOS) that those changes will likely be landing in the next few days.

from novnc.

danielkho avatar danielkho commented on May 30, 2024

Hi joel, sorry I'm new to github and git. How do I do a fork? Do I do a "git
commit"?
I'm looking forward to the new updates by snorkeyg. Hopefully it has all the
good browser rescale features. :)

On Thu, Sep 1, 2011 at 11:14 PM, kanaka <
[email protected]>wrote:

@danielkho, I'll look at your fork. However, @snorkeyg has some pending
refactoring that will enable noVNC on iOS (iPhone and iOS) that those
changes will likely be landing in the next few days.

Reply to this email directly or view it on GitHub:
#12 (comment)

from novnc.

kanaka avatar kanaka commented on May 30, 2024

Go to a project page on github that you want to fork. In the upper right at the same level as the project name is a button called "Fork" which will create a copy of the repository for you as your own user (but with the same name). You can then clone that, make changes, commit, and then push those changes. Once you have the changes committed, in about the same place on the page for you project is a button labeled "Pull request". This will create a new pull issue in the original project where I can review and comment on the code changes and merge them into the upstream.

from novnc.

kanaka avatar kanaka commented on May 30, 2024

@danielkho. Scaling support will probably be a little ways down the road. Initially it will be viewport support since this will work across a range of devices. With scaling, you still have to download and render exactly the same amount of data so it would be unusable for iPhone 3G as an example. Scaling support is on the roadmap but it's less important to me right now that viewport support. For the next generation of smartphones (e.g. dual-core, LTE), scaling will make more sense.

from novnc.

DirectXMan12 avatar DirectXMan12 commented on May 30, 2024

closing due to age.

from novnc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.