By bining some CSS and Jquery UI / draggable I have created the ability to pan an image and with a little extra JS you can now zoom the image.
The problem I am having is that, if you zoom in the image's top left corner is fixed, as you would expect. What I would like is for the image to stay central (based on the current pan) so that the middle of the image stays in the middle of the container whilst getting larger.
I have written some code for this but doesn't work, I expect my maths is wrong. Could anyone help?
I want it to work like this does. When you scroll into an image it keeps the image centered based on the current pan rather than zooming out from the corner.
HTML:
<div id="creator_container" style="position: relative; width: 300px; height: 400px; overflow: hidden;">
<img src="/images/test.gif" class="user_image" width="300" style="cursor: move; position: absolute; left: 0; top: 0;">
</div>
Javascript:
$("#_popup_creator .user_image").bind('mousewheel', function(event, delta) {
zoomPercentage += delta;
$(this).css('width',zoomPercentage+'%');
$(this).css('height',zoomPercentage+'%');
var widthOffset = (($(this).width() - $(this).parent().width()) / 2);
$(this).css('left', $(this).position().left - widthOffset);
});
By bining some CSS and Jquery UI / draggable I have created the ability to pan an image and with a little extra JS you can now zoom the image.
The problem I am having is that, if you zoom in the image's top left corner is fixed, as you would expect. What I would like is for the image to stay central (based on the current pan) so that the middle of the image stays in the middle of the container whilst getting larger.
I have written some code for this but doesn't work, I expect my maths is wrong. Could anyone help?
I want it to work like this does. When you scroll into an image it keeps the image centered based on the current pan rather than zooming out from the corner.
HTML:
<div id="creator_container" style="position: relative; width: 300px; height: 400px; overflow: hidden;">
<img src="/images/test.gif" class="user_image" width="300" style="cursor: move; position: absolute; left: 0; top: 0;">
</div>
Javascript:
$("#_popup_creator .user_image").bind('mousewheel', function(event, delta) {
zoomPercentage += delta;
$(this).css('width',zoomPercentage+'%');
$(this).css('height',zoomPercentage+'%');
var widthOffset = (($(this).width() - $(this).parent().width()) / 2);
$(this).css('left', $(this).position().left - widthOffset);
});
Share
Improve this question
edited Jun 7, 2011 at 19:23
Chris
asked Jun 7, 2011 at 18:18
ChrisChris
27.4k49 gold badges206 silver badges357 bronze badges
3
- Please share your HTML as well – Niklas Commented Jun 7, 2011 at 18:26
- jsfiddle/niklasvh/SxLSY its not doing anything? – Niklas Commented Jun 7, 2011 at 18:37
- could you share how you did the panning ? does it pan in all directions ? – Rami Sarieddine Commented Jan 23, 2013 at 20:40
1 Answer
Reset to default 9Long story short, you need to make a transform matrix to scale by the same amount as the image and then transform the image's position using that matrix. If that explanation is plete greek to you, look up "image transforms" and "matrix math".
The beginning of this page is a pretty good resource to start with even though it's a different programming language: http://livedocs.adobe./flash/9.0/ActionScriptLangRefV3/flash/geom/Matrix.html
Anyway, I've implemented those methods in some projects of my own. Here's the zoom in function from something I wrote that functions the way you want:
function zoomIn(event) {
var prevS = scale;
scale += .1;
$(map).css({width: (baseSizeHor * scale) + "px", height: (baseSizeVer * scale) + "px"});
//scale from middle of screen
var point = new Vector.create([posX - $(viewer).width() / 2, posY - $(viewer).height() / 2, 1]);
var mat = Matrix.I(3);
mat = scaleMatrix(mat, scale / prevS, scale / prevS);
point = transformPoint(mat, point);
//http://stackoverflow./questions/1248081/get-the-browser-viewport-dimensions-with-javascript
posX = point.e(1) + $(viewer).width() / 2;
posY = point.e(2) + $(viewer).height() / 2;
$(map).css({left: posX, top: posY});
return false;//prevent drag image out of browser
}
Note the mands "new Vector.create()" and "Matrix.I(3)". Those e from the JavaScript vector/matrix math library http://sylvester.jcoglan./
Then note "transformPoint()". That's one of the functions from that ActionScript link (plus hints on http://wxs.ca/js3d/) that I implemented using sylvester.js
For the full set of functions I wrote:
function translateMatrix(mat, dx, dy) {
var m = Matrix.create([
[1,0,dx],
[0,1,dy],
[0,0,1]
]);
return m.multiply(mat);
}
function rotateMatrix(mat, rad) {
var c = Math.cos(rad);
var s = Math.sin(rad);
var m = Matrix.create([
[c,-s,0],
[s,c,0],
[0,0,1]
]);
return m.multiply(mat);
}
function scaleMatrix(mat, sx, sy) {
var m = Matrix.create([
[sx,0,0],
[0,sy,0],
[0,0,1]
]);
return m.multiply(mat);
}
function transformPoint(mat, vec) {
return mat.multiply(vec);
}