Chr*_*ian 9 javascript math jquery scaling offset
这看起来应该很简单,但由于某种原因,我不能完全围绕它.我在"viewport"div中有一个图像,其中overflow属性设置为hidden.
我已经使用jQuery UI实现了简单的缩放和平移,但是我无法使缩放看起来来自视口的中心.我在Photoshop上做了一个小小的截屏视频我想要重现的效果:http://dl.dropbox.com/u/107346/share/reference-point-zoom.mov
在PS中,您可以调整缩放参考点,对象将从该点开始缩放.显然这对HTML/CSS/JS来说是不可能的,所以我试图找到合适的左边和顶部CSS值来模仿效果.
这是有问题的代码,删除了一些不必要的位:
HTML
<div id="viewport">
<img id="map" src="http://dl.dropbox.com/u/107346/share/fake-map.png" alt="" />
</div>
<div id="zoom-control"></div>
Run Code Online (Sandbox Code Playgroud)
JavaScript的
$('#zoom-control').slider({
min: 300,
max: 1020,
value: 300,
step: 24,
slide: function(event, ui) {
var old_width = $('#map').width();
var new_width = ui.value;
var width_change = new_width - old_width;
$('#map').css({
width: new_width,
// this is where I'm stuck...
// dividing by 2 makes the map zoom
// from the center, but if I've panned
// the map to a different location I'd
// like that reference point to change.
// So instead of zooming relative to
// the map image center point, it would
// appear to zoom relative to the center
// of the viewport.
left: "-=" + (width_change / 2),
top: "-=" + (width_change / 2)
});
}
});
Run Code Online (Sandbox Code Playgroud)
这是关于JSFiddle的项目:http://jsfiddle.net/christiannaths/W4seR/
这是工作解决方案.我将在下一次编辑中解释逻辑.
功能逻辑:
摘要:相对而言,请记住图像的中心位置.
宽度和高度的计算是类似的,我只会解释height计算
.详细解释只是函数逻辑的一个例子.可以在答案的底部找到具有不同变量名称的真实代码.
计算的中心(X,Y) #map,相对于#viewport.这可以通过使用来完成offset(),height()和width()方法.
// Absolute difference between the top border of #map and #viewport
var differenceY = viewport.offset().top - map.offset().top;
// We want to get the center position, so add it.
var centerPosition = differenceY + viewport.height() * 0.5;
// Don't forget about the border (3px per CSS)
centerPosition += 3;
// Calculate the relative center position of #map
var relativeCenterY = centerPosition / map.height();
// RESULT: A relative offset. When initialized, the center of #map is at
// the center of #viewport, so 50% (= 0.5)
// Same method for relativeCenterX
Run Code Online (Sandbox Code Playgroud)计算新的顶部和左侧偏移量:
// Calculate the effect of zooming (example: zoom 1->2 = 2)
var relativeChange = new_width / old_width;
// Calculate the new height
var new_height = relativeChange * old_height;
// Calculate the `top` and `left` CSS properties.
// These must be negative if the upperleft corner is outside he viewport
// Add 50% of the #viewport's height to correctly position #map
// (otherwise, the center will be at the upperleft corner)
var newTopCss = -relativeCenterY * new_height + 0.5 * viewport.height();
Run Code Online (Sandbox Code Playgroud)更改CSS属性
map.css("top", newTopCss);
Run Code Online (Sandbox Code Playgroud)演示:http://jsfiddle.net/W4seR/12/
var map = $('#map');
var viewport = $('#viewport');
// Cache the size of the viewport (300x300)
var viewport_size = {
x: viewport.width(),
y: viewport.height()
};
map.draggable();
$('#zoom-control').slider({
min: 300,
max: 1020,
value: 300,
step: 24,
create: function() {
map.css({
'width': 300,
'left': 0,
'top': 0
});
},
slide: function(event, ui) {
var old_width = map.width();
var old_height = map.height();
var viewport_offset = viewport.offset();
var offset = map.offset();
offset = {
top: viewport_offset.top - offset.top + .5*viewport_size.y +3,
left: viewport_offset.left - offset.left + .5*viewport_size.x +3
};
// Relative offsets, relative to the center!
offset.top = offset.top / old_height;
offset.left = offset.left / old_width;
var new_width = ui.value;
var relative = new_width / old_width;
var new_height = relative * old_height;
offset = {
top: -offset.top * new_height + .5*viewport_size.y,
left: -offset.left * new_width + .5*viewport_size.x
};
var css_properties = {
width: new_width,
left: offset.left,
top: offset.top
};
map.css(css_properties);
trace((map.position().left));
}
});
Run Code Online (Sandbox Code Playgroud)
我一直依赖陌生人的善意。相关变更:
// Calculate the offset as a percentage, accounting for the height of the window
var x_offset = ((map.position().left-150))/(old_width/2);
var y_offset = ((map.position().top-150))/(old_width/2);
var css_properties = {
width: new_width,
// Set the offset based on the existing percentage rather than 1/2
// then readjust for the height of the window
left: (new_width * x_offset /2 ) + 150 + "px",
top: (new_width * y_offset /2 ) + 150 + "px"
};
Run Code Online (Sandbox Code Playgroud)
如有必要,将硬编码替换150为视口实例化时设置的变量。