Seadragon ajax fix coordinates system - coordinate-systems

I'm trying Seadragon Ajax with coordinates system in order to show in my website large images with big resolution .
I would to view a part of this image knowing their coordinates. The problem is that when I make zoom or drag the image , coordinates no longer correspond to the same part of the image.
I try with some code but no way.I need that coordinates system is fix for all the image .
As i can do?
Thanks

Sure, no problem. You have to transform the "real" pixelbased coordinate to the seadragon point-coordinate.
"Seadragon Ajax uses a normalized coordinate system. The top-left of the image is always at the origin (0, 0) while the width of the image is always 1. The height of the image is dependant on the aspect ratio, so an image which is half as tall as it is wide will have a height of 0.5"
So, if you know that your image is 500x500px, then point 1,1 = 500px,500px and 0.5,0.5 = 250px,250px.
Convert by writing a function like this:
var my_position_x=333; // the position you want to get point for
var my_position_y=666; // the position you want to get point for
var width=500;
var height=500;
var pointx=1/width * my_position_x;
var pointy=1/height * my_position_y;

Related

How to resize and reposition PaperJs drawing with canvas size change?

I'm creating an application using Paperjs to drawing some sketch on an image, persisting the sketch without the background and display back the sketch along with background image.
In my Paperjs canvas, I have a raster image and on top of that I'm making some sketch pointing a part of the background image. After the drawing is done, I'm doing JSON export, excluding background raster image, to persist the drawing. Now when I export it back, the background raster image is generated dynamically and the Paper canvas size is set to the size of the image. But if the browser window size is different then the size of the image will be different than where the original drawing is created.
The issue that I'm facing if the image size isn't the used while creating the sketch, its pointing to the different part of the image. Is there any way we can proportionally change the paperjs drawing so that the sketch points to the same point of the background raster image?
Any help would be appreciated.
Below is an example :
With actual size -
After resize
I'm able to achieve what I wanted to with the below changes. Thanks #arthur.sw for your help.
Here originalViewSize is the original size on which the actual sketch was created.
Steps:
Update view size
Calculate x-axis and y-axis scale factor
Update bounds for background image
Update active layer positions
Scale active layer
// Changing view size and calculating scale factor for x & y-axis
paperScope.view.viewSize = new Size(originalViewSize.width + 200, originalViewSize.height + 100);
const xScale = paperScope.view.viewSize.width /originalViewSize.width;
const yScale = paperScope.view.viewSize.height /originalViewSize.height;
// Update b/g image bounds
backgroundRaster.bounds = paperScope.view.bounds;
paperScope.project.activeLayer.position.x = paperScope.project.activeLayer.position.x * xScale;
paperScope.project.activeLayer.position.y = paperScope.project.activeLayer.position.y * yScale;
paperScope.project.activeLayer.scale(xScale, yScale);

Scaling ImageView Programmatically

I have 7*7 ImageViews and I want to put them scalingly in some positions.
I need to know how I scale ImageView and how to set their position relatively to screen size.
(I will need to reposition and animate them dynamically after program start)
You need to add a CGAffineTransormation onto the image view
imageView.transform = CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
This will scale down the image view, and will give you your desired output
Dealing with the repositioning, all you gotta do is add a CGAffineTransformationTranslation
imageView.transform = CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
Do this with all the image views that you watn, and you will get what you want
Hope this helps!

Trying to zoom image based on mouse origin, yet my math is slightly off

I'm working on a full screen image viewer, I'll temporarily open a dev URL here:
http://www.jungledragon.org/apps/jd3/image/704/great_grey_owl.html/zoom
This viewer is responsive and scales to your browser width/height. One of its key features is being able to zoom in and out of the image using your mouse wheel. Rather than a center-based zoom, the idea is to zoom based on origin, meaning the coordinates of your mouse, allowing you to zoom into specific areas of the image.
How to reproduce the issue
If you open the above URL and have a quick play with your mouse wheel, it may appear to be working correctly. However, the math I am using is slightly off. Here is how you can reproduce the issue:
Open the above URL
Hover your mouse over the left eye of the Owl
Zoom one step using your mouse wheel, it should zoom exactly into the eye
Position your mouse on the owl's beak
Zoom one more step using your mouse wheel
You should now notice that the second zoom step did not go into the Owl's beak exactly, it seems to be slightly off, both horizontally and vertically. I'm thinking this is a result of bad math.
How it works
Here is the javascript that handles it all:
http://www.jungledragon.org/apps/jd3/js/jd3-slideshow.js
I am capturing the mousewheel event. Based upon its direction, I am increasing or decreasing the zoom level. The actual zooming is nothing more than applying a CSS class that scales the image using a CSS3 transform:
&.grow1 { #include jd-scale(1); }
&.grow2 { #include jd-scale(1.5); }
&.grow3 { #include jd-scale(2.0); }
&.grow4 { #include jd-scale(2.5); }
&.grow5 { #include jd-scale(3.0); }
Note: the above is a call to a SASS mixin that translates into the right vendor prefixes for transform:scale.
The above accomplishes the basic zooming without issues. To make origin-based zooming possible, however, a few more steps are needed. Upon doing the actual zooming, I first set the origin of the zoom in javascript, using transform-origin. Here is my helper function for setting it:
function zoomOrigin(selector, originStr) {
selector.css({'-webkit-transform-origin': originStr});
selector.css({'-moz-transform-origin': originStr});
selector.css({'-ms-transform-origin': originStr});
selector.css({'-o-transform-origin': originStr});
selector.css({'transform-origin': originStr});
}
The heart of this question is about calculating the correct origin. There are two things worthy to mention in calculating this value:
The absolute coordinates (meaning the X and Y) are relative to the image, not relative to the page
The calculation of the origin should take into account that the image has grown/shrunk based on the current zoom state
The origin calculation happens in realtime, based on the mousemove event. Here is the method that does so, with irrelevant parts removed:
$("#image-container img").mousemove(function(e) {
// user has moved their mouse. in case of zooming or panning, this means that the
// origin (center point) of those interactions need to be recalculated
// calculate the mouse offset within the zoomable object (which is different than the page-level offset)
// this relies on the parent of the element having position:relative set
var parentOffset = $(this).offset();
zoomOriginX = e.pageX - parentOffset.left;
zoomOriginY = e.pageY - parentOffset.top;
// recalculate the width and height of the image given the current zoom level
width = $(this).outerWidth() + (1 + ((zoomLevelCurrent - 1)*0.5) * $(this).outerWidth());
height = $(this).outerHeight() + (1 + ((zoomLevelCurrent - 1)*0.5) * $(this).outerHeight());
// calculate origin percentages based on zoomed width and height
// the zoom methods rely on these variables to be set
zoomOriginPercX = (zoomOriginX / width * 100);
zoomOriginPercY = (zoomOriginY / height * 100);
});
The main purpose of this method is to correctly set the global variables zoomOriginPercX and zoomOriginPercY, which are used to set the origin (percentage) prior to zooming.
From a math perspective, my idea was to simply calculate the zoomed width of the image, and to use the offset X and Y to come to a reliable origin percentage. As the problem statement shows, I am quite close to a correct calculation, yet something is off.
Although the zooming currently works well, I want it to be perfect. It would make for quite a powerful image viewer that is really easy to implement, also for others.
Desired Effect
To start answering your question I think it's worth first clarifying the desired effect. Essentially you're looking for the same effect you'd get if you pinched to zoom on an iPhone - the 'origin' of the pinch stays exactly the same, and everything around it stretches. You can imagine pinning some stretchy fabric at the origin, and pulling the corners.
Problem
This is working fine for you if you don't move the mouse between zooms, but if you do, the origin appears to move. The cause of the problem is exactly that - you are changing the origin of the transform every time you move the mouse. Of course you do need to do this, but you are calculating the origin based on the original (100% zoomed) position of the image. The actual origin needs to be somewhere between the origin of the first zoom and the new mouse position.
In other words, CSS is just doing one transform. If you set the origin to x,y then zoom to zoom level 2, this will give the same result as if you set the origin to x2,y2, zoom to level 1, then move to x,y, and go to level 2.
Solutions
I presume you could solve the issue in several ways:
Calculate a scaling factor for the 'new' origin on each zoom
this is likely a function of zoom level, mouse position and previous origin
Calculate and apply a translation each time the origin is moved
again will depend on the current origin, zoom level and mouse position
Find another way to 'stack' transforms on top of one another.
One way to do this may be to dynamically generate a new containing div each time you and apply a scale transform to that similar to the accepted solution in this question.
Unfortunately I don't have the time to go further than this, but hopefully it points you in the right direction?

How to scale and clip a BitmapImage in Flex 4.5

Here's my problem, I need to scale and clip images into square sized tiles to put into a tile list. Here's how I want it to work:
I want all my tiles to be, say, 300px x 300px.
For each image, I want to scale the shorter side (either width or height) to fit in the tile using the "letterbox" scaleMode (so that it maintains aspect ratio).
Then I want to position the image in the center and clip away anything left over from either both sides or the top and bottom.
Here's an example to help clarify:
I have an image with width=600px and height=1200px. First I want to scale the image to width=300px and height=600px (notice that aspect ratio is maintained), then center the image vertically and clip the image to 300 x 300.
Is this possible? This is actually a pretty standard way of displaying square thumbnails in many photo-based web sites, but I can't find a way to make it work in flex.
Any help would be appreciated, thanks!
UPDATE JUNE 2012:
Just in case anyone finds this thread now, this issue has been resolved in the latest version of the Flex SDK. On the spark image object there is a new scaleMode of "zoom" which does exactly what I've asked for here.
Take your big image and draw it on BitmapData with scale and reposition:
const zoom:Number = Math.max(THUMB_WIDTH/image.width, THUMB_HEIGHT/image.height);
const x:int = (THUMB_WIDTH - image.width*zoom)/2;
const y:int = (THUMB_HEIGHT - image.height*zoom)/2;
var matrix:Matrix = new Matrix;
matrix.scale(zoom, zoom);
matrix.translate(x, y);
var _thumbBitmap:BitmapData = new BitmapData(THUMB_WIDTH, THUMB_HEIGHT, false, 0xFFFFFF);
_thumbBitmap.draw(image, matrix, null, null, null, true);
Then assign resulting BitmapData to the source of the BitmapImage.
More: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#draw%28%29
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/primitives/BitmapImage.html#source

Find Upper Right Point of Rotated Rectangle in AS3 (Flex)

I have a rectangle of any arbitrary width and height. I know X,Y, width, and height. How do I solve the upper right hand coordinates when the rectangle is rotated N degrees? I realized if it were axis aligned I would simply solve for (x,y+width). Unforunatly this doesn't hold true when I apply a transform matrix on the rectangle to rotate it around its center.
It's usually easiest and fastest to let Flash's display code do these kinds of things for you. Create an empty Sprite and put it inside the rectangle's display object at the corner you want to track. Then, find the location of that sprite in the coordinate space of your choice:
var p:Point = new Point(0,0);
myRectangle.myCornerSprite.localToGlobal( p );
someDisplayObject.globalToLocal( p ); // for a coord space besides the stage
This gets you out of making any assumptions about the rectangle's design (i.e. registration point), and works even if the rectangle should be skewed or scaled as well as being rotated. Plus, this will be much easier to implement and maintain then a mess of cosines and whatnot.
(Note that the code above assumes that "upper right" refers to a specific corner - if you want to examine whichever corner happens to upper-rightmost at the moment, I'd simply add do the same thing with a sprite at all four corners, and pick whichever is to the upper right in global coords.)
You just have to calculate the point on a circle for the given radius. The center of your rectangle will be the circle's origin and any corner will be a point on the circle's circumference. You need to use trigonometry to calculate the new point using the rotation. I don't have time right now to explain all this, but here is a link to a decent 2D Javascript library I've used in the past and which should give you everything you need (bearing in mind that the math is virtually the same in Javascript and ActionScript) to work it out for yourself.
http://jsdraw2d.jsfiction.com/viewsourcecode.htm

Resources