• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 459
  • Last Modified:

Coordinates conversion from HTML's pixels to Flash's MovieClip

Hi all!

I am implementing an HTML page which contains Java Script-controlled Macromedia Flash Player. In Flash Player is loaded some static SWF which also is generated by me, thus it is under my control and i can add any Action script inside SWF.

I want to  implement viewer's functionality including: zooming, scrolling and "zooming by window" in some variations.  I want to implement the most amount of this functionality in HTML's Java Script (for Internet Explorer and Netscape Navigator) and do not want to include a large and complex scripts into the SWF.

I found 3 alternative ways in "Flash Player"'s API to implement this:
  a) Pan and Zoom functions;
  b) set "Flash Player"'s properties by means of  TSetProperty (X_POS, Y_POS, X_SCALE, Y_SCALE);
  c) use SetZoomRect function.

The "a)" way is incomplete: it prohibits the "zooming by window" functionality. Therefore i consider b) now. The most amount of Java Script's code is implemented and working already, but one obstacle is met:
                    i do not know HOW TO CONVERT COORDINATES from HTML's pixels to Flash's document.

Somebody has ideas?
Thanks in advance for any response!


In addition, i want to explain a code snippet illustrating current implementation:

var f = document.getElementById( "idFlashPlayer" ); //in Microsoft Internet Explorer it is <object> tag with id="idFlashPlayer"
var currScale = 1;
var shX = 0, shY = 0;

function onZoomOut()
{    
     var cx1 = getCenX(), cy1 = getCenY();
     
     currScale /= 1.5;    
     putZoom( currScale );

     compensateShift( cx1, cy1, getCenX(), getCenY() );    
     putShift( shX, shY );
}
function onZoomIn()
{    
     var cx1 = getCenX(), cy1 = getCenY();
     
     currScale *= 1.5;    
     putZoom( currScale );

     compensateShift( cx1, cy1, getCenX(), getCenY() );    
     putShift( shX, shY );
}

function putZoom( newZoom )
{
     var zoom = Math.round( newZoom * 100.0 );    
     f.TSetProperty( "/", 2, zoom );
     f.TSetProperty( "/", 3, zoom );
}
function compensateShift( cx1, cy1, cx2, cy2 )
{
     shX = shX + (cx2 - cx1) * currScale;
     shY = shY + (cy2 - cy1) * currScale;    
}
function putShift( shx, shy )
{
     f.TSetProperty( "/", 0, Math.round(shx) );
     f.TSetProperty( "/", 1, Math.round(shy) );
}

function getCenX()
{
     var v = pixelsWidthToFlashNotScaled( clientWidth() );
     return (v/2.0 - shX) / currScale;
}
function getCenY()
{
     var v = pixelsHeightToFlashNotScaled( clientHeight() );
     return (v/2.0 - shY) / currScale;
}

function clientWidth()
{
     return f.clientWidth;
}
function clientHeight()
{
     return f.clientHeight;
}

function pixelsWidthToFlashNotScaled( v )
{
     return v * 1.6;
}
function pixelsHeightToFlashNotScaled( v )
{
     return v * 2.9;
}

You can see, i found only magic coefficients 1.6 and 2.9 which are permitting to convert coordinates from HTML's pixels to Flash's document. This is a partial and inaccurate solution and works only for view's center.  pixelsWidthToFlashNotScaled and pixelsHeightToFlashNotScaled  should be substituted by natural conversion functions.



0
Alexey Fedorov
Asked:
Alexey Fedorov
  • 5
  • 3
1 Solution
 
negatyveCommented:
I made this example (inside a tutorial) some times ago:

http://flash-mx.html.it/guide/swf/negatyve_javascript/SetZoomRect/SetZoomRect.html

the image button at the top zooms over the middle area in the bottom most movie. The first button of the middle movie zoom on the little area and the second one on the bigger one. You can download the source from here:

http://flash-mx.html.it/guide/zip/negatyve_javascript/SetZoomRect.zip

To the setZoomRect function you have to pass 4 parameters:

filmato.SetZoomRect( x1, y1, x2, y2 )

the first two parameters are the coordinates of the top left angle of the rectangle to zoom in, while the third and the fourth are the coordinates of the bottom right angle.
The unit of those forth parameters is "twips", which correspond to 1440 point per inch, so, to convert them to pixel (72 point per inch) you have to multiply them for 20.

ie, to zoom the area that goes from (x:10, y:10) to (x:100, y:100) you'll do:

function zoomMovie(x1, y1, x2, y2)
{
      var f = document.getElementById( "idFlashPlayer" )
      f.SetZoomRect(x1 * 20, y1 * 20, x2 * 20, y2 * 20);
}
zoomMovie(10, 10, 100, 100);
0
 
Alexey FedorovSoftware developerAuthor Commented:
Thanks, negatyve.

The using of "SetZoomRect" function is the third variant of the implementation. But it is still out of scope. This function prohibits of using X_POS,  Y_POS, X_SCALE and Y_SCALE properies. They will be ignored by "Flash Player" if "SetZoomRect" was called.

"SetZoomRect" is a well known documented function. Mentioned above information about x1-y2 and "twips" is available on the official Macromedia site:  
"http://www.macromedia.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html".

Possible, i will soon try to implement viewer's functionality by way "c)", but i think, it can be got involved with obstacles of another kind.

Now, i want to finish "b)" implementation, based on X_POS,  Y_POS, X_SCALE and Y_SCALE properies. In order to do this i should correct
pixelsWidthToFlashNotScaled and pixelsHeightToFlashNotScaled functions (see my code snippet). Now they are based on a "fake" coefficients 1.6 and 2.9. I need to find out the proper transformation from HTML-pixels to Flash-document  coordinates.

For example, if i click mouse button over the Flash and i know client coordinates in pixels relative the left upper corner of the HTML's <object> tag, how i can  calculate Flash's coordinates?
0
 
negatyveCommented:
Probably (maybe it's a matter of language, I'm not a native english speaker) I cannot understand what you are doin. Can you show me a working example of what you are doing (even with your empyric conversion system)?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
Alexey FedorovSoftware developerAuthor Commented:
Current example of the implementation is available at "http://afedorov.dyndns.info:81/FlashDemo/Flash2.aspx".
Host is on slow connection - please wait when page opens.
0
 
negatyveCommented:
ok, so you wnat to fit the zoom when clicking on a diagram part?
0
 
Alexey FedorovSoftware developerAuthor Commented:
Now you can see the application and i can discuss requirements in more details.
Coordinates translation HTML-pixeld --> Flash-document is required for:
  1) constraints implementation (viewed Flash-document should not be prohibited from complete disappearing during shifting and zooming);
 (now constraints are implemented, but they are based on a "fake"  pixelsWidthToFlashNotScaled and pixelsHeightToFlashNotScaled functions, thus a bit inaccurate)

  2) dragging Flash-document by mouse (as an additional panning tool);
(still is not implemented)

  3) zooming by window (user draws rectangle by mouse over the Flash-document; after that, current view zooms to fit selected area).



0
 
Alexey FedorovSoftware developerAuthor Commented:
Sorry, i forgot to remember one more goal:
  4) compensation of the shifts caused by "ZoomIn", "ZoomOut", "100%", "Zoom Exactly" functions.
(now is implemented, but, also, based on "fake" pixelsWidthToFlashNotScaled and pixelsHeightToFlashNotScaled functions).

You can see "4) compensation" in live application: 2-3 times click "+" button, shift Flash-document by arrows, now try to ZoomIn/ZoomOut the shifted Flash: you can notice - zooming is performing relative of the current view's center instead of zero.

In to be more clear, i want to summarize obstacles:
  the main problem is in - how to calculate (Xf, Yf)  by (Xp, Yp), where Xf and Yf are Flash-document's internal coordinates; Xp,Yp - are HTML's coordinates in pixels relative (0,0) of the <object> tag of the "Flash Player".

0
 
Alexey FedorovSoftware developerAuthor Commented:
I had solved question. Solution turned out extremely simple.

<PARAM NAME="Scale" VALUE="noscale"> and <PARAM NAME="SAlign" VALUE="LT"> should be set in HTML inside tag <object> and corresponding properties should be set on the nested tag <embed>. As the result, coordinates matching will be reached between HTML and Flash. Now they are 1:1 and identity matrix HTML-->Flash can be used, that is to say - no matrix is needed.

Now, coordinates translation HTML-->Flash looks like:
function toFlash2X( val )
{
      return (-shX + val) / currScale;
}
function toFlash2Y( val )
{
      return (-shY + val) / currScale;
}
where shX, shY - are current shifts MovieClip._x, and MovieClip._y. They can be set as
var f = document.getElementById( "idFla" );
f.TSetProperty( "/", 0, shX.toString() );
f.TSetProperty( "/", 1, shY.toString() );

currScale - normalized zoom-factor. Can be set as:
var zoom = (currScale * 100.0).toString();
f.TSetProperty( "/", 2, zoom ); //zoomX = zoomY
f.TSetProperty( "/", 3, zoom );

HTML coordinates should be got relative <object>'s client area of the "Flash Player":
toFlash2X:

f.onmousedown = onMouseDownFlash;
function onMouseDownFlash( e )
{
   var ev = new InterEvent( e );
   var flashX = toFlash2X( ev.cliX );
   var flashY = toFlash2Y( ev.cliY );
   //Do something...            
   return true;
}

function InterEvent( e )
{
      this.ev = (typeof(e) != "undefined" ? e:window.event);

      if( typeof(this.ev.offsetX) != "undefined" )
      {
            this.cliX = this.ev.offsetX;
            this.cliY = this.ev.offsetY;
      }
      else //NN, Mozilla, FFx
      {
            this.cliX = this.ev.layerX;
            this.cliY = this.ev.layerY;
      }
}
0
 
DarthModCommented:
PAQed with points (100) refunded

DarthMod
Community Support Moderator
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now