Zoom image given x and y - javascript

I have an image which as a "ruler" (made of basic divs positioned absolute on top of the image) that are use to measure the ends of the image. Now the idea is that if you long press one of the ruler ends (the dots at the end of the line which are draggable), the image in the background would zoom in that point, and follow the dot if the user moves it. I am able to detect the long press but I cannot get the image to zoom and follow the dot once detected. The code below is where I have done the detection and now I should apply the styling to move the image. I thought of using the transition property but couldn't get it to zoom on the dot. Any help is appreciated...
Here's a codesandbox with how the ruler works: Link
Meaningful code:
const x = get('x', varToUse); //This just gives the x coordinate of the ruler end
const y = get('y', varToUse); //This just gives the y coordinate of the ruler end
const image = ruler.current.parentElement.parentElement.childNodes[1].childNodes[1];
if (zoom) {
image.style.transform = `translate(${x * 2}px, ${y * 2}px) scale(2.0)`;
} else {
image.style.transform = `scale(1.0)`;
}
This is what the ruler looks like just to get an understanding:

You can make the image a div with background-image.
.image {
background-image: url({image_url});
}
so this way you can update the image size and position easily with this properties
.image {
background-size: x y;
background-position x y;
}
I think this way is easier to do the image resizing and zoom abilities.
another way is to use a canvas library that can help you a lot they have lots of built in functions.
I think trying it without library is better for now but as it grows try to move to a canvas library

The first reason is that in the code you provided, the DOM element that is being manipulated is a div id='root'. The image should be selected.

Related

Resizing and rotation on svg (Raphael.js) creates jumping

I've been working on this problem for days. I am trying to implement a "free transform" tool for svgs. Similar to that of Raphael.FreeTransform or how you would move/rotate/scale images in MS Word. (Yes, I am aware there are libraries) The following jSFiddle displays my problem: https://jsfiddle.net/hLjvrep7/12/
There are 5 functions in the jsFiddle: rotate-t. shrink-t, grow-t, shrink, grow. The functions suffixed with '-t' also apply the current rotation transformation. e.g.:
grow-t
rect.attr({height : height * 1.25, width : width * 1.25}).transform('r' + degree);
grow
rect.attr({height : height * 1.25, width : width * 1.25});
Once an svg is rotated, then scaled. If you try to rotate the svg again (after scale), the svg jumps. To see this, go top the fiddle:
Hit rotate-t twice. Svg should rotate a total of 30 degrees from the rectangles origin.
Hit grow (not grow-t) twice. Note the top left position of the svg stays the same.
Hit rotate-t once. Note the svg jumps to a different position, then rotates.
Note hitting rotate-t subsequent times will continue to rotate the image around the origin (which is what I want the first time rotate-t is clicked)
One solution I had was to apply the current rotation transformation whenever changing the height and width. This fixes my previous problem, but introduces another problem. To see an example of this, go to the fiddle, and:
Hit rotate-t twice.
Hit grow-t a couple times. Notice the svg grows, but the top left position of the rectangle moves. That's a problem for me. I want the svg to grow without the top left corner to move.
Notes on using the jsFiddle:
Any combination of rotate-t, grow-t, shrink-t will exhibit the ideal rotation behavior (about the origin, no jumping). But this also demonstrates the undesired growing and shrinking (top left position moved when svg is on angle).
Any combination pf rotate-t, grow, shrink will exhibit the ideal scaling behavior (top left corner of svg doesn't move). But this also demonstrates the undesired rotation property (will jump around after different rotations and scales).
Bottom line: I want to be able to the svg rotate around the origin. Then grow the image, while the top left position remains the same. Then rotate the svg again, around the origin without any jumping.
I am aware the how the transform function impacts the local coordinate system of the svg. I'm leaning towards using rotate-t, grow, shrink combo and simply apply some x-y offsets to remove the "jumping" effect. I would imagine there must be some sort of offset I could apply to avoid jumping or shifting during rotation or scaling, but its not clear to me how to calculate such offsets. Any help would be appreciated.
Please don't hesitate to ask anymore questions. Like I said, I've been digging into this for days. Clearly, I don't understand it all, but am somewhat intimate with what's happening and happy to explain anything in more detail.
My solutions for scale, rotate, move back and front etc:
$scope.back = function () {
if($scope.currentImage !==null) {
if($scope.currentImage.prev!=undefined) {
var bot = $scope.currentImage.prev;
$scope.currentImage.insertBefore(bot);
ft.apply();
}
}
};
//Function for moving front
$scope.front = function () {
if($scope.currentImage !==null) {
if($scope.currentImage.next!=undefined) {
var top = $scope.currentImage.next;
if($scope.currentImage.next.node.localName == "image")
$scope.currentImage.insertAfter(top);
ft.apply();
}
}
};
//ZOOM
$scope.zoomIn = function () {
if ($scope.currentImage!= null) {
var ft = paper.freeTransform($scope.currentImage);
if(ft.attrs.scale.y<4) {
$scope.currentImage.toFront();
ft.attrs.scale.y = ft.attrs.scale.y *(1.1);
ft.attrs.scale.x = ft.attrs.scale.x *(1.1);
ft.apply();
ft.updateHandles();
}
}
};

Getting CSS left and top when div is rotated

I'm trying to get the style.left and style.top of a rectangular div, after it has been rotated using style.transform=rotate(90deg).
I understand how the div is being rotated, with it being rotated around a 'transform point'. And I also understand that a div could be rotated by 45 degrees, so giving the new top/left of that would be awkward (In effect giving the bounding box left/top).
But back to the original question, rotating the rectangular div by 90 degrees, is there a way to get the 'new' left/top?
The reason I need this, is for a project im working on to upload images, allow the user to zoom, rotate etc, but currently having to do it with PHP to keep all the dimensions correct for the final image (Which is obviously bad, because I'm having to keep loading a new image once PHP has done the rotating/zooming etc)
I've also made a little jsfiddle showing that the top/left position doesn't change when it is rotated
Okay, thanks to the comment left above, I managed to throw together an answer.
Basically using:
newleft = parseInt(div.style.top) + Math.cos(90) * parseInt(div.style.height);
newtop = parseInt(div.style.left) + Math.sin(90) * parseInt(div.style.height);
after the div had been rotated.
I've updated my jsfiddle aswell, because the one in the comment above uses jQuery, but this way uses only javascript.

Zoom-in and Zoom-out image when Mouse Scroll

I want to zoom-in and zoom-out image on mouse scroll in HTML. There are multiple img tag without ID. So how can I do it using JavaScript or Ajax?
Just throwing the answer for the ones that will search for an answer to this question.
First, you will need to find a system to detect the mouse scroll.
If you are courageous, you can develop it yourself.
If you're not, you can find some pretty good libraries (ex : MouseWheel with JQuery).
Next, you will find another two ways to zoom in and out.
Easy way
First, let's cheat a bit.
When you will have to zoom, just multiply the height and width of your image by a factor you will decide.
To have height and width into a variable (JQuery)
var height = $('#image').height();
var width = $('#image').width();
For each scroll you will receive, you will only have 2 choices.
Once you are able to know if the mousewheel goes up or down, you will just have to do something like this (JQuery)
height *= 2;
width *= 2;
This way, by doubling the size of your image, you will have the impression to zoom in.
Less easy way
If you want to zoom in as you would do in a GMap object, you can do something like that.
var firstHeight = $('#image').height();
height *= 2;
width *= 2;
scalechange = (actualHeight / firstHeight) - 1;
offsetX = -(coordX * scalechange);
offsetY = -(coordY * scalechange);
$("#image").css('top', offsetY + 'px');
$("#image").css('left', offsetX + 'px');
First, you have to have the first height of your image.
Next, you will double the size of your image (zoom effect).
Next step is to calculate the scalechange. You will be able to find multiple explanations and many way to calculate it, my method is as good as another.
The two offsets presented are the new positions that your image will adopt (simple factor calculation, it's like making x percent on a price).
Last part is to set the new values of your image.
In the end, you will be able to zoom and unzoom with ou without centering the image at your mouse position.
Be careful : The calculation above in only to zoom-in. You will have to do some maths to get the zoom-out!
Go further ?
Another way to go further would be to place your image in a div.
<div id="imageContainer" style="overflow:hidden;">
<img id="image" src="YourImage">
</div>
By setting
"overflow:hidden;"
to your div, your image will zoom.
But everything that will overflow your div will be hidden.
If you set your div to the original size of your image, like this (JQuery)
$("#imageContainer").css('height', $('#image').height());
$("#imageContainer").css('width', $('#image').width());
Then you will have an image displayed that will always be at the same size, but your zoom will be effective.
If you combine this to a drag'n'drop method, you have a GMap object-like (zoom in-out, moove the zoomed image, ...)
Hope it will help someone!

Get coordinates of image within a box

I need to grab the following coordinates topX, topY, bottomX, bottomY, as they represent a box around a source image. They are equal to:
topX = X coordinate at top left corner on source image
topY = Y Coordinate at top left corner on source image
bottomX = X coordinate at bottom right corner on source image
bottomY = Y coordinate at bottom right corner on source image
Here is a sample plugin that calculates these values. The source image width = 1024px and the height = 750px:
http://thindery.com/jsfiddle/crop_move.html
However, I have a new plugin that does more functionality than the above plugin, but I can't figure out how to get these 4 variables I need.
here is the jsfiddle http://jsfiddle.net/thindery/cv96e/
i tried to create my own boxedCoords(), based on how the original plugin calculated the values. However i'm still new to jQuery and I can't get it to work.
anybody have an idea how I can get these 4 variables?
This was solved. For the solution: jsfiddle

Spot the ball game, zooming problems, jQuery

I am trying to create a spot the ball game, so it will (eventually) be an image of a player kicking a ball but the ball has been removed and the player needs to click where the ball should be.
The first version went well and works.
http://enjoythespace.com/sites/game/test.html
But what I need to add is some sort of zooming so you can see more accurately where you are clicking. I been playing around and have come up with this
http://enjoythespace.com/sites/v2/demo.html
But once you click it looks great when zoomed in but when you go back to the image its way off.
I think its todo with how the image is setup, the #webpage is half the original size of the image and the #retina uses the full size of the image.
Any help?
The first problem is that you aren't setting the retina backgroundPosition correctly.
This code works (I added a zoom variable to make it clear how changing the zoom would change the calculation, but it would need other changes too):
/* Moving the retina div with the mouse
(and scrolling the background) */
zoom = 2.0;
retina.css({
left : left - sizes.retina.width/2,
top : top - sizes.retina.height/2,
backgroundPosition : ""+(-zoom*left+sizes.retina.width/2)+'px '+(-zoom*top+sizes.retina.height/2)+'px'
});
Test this by checking that all four corners are seen correctly in the retina, i.e. when you're over the corner of the main image, the corner should be in the center of the retina circle.
The second problem is if you resize the browser the position calculations are out because the offset variable isn't updated for the new size. A simple way to do this is to put this as the first line of webpage.mousemove() so the offsets are updated every time:
var offset = { left: webpage.offset().left, top: webpage.offset().top };
It looks like you are passing the top/left position click point of the zoomed image to highlight where you have clicked. What you will need to do is alter your top/left position based on whether the fisheye is over the image or not.
Does the un-zoomed image have to be part of the news page or can it be a standalone image?
If it can be standalone then the solution should be quite simple. If the zoomed in image is twice the size of the unzoomed one then you can just set the top/left values of the highlight to half the value of the zoomed, when looking at the unzoomed.
Jquery position will allow you to accurately get the position.
jQuery Position()

Categories

Resources