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!
Related
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.
Hi I'm looking at the Scroll Drawing examples over on W3Schools and CSS Tricks. Both examples use Javascript and an SVG path to "draw" an element on scroll. They also both base the length of the drawn path according to how much the document body has been scrolled (scroll percentage). Here's how they calculate their scroll percentage:
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
Does anyone know how I can change the scroll percentage so that it calculates based on how far down a div has been scrolled?
Here's a Fiddle where I tried using the y of the div's boundingClientRect() divided by the window.innerHeight. This probably doesn't make sense because it seems to be drawn over and over again, but I'm trying to figure out the math. The SVG in this case is sticky to the div (instead of fixed). This only kind of works in that the SVG path is drawn on scroll, but it's drawn over and over again until you've scrolled past the height of the div.
My desired outcome is for it to be drawn once completely when scrolled 50% down the div and stay drawn for scrolling the remaining 50% of the div.
I hope this makes sense. Thanks for your help in advance! Any references would help too in terms of JS math and logic!
Also, for the SVG itself, do you know which end of the path is the one that starts?
Okay, I figured this out. Here's the complete fiddle
The math for calculating the scroll percentage: get the amount that the window has scrolled and divide by the height of the div (that the SVG is in). You then want to divide this in half so that the drawing completes halfway before div finishes scrolling:
var svgContainer = document.getElementById("svg-container");
var svgContainerRect = svgContainer.getBoundingClientRect();
var svgDivHeight = svgContainerRect.height;
var windowScroll = window.pageYOffset;
var scrollPercent = windowScroll / svgDivHeight *2;
Then, for the drawing to remain "drawn" after scrolling halfway through the div, throw the "drawing function" into an "if". This stops drawing once the scroll percentage reaches 1 (reaching halfway down the page):
if (scrollPercent < 1) {
//draw the length of SVG path according to the scroll
var draw = length * scrollPercent;
// Reverse the drawing (when scrolling upwards)
triangle.style.strokeDashoffset = length - draw;
} else {
var still = length;
}
The only quirk is that when the drawing is reversed (when you scroll up and then scroll back down), it seems to not complete all the way, like there's a bit of length missing. More to figure out, but the main function is there.
I guess it just took me a while to figure out the simple math. Hope this can help someone in the future.
I don't know if there will be a solution to this.
I have a canvas element which I wish to change the width of. That's easy enough, I know, but when the width changes, the lines in the drawing also go thinner/thicker when the width goes narrower/wider.
I could probably get around this by redrawing the image and playing around with scaling and lineWidth, etc, but I do not want to re-draw every time the width changes (I am changing the width using setInterval, so I don't think redrawing every 40-50 - or less - milliseconds is a reasonable/doable solution).
Can anyone think of a way to get around this?
A simple explanation to explain, I have:
ctx.beginPath()
ctx.strokeStyle="#000000";
ctx.lineWidth=1;
ctx.strokeRect(10, 10, 400, 400);
So when the width of canvas changes, the lineWidth becomes less than 1 pixel, to a point where it becomes "broken" and disappears.
In writing this question I am think more and more that the only solution would be to redraw the image but please let me know your thoughts.
ADDITION***
I am using this to change width, hope it makes sense:
repeater = setInterval(function() {
$(".action").css("width", originalWidth - borderRight - borderLeft + (mouseX - clickX));
}, 40);
I check when mouse is over right edge of canvas, then on "mousedown" originalWidth, borderRight, borderLeft, mouseX and clickX are set outside of repeater, so as mouse moves left and right the width increases/decreases. The interval is cleared on "mouseup", of course.
Thanks, Mike
Do not use CSS to rescale a canvas. When you use CSS, you scale the output of the canvas in the HTML layout, but don't change the internal resolution.
Change the width and height attribute of the canvas HTML node instead.
I have an <img> within a <div> which can be moved around using four directional buttons, for example:
The image is obviously larger than its container, hence the directional buttons to move it in different directions.
There is also a zoom control where you can zoom in and out. I set up the scaling method with ease, by just applying a zoom factor as a percentage to the base width and height:
scale: function(zoom)
{
image.width = baseWidth * zoom;
image.height = baseHeight * zoom;
}
// Zoom in 50%.
Scene.scale(1.5);
This is fine however the image scales from top-left, meaning that the image looks like it's getting sucked out towards the top left during a zoom in and spat back out when zooming out.
I'm trying to have the zoom effect apply from the centre of the container, like this:
But I'm finding it hard to get my head around the mathematics required to move the image after scaling applies to give this effect.
The closest I've gotten is to move the image based on the difference between the current zoom and the new zoom level, but it's still slightly off and gives a 'curved' effect when zooming.
Is there a common formula used to reposition an image so that it scales around a different origin (i.e. not top-left (0,0)).
This is what it looks like currently.
You have to take your original coordinates and calculate the center of your original image, that is x_center = x_orig + width_orig / 2; Then you can calculate the new x coordinate of your scaled image: x_new = x_center - width_new / 2. The same applies for y. Then move your scaled image to these new coordinates. If you do it after each time you scale the image, it will look as though it is scaled around its center.
I made a script that draws a series of lines on a canvas that makes it look like a sketch. There are two issues with the script. One, why is the y value twice as much as it should be? And two, why is the line several pixels wide and faded out?
I've tried it in both Google Chrome and Firefox and I get the same incorrect results. I realize that I can divide the y value by two to fix the first problem but that part of my question is why do I need to do that. I shouldn't have to.
I think you have two issues:
You need to be more careful in how you calculate the offset of where to draw. I have some code below that demonstrates how to handle this properly.
You aren't setting the width and height on the <canvas> element itself, which means it will scale your lines in funny ways depending how what you've set in your css.
An Example
I built a simple collaborative drawing app using <canvas> and socket.io that lets you draw to the screen like a pencil. You can check it out here:
http://xjamundx.no.de/
The source is also on github if that might help:
https://github.com/xjamundx/CollabPaintJS/ (main repo)
https://github.com/xjamundx/CollabPaintJS/blob/master/public/collabpaint.js (canvas drawing code)
In particular I do something like this to figure out where to draw things:
x = e.clientX + window.scrollX
y = e.clientY + window.scrollY
x -= $game.offsetLeft
y -= $game.offsetTop
Give a width and a height to your canvas; always !
http://jsfiddle.net/mz6hK/7/
fixed