在纯js中移动(drag/pan)和缩放对象(图像或div)
Move (drag/pan) and zoom object (image or div) in pure js
我正在编写一个小脚本,使对象(div 或 img)可以在给定的框架内移动和缩放。
但是我遇到了一些我不太确定的问题,因为我是 javascript 初学者 - 所以解释为什么会出现这些问题将不胜感激。
问题:
- 调用函数
start_drag()
、while_drag()
和 stop_drag()
returns undefined
- 为什么?应该返回什么?
- 图像的拖动和移动无法正常工作 - 我没有单击鼠标按钮开始四处移动图像,而是必须单击一次然后开始移动。虽然我将
mousedown
事件绑定到图像。我做错了什么?
- 为什么移动部件在移动设备上不起作用(缩放有效!)?
请看我的fiddle:https://jsfiddle.net/pow4ngbw/15/
现在工作正常,主要是图像 css 但发现了几个错误(请参阅新的 img 属性),还添加了一些调整以使拖动更顺畅。
var img_ele = null,
x_cursor = 0,
y_cursor = 0,
x_img_ele = 0,
y_img_ele = 0;
function zoom(zoomincrement) {
img_ele = document.getElementById('drag-img');
var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
img_ele.style.width = (pre_width * zoomincrement) + 'px';
img_ele.style.height = (pre_height * zoomincrement) + 'px';
img_ele = null;
}
document.getElementById('zoomout').addEventListener('click', function() {
zoom(0.5);
});
document.getElementById('zoomin').addEventListener('click', function() {
zoom(1.5);
});
function start_drag() {
img_ele = this;
x_img_ele = window.event.clientX - document.getElementById('drag-img').offsetLeft;
y_img_ele = window.event.clientY - document.getElementById('drag-img').offsetTop;
}
function stop_drag() {
img_ele = null;
}
function while_drag() {
var x_cursor = window.event.clientX;
var y_cursor = window.event.clientY;
if (img_ele !== null) {
img_ele.style.left = (x_cursor - x_img_ele) + 'px';
img_ele.style.top = ( window.event.clientY - y_img_ele) + 'px';
console.log(img_ele.style.left+' - '+img_ele.style.top);
}
}
document.getElementById('drag-img').addEventListener('mousedown', start_drag);
document.getElementById('container').addEventListener('mousemove', while_drag);
document.getElementById('container').addEventListener('mouseup', stop_drag);
#drag-img {
cursor: move;
position: relative;
width: 500px;
height: 500px;
}
#container {
overflow: hidden;
background: red;
height: 500px;
width: 500px;
}
.button {
width: 200px;
height: 50px;
}
<div id="container">
<img ondragstart="return false" id="drag-img" src="http://www.patsoy.com/p/2015/09/geometric-patterns-f03phtdx.jpg" />
</div>
<input type="button" id="zoomout" class="button" value="Zoom out">
<input type="button" id="zoomin" class="button" value="Zoom in">
我已经获取了 Bug 的代码并添加了我需要并在评论中要求的功能。我已将其更新为:缩放或平移时始终将图像保持在容器内,并将实现封装在 zoomer 对象内以保持全局环境清洁。
<!DOCTYPE html>
<html>
<head>
<style>
#zoom-img {
cursor: move;
position: relative;
width: 500px;
height: 500px;
}
#zoom-container {
overflow: hidden;
background: red;
height: 500px;
width: 500px;
}
.button {
width: 100px;
height: 50px;
}
</style>
</head>
<body id="fullbody">
<div id="zoom-container">
<img ondragstart="return false" id="zoom-img" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Cordillera_de_los_Andes.jpg/1024px-Cordillera_de_los_Andes.jpg" />
</div>
<input type="button" id="zoomout" class="button" value="Zoom out">
<input type="button" id="zoomin" class="button" value="Zoom in">
</body>
</html>
<script>
//
// This file is derived from the javascript portion of the drag-zoom example
// at the web site:
//
//
var zoomer = (function () {
var img_ele = null,
x_cursor = 0,
y_cursor = 0,
x_img_ele = 0,
y_img_ele = 0,
orig_width = document.getElementById('zoom-img').getBoundingClientRect().width,
orig_height = document.getElementById('zoom-img').getBoundingClientRect().height,
current_top = 0,
current_left = 0,
zoom_factor = 1.0;
return {
zoom: function (zoomincrement) {
img_ele = document.getElementById('zoom-img');
zoom_factor = zoom_factor + zoomincrement;
if (zoom_factor <= 1.0)
{
zoom_factor = 1.0;
img_ele.style.top = '0px';
img_ele.style.left = '0px';
}
var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
console.log('prewidth='+img_ele.getBoundingClientRect().width+'; pre_height ='+img_ele.getBoundingClientRect().height);
// img_ele.style.width = (pre_width * zoomincrement) + 'px';
// img_ele.style.height = (pre_height * zoomincrement) + 'px';
var new_width = (orig_width * zoom_factor);
var new_heigth = (orig_height * zoom_factor);
console.log('postwidth='+img_ele.style.width+'; postheight ='+img_ele.style.height);
if (current_left < (orig_width - new_width))
{
current_left = (orig_width - new_width);
}
if (current_top < (orig_height - new_heigth))
{
current_top = (orig_height - new_heigth);
}
img_ele.style.left = current_left + 'px';
img_ele.style.top = current_top + 'px';
img_ele.style.width = new_width + 'px';
img_ele.style.height = new_heigth + 'px';
img_ele = null;
},
start_drag: function () {
if (zoom_factor <= 1.0)
{
return;
}
img_ele = this;
x_img_ele = window.event.clientX - document.getElementById('zoom-img').offsetLeft;
y_img_ele = window.event.clientY - document.getElementById('zoom-img').offsetTop;
console.log('img='+img_ele.toString()+'; x_img_ele='+x_img_ele+'; y_img_ele='+y_img_ele+';')
console.log('offLeft='+document.getElementById('zoom-img').offsetLeft+'; offTop='+document.getElementById('zoom-img').offsetTop)
},
stop_drag: function () {
if (img_ele !== null) {
if (zoom_factor <= 1.0)
{
img_ele.style.left = '0px';
img_ele.style.top = '0px';
}
console.log(img_ele.style.left+' - '+img_ele.style.top);
}
img_ele = null;
},
while_drag: function () {
if (img_ele !== null)
{
var x_cursor = window.event.clientX;
var y_cursor = window.event.clientY;
var new_left = (x_cursor - x_img_ele);
if (new_left > 0)
{
new_left = 0;
}
if (new_left < (orig_width - img_ele.width))
{
new_left = (orig_width - img_ele.width);
}
var new_top = ( y_cursor - y_img_ele);
if (new_top > 0)
{
new_top = 0;
}
if (new_top < (orig_height - img_ele.height))
{
new_top = (orig_height - img_ele.height);
}
current_left = new_left;
img_ele.style.left = new_left + 'px';
current_top = new_top;
img_ele.style.top = new_top + 'px';
//console.log(img_ele.style.left+' - '+img_ele.style.top);
}
}
};
} ());
document.getElementById('zoomout').addEventListener('click', function() {
zoomer.zoom(-0.25);
});
document.getElementById('zoomin').addEventListener('click', function() {
zoomer.zoom(0.25);
});
document.getElementById('zoom-img').addEventListener('mousedown', zoomer.start_drag);
document.getElementById('zoom-container').addEventListener('mousemove', zoomer.while_drag);
document.getElementById('zoom-container').addEventListener('mouseup', zoomer.stop_drag);
document.getElementById('zoom-container').addEventListener('mouseout', zoomer.stop_drag);
</script>
我正在编写一个小脚本,使对象(div 或 img)可以在给定的框架内移动和缩放。
但是我遇到了一些我不太确定的问题,因为我是 javascript 初学者 - 所以解释为什么会出现这些问题将不胜感激。
问题:
- 调用函数
start_drag()
、while_drag()
和stop_drag()
returnsundefined
- 为什么?应该返回什么? - 图像的拖动和移动无法正常工作 - 我没有单击鼠标按钮开始四处移动图像,而是必须单击一次然后开始移动。虽然我将
mousedown
事件绑定到图像。我做错了什么? - 为什么移动部件在移动设备上不起作用(缩放有效!)?
请看我的fiddle:https://jsfiddle.net/pow4ngbw/15/
现在工作正常,主要是图像 css 但发现了几个错误(请参阅新的 img 属性),还添加了一些调整以使拖动更顺畅。
var img_ele = null,
x_cursor = 0,
y_cursor = 0,
x_img_ele = 0,
y_img_ele = 0;
function zoom(zoomincrement) {
img_ele = document.getElementById('drag-img');
var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
img_ele.style.width = (pre_width * zoomincrement) + 'px';
img_ele.style.height = (pre_height * zoomincrement) + 'px';
img_ele = null;
}
document.getElementById('zoomout').addEventListener('click', function() {
zoom(0.5);
});
document.getElementById('zoomin').addEventListener('click', function() {
zoom(1.5);
});
function start_drag() {
img_ele = this;
x_img_ele = window.event.clientX - document.getElementById('drag-img').offsetLeft;
y_img_ele = window.event.clientY - document.getElementById('drag-img').offsetTop;
}
function stop_drag() {
img_ele = null;
}
function while_drag() {
var x_cursor = window.event.clientX;
var y_cursor = window.event.clientY;
if (img_ele !== null) {
img_ele.style.left = (x_cursor - x_img_ele) + 'px';
img_ele.style.top = ( window.event.clientY - y_img_ele) + 'px';
console.log(img_ele.style.left+' - '+img_ele.style.top);
}
}
document.getElementById('drag-img').addEventListener('mousedown', start_drag);
document.getElementById('container').addEventListener('mousemove', while_drag);
document.getElementById('container').addEventListener('mouseup', stop_drag);
#drag-img {
cursor: move;
position: relative;
width: 500px;
height: 500px;
}
#container {
overflow: hidden;
background: red;
height: 500px;
width: 500px;
}
.button {
width: 200px;
height: 50px;
}
<div id="container">
<img ondragstart="return false" id="drag-img" src="http://www.patsoy.com/p/2015/09/geometric-patterns-f03phtdx.jpg" />
</div>
<input type="button" id="zoomout" class="button" value="Zoom out">
<input type="button" id="zoomin" class="button" value="Zoom in">
我已经获取了 Bug 的代码并添加了我需要并在评论中要求的功能。我已将其更新为:缩放或平移时始终将图像保持在容器内,并将实现封装在 zoomer 对象内以保持全局环境清洁。
<!DOCTYPE html>
<html>
<head>
<style>
#zoom-img {
cursor: move;
position: relative;
width: 500px;
height: 500px;
}
#zoom-container {
overflow: hidden;
background: red;
height: 500px;
width: 500px;
}
.button {
width: 100px;
height: 50px;
}
</style>
</head>
<body id="fullbody">
<div id="zoom-container">
<img ondragstart="return false" id="zoom-img" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Cordillera_de_los_Andes.jpg/1024px-Cordillera_de_los_Andes.jpg" />
</div>
<input type="button" id="zoomout" class="button" value="Zoom out">
<input type="button" id="zoomin" class="button" value="Zoom in">
</body>
</html>
<script>
//
// This file is derived from the javascript portion of the drag-zoom example
// at the web site:
//
//
var zoomer = (function () {
var img_ele = null,
x_cursor = 0,
y_cursor = 0,
x_img_ele = 0,
y_img_ele = 0,
orig_width = document.getElementById('zoom-img').getBoundingClientRect().width,
orig_height = document.getElementById('zoom-img').getBoundingClientRect().height,
current_top = 0,
current_left = 0,
zoom_factor = 1.0;
return {
zoom: function (zoomincrement) {
img_ele = document.getElementById('zoom-img');
zoom_factor = zoom_factor + zoomincrement;
if (zoom_factor <= 1.0)
{
zoom_factor = 1.0;
img_ele.style.top = '0px';
img_ele.style.left = '0px';
}
var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
console.log('prewidth='+img_ele.getBoundingClientRect().width+'; pre_height ='+img_ele.getBoundingClientRect().height);
// img_ele.style.width = (pre_width * zoomincrement) + 'px';
// img_ele.style.height = (pre_height * zoomincrement) + 'px';
var new_width = (orig_width * zoom_factor);
var new_heigth = (orig_height * zoom_factor);
console.log('postwidth='+img_ele.style.width+'; postheight ='+img_ele.style.height);
if (current_left < (orig_width - new_width))
{
current_left = (orig_width - new_width);
}
if (current_top < (orig_height - new_heigth))
{
current_top = (orig_height - new_heigth);
}
img_ele.style.left = current_left + 'px';
img_ele.style.top = current_top + 'px';
img_ele.style.width = new_width + 'px';
img_ele.style.height = new_heigth + 'px';
img_ele = null;
},
start_drag: function () {
if (zoom_factor <= 1.0)
{
return;
}
img_ele = this;
x_img_ele = window.event.clientX - document.getElementById('zoom-img').offsetLeft;
y_img_ele = window.event.clientY - document.getElementById('zoom-img').offsetTop;
console.log('img='+img_ele.toString()+'; x_img_ele='+x_img_ele+'; y_img_ele='+y_img_ele+';')
console.log('offLeft='+document.getElementById('zoom-img').offsetLeft+'; offTop='+document.getElementById('zoom-img').offsetTop)
},
stop_drag: function () {
if (img_ele !== null) {
if (zoom_factor <= 1.0)
{
img_ele.style.left = '0px';
img_ele.style.top = '0px';
}
console.log(img_ele.style.left+' - '+img_ele.style.top);
}
img_ele = null;
},
while_drag: function () {
if (img_ele !== null)
{
var x_cursor = window.event.clientX;
var y_cursor = window.event.clientY;
var new_left = (x_cursor - x_img_ele);
if (new_left > 0)
{
new_left = 0;
}
if (new_left < (orig_width - img_ele.width))
{
new_left = (orig_width - img_ele.width);
}
var new_top = ( y_cursor - y_img_ele);
if (new_top > 0)
{
new_top = 0;
}
if (new_top < (orig_height - img_ele.height))
{
new_top = (orig_height - img_ele.height);
}
current_left = new_left;
img_ele.style.left = new_left + 'px';
current_top = new_top;
img_ele.style.top = new_top + 'px';
//console.log(img_ele.style.left+' - '+img_ele.style.top);
}
}
};
} ());
document.getElementById('zoomout').addEventListener('click', function() {
zoomer.zoom(-0.25);
});
document.getElementById('zoomin').addEventListener('click', function() {
zoomer.zoom(0.25);
});
document.getElementById('zoom-img').addEventListener('mousedown', zoomer.start_drag);
document.getElementById('zoom-container').addEventListener('mousemove', zoomer.while_drag);
document.getElementById('zoom-container').addEventListener('mouseup', zoomer.stop_drag);
document.getElementById('zoom-container').addEventListener('mouseout', zoomer.stop_drag);
</script>