四角拖拽-文本可伸缩
Posted tlsf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四角拖拽-文本可伸缩相关的知识,希望对你有一定的参考价值。
女朋友公司需求,要求做一个可以拖拽和伸缩的盒子,还挺急的,她暂时没什么头绪,交到我这了,┭┮﹏┭┮,写吧,熬了几天夜,可算是写出来了
首先去GitHub找拖拽放大相关的Demo,找到,哈哈。
为方便大家使用,我把源码奉上,取相同的命名即可。
css文件名 — Drag.css
@charset ‘utf-8‘;
#container {
width: 800px;
height: 500px;
margin: 50px auto;
border: 1px solid #ccc;
box-sizing: content-box;
position: relative;
}
#myDrag {
width: 60px;
height: 60px;
position: absolute;
top: 100px;
left: 100px;
box-shadow: 0 0px 10px rgba(33, 133, 208, 1);
}
#myDrag2{
width: 60px;
height: 60px;
position: absolute;
top: 200px;
left: 200px;
box-shadow: 0 0px 10px rgba(33, 133, 208, 1);
}
.point{
position: absolute;
width: 12px;
height: 12px;
z-index: 5;
border: 1px solid #d5ece8;
border-radius: 100%;
box-shadow: 0 0 5px #eee;
-moz-box-shadow: 0 0 5px #eee;
-webkit-box-shadow: 0 0 5px #eee;
background-color: #2185d0;
}
.drag-left {
left : -7px;
cursor : w-resize;
}
.drag-right {
right : -7px;
cursor : w-resize;
}
.drag-up {
top : -7px;
cursor : s-resize;
}
.drag-down {
bottom : -7px;
cursor : s-resize;
}
.drag-leftUp {
left : -7px;
top : -7px;
cursor : nw-resize
}
.drag-rightUp {
right : -7px;
top : -7px;
cursor : ne-resize
}
.drag-leftDown {
left : -7px;
bottom : -7px;
cursor : sw-resize
}
.drag-rightDown {
right : -7px;
bottom : -7px;
cursor : se-resize
}
[class^="xingquanDrag"].select:active{
cursor: move;
}
.hidden{
display: none;
}
.show{
display: inline;
}
js命名 — Drag.js
/**
* 此文主要是控制目标元素的拖拽以及缩放
*
* @author panjaignhong
* @since 2017-08-16
* @email [email protected]
*/
(function ($) {
$.fn.xingquanDrag = function (options) {
var data = {
fullScreen: false,
container: null,
target: null,
resize: true,
drag: true,
}
options = options ? options : {};
//data.fullScreen = options.fullScreen ? options.fullScreen : null;
data.container = options.container ? options.container : null;
data.target = this;
data.resize = options.resize == false ? options.resize : true;
data.drag = options.drag == false ? options.drag : true;
var xingquanDrag = $.xingquanDrag.newInstance();
xingquanDrag.init(data);
}
$.xingquanDrag = {
settings: {
data: null,
pointSize: 12, //圆点长宽为12px
maxSize: null,
min: { //缩放的最小宽高,真实宽高,没有缩放
width: 10,
height: 10
},
directions: { //各个方向对应的值
leftUp: ‘.drag-leftUp‘,
rightUp: ‘.drag-rightUp‘,
leftDown: ‘.drag-leftDown‘,
rightDown: ‘.drag-rightDown‘,
}
},
newInstance: function () {
return $.extend(true, {}, this);
},
init: function (data) {
this.initDataEvent(data);
this.addPointEvent();
this.handleResizeEvent();
this.handleTargetClick();
this.handelTargetCancel();
},
initDataEvent: function (data) {
this.settings.data = data;
$(this.settings.data.target).addClass("xingquanDrag");
if (this.settings.data.fullScreen) {
return;
}
$($(this.settings.data.target).parent())[0].oncontextmenu = function () {
return false;
};
$($(this.settings.data.target).parent()).css({
position: ‘relative‘
});
},
handleTargetClick: function () {
var drag = this;
$(this.settings.data.target).off("mousedown").on("mousedown", function (e) {
drag.preventBuddle(e);
drag.select(e);
drag.handleTargetMoveEvent(e);
drag.handleKeyDownEvent(e);
});
},
select: function (e) { //用户鼠标点击画布中元素即可选中(单选或多选)或取消选中当前元素
if (!e.ctrlKey) { //单选
this.singleSelect();
} else { //多选
this.multiSelect();
}
},
singleSelect: function () {
//单选时 先清空选中效果
this.hidden($(this.settings.data.target).parent());
var point = $(this.settings.data.target).find(".point");
$(this.settings.data.target).addClass("select");
this.show(this.settings.data.target);
},
multiSelect: function () {
var point = $(this.settings.data.target).find(".point");
if ($(this.settings.data.target).hasClass("select")) {
this.hidden($(this.settings.data.target));
$(this.settings.data.target).removeClass("select");
} else {
$(this.settings.data.target).addClass("select");
this.show(this.settings.data.target);
}
},
show: function (flag) {
$(flag).find(".point").addClass("show");
$(flag).find(".point").removeClass("hidden");
},
hidden: function (flag) {
$(flag).find(".point").addClass("hidden");
$(flag).find(".point").removeClass("show");
},
handelTargetCancel: function () {
var drag = this;
$(this.settings.data.target).parent().off("mousedown").on("mousedown", function () {
var point = $(this).find(".point");
$(this).find(".select").removeClass("select");
drag.hidden($(this));
});
$(this.settings.data.target).parent().off("touchstart").on("touchstart", function () {
var point = $(this).find(".point");
$(this).find(".select").removeClass("select");
drag.hidden($(this));
});
},
addPointEvent: function () {
$(this.settings.data.target).find(‘.point‘).remove(); //先清空之前设置的助托点,重新设置
var horizentalMiddle = ($(this.settings.data.target).width() - this.settings.pointSize) / 2;
var verticalMiddle = ($(this.settings.data.target).height() - this.settings.pointSize) / 2;
// 左上角
var rLeftUp = document.createElement(‘div‘);
$(rLeftUp).addClass(this.settings.directions.leftUp.substring(1) + ‘ point hidden‘);
$(this.settings.data.target).append($(rLeftUp));
// 右上角
var rRightUp = document.createElement(‘div‘);
$(rRightUp).addClass(this.settings.directions.rightUp.substring(1) + ‘ point hidden‘);
$(this.settings.data.target).append($(rRightUp));
// 左下角
var rLeftDown = document.createElement(‘div‘);
$(rLeftDown).addClass(this.settings.directions.leftDown.substring(1) + ‘ point hidden‘);
$(this.settings.data.target).append($(rLeftDown));
// 右下角
var rRightDown = document.createElement(‘div‘);
$(rRightDown).addClass(this.settings.directions.rightDown.substring(1) + ‘ point hidden‘);
$(this.settings.data.target).append($(rRightDown));
},
preventBuddle: function (e) { //阻止事件冒泡
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
},
handleTargetMoveEvent: function (e) {
if (!this.settings.data.drag) {
return;
}
var drag = this
var startXY = this.getXY(e);
$(document).off("mousemove").on("mousemove", function (e) { //拖动时移动
drag.preventBuddle(e);
drag.resetPosition(e, startXY);
return false;
});
$(document).off("mouseup").on("mouseup", function (e) {
drag.preventBuddle(e);
$(document).unbind(‘mousemove‘);
$(document).unbind(‘mouseup‘);
return false;
});
return false;
},
handleKeyDownEvent: function () {
var drag = this;
$(document).off("keydown").on("keydown", function (e) {
drag.preventBuddle(e);
var position = drag.getTargetPosition();
var maxSize = drag.getMaxSize();
//左
if (e.keyCode == 37) {
if (position.left > 0) {
$(drag.settings.data.target).css({
left: position.left - 1
});
}
}
//上
if (e.keyCode == 38) {
if (position.top > 0) {
$(drag.settings.data.target).css({
top: position.top - 1
});
}
e.preventDefault();
}
//右
if (e.keyCode == 39) {
if (position.width + position.left < maxSize.width) {
$(drag.settings.data.target).css({
left: position.left * 1 + 1
});
}
}
//下
if (e.keyCode == 40) {
if (position.height + position.top < maxSize.height) {
$(drag.settings.data.target).css({
top: position.top * 1 + 1
});
}
e.preventDefault();
}
});
},
getXY: function (e) {
width = $(e.target).parent().width();
height = $(e.target).parent().height();
return {
x: e.pageX != undefined ? e.pageX : e.originalEvent.targetTouches[0].pageX,
y: e.pageY != undefined ? e.pageY : e.originalEvent.targetTouches[0].pageY,
width: width,
height: height
};
},
resetPosition: function (e, startXY) {
var xy = this.getXY(e);
var distanceX = xy.x - startXY.x;
var distanceY = xy.y - startXY.y;
var left = $(this.settings.data.target)[0].offsetLeft + distanceX;
var top = $(this.settings.data.target)[0].offsetTop + distanceY;
if (!this.settings.data.fullScreen) {
var maxPosition = this.getMaxPosition();
if (left < 0) {
left = 0;
} else if (left > maxPosition.left) {
left = maxPosition.left;
}
if (top < 0) {
top = 0;
} else if (top > maxPosition.top) {
top = maxPosition.top
}
}
$(this.settings.data.target).css({
left: left,
top: top
});
//更新后将当前xy设置为startXY
$.extend(startXY, xy);
},
getMaxPosition: function () {
if (!this.settings.data.fullScreen) {
var left = $(this.settings.data.target).parent().width() - $(this.settings.data.target).width();
var top = $(this.settings.data.target).parent().height() - $(this.settings.data.target).height();
return {
left: left,
top: top
};
} else {
// TODO
}
},
handleResizeEvent: function () {
var drag = this;
$(this.settings.data.target).find(‘.point‘).off(‘mousedown‘).on(‘mousedown‘, function (e) {
var parentObj = $(e.target).parent();
var downRate = parentObj.width() / parentObj.height();
drag.preventBuddle(e);
var direction = $(this).attr(‘class‘).split(‘point‘, 1)[0].trim();
var startXY = drag.getXY(e);
$(document).off("mousemove").on("mousemove", function (e) {
drag.preventBuddle(e);
drag.handleResize(e, startXY, direction, downRate);
return false;
});
$(document).off("mouseup").on("mouseup", function (e) {
drag.preventBuddle(e);
//获取文件的宽高
var upRate = parentObj.width() / parentObj.height();
if (downRate > upRate) {
//以父盒子的宽为基准
parentObj.css("height", parentObj.width() / downRate);
} else {
//以父盒子的高为基准
parentObj.css("width", parentObj.height() * downRate);
}
$(document).unbind(‘mousemove‘);
$(document).unbind(‘mouseup‘);
return false;
});
return false;
});
},
handleResize: function (e, startXY, direction, downRate) {
if (!this.settings.data.resize) {
return;
}
var xy = this.getXY(e);
var directions = this.settings.directions;
switch (direction) {
case directions.leftUp.substring(1):
this.handleResizeLeftUp(startXY, xy, downRate);
break;
case directions.rightUp.substring(1):
this.handleResizeRightUp(startXY, xy, downRate);
break;
case directions.leftDown.substring(1):
this.handleResizeLeftDown(startXY, xy, downRate);
break;
case directions.rightDown.substring(1):
this.handleResizeRightDown(startXY, xy, downRate);
break;
default:
toastr.error(‘发生错误,方向未知!‘);
break;
}
$.extend(startXY, xy);
// 监听下圆角的移动
var resizeXB=XieBian($(".textDiv").css("width"),$(".textDiv").css("height"));
var resizeSize=(resizeXB/initXB)*initSize+"px";
$(".preTextarea").css("fontSize",resizeSize);
},
handleResizeLeftUp: function (startXY, xy, downRate) {
var position = this.getTargetPosition();
var maxSize = this.getMaxSize();
var distanceX = xy.x - startXY.x;
var distanceY = xy.y - startXY.y;
var xValue = distanceX;
var yValue = distanceY;
position.left += xValue;
position.top += yValue;
if (position.left > 0 && position.top > 0) {
position.width -= xValue;
if (position.width <= this.settings.min.width) {
position.left -= xValue; //前面加了 这里减去 保持不变
position.width += xValue;
}
if (position.top > 0) {
position.height -= yValue;
if (position.height <= this.settings.min.height) {
position.top -= yValue;
position.height += yValue;
}
}
} else {
position.left -= xValue;
position.top -= yValue;
}
if (downRate >= xy.width / xy.height) {
//以父盒子的宽为基准
position.height = position.width / downRate;
} else {
position.width = position.height * downRate;
//以父盒子的高为基准
}
if (position.top + position.height > maxSize.height) {
position.height = maxSize.height - position.top;
position.width = position.height * downRate;
}
if (position.left + position.width > maxSize.width) {
position.width = maxSize.width - position.left;
position.height = position.width / downRate;
}
this.handlePosition(position);
},
handleResizeRightUp: function (startXY, xy, downRate) {
var position = this.getTargetPosition();
var maxSize = this.getMaxSize();
var xValue = xy.x - startXY.x;
var yValue = xy.y - startXY.y;
position.width += xValue;
position.top += yValue;
if (position.top > 0) {
position.height -= yValue;
if (position.height < this.settings.min.height) {
position.top -= yValue;
position.height += yValue;
}
if (position.width < this.settings.min.width || position.left + position.width > maxSize.width) {
position.width -= xValue;
}
} else {
position.width -= xValue;
position.top -= yValue;
}
if (downRate >= xy.width / xy.height) {
//以父盒子的宽为基准
position.height = position.width / downRate;
} else {
position.width = position.height * downRate;
//以父盒子的高为基准
}
if (position.top + position.height > maxSize.height) {
position.height = maxSize.height - position.top;
position.width = position.height * downRate;
}
if (position.left + position.width > maxSize.width) {
position.width = maxSize.width - position.left;
position.height = position.width / downRate;
}
this.handlePosition(position);
},
handleResizeLeftDown: function (startXY, xy, downRate) {
var position = this.getTargetPosition();
var maxSize = this.getMaxSize();
var xValue = xy.x - startXY.x;
var yValue = xy.y - startXY.y;
position.height += yValue;
position.left += xValue;
if (position.left > 0) {
position.width -= xValue;
if (position.width < this.settings.min.width) {
position.left -= xValue;
position.width += xValue;
}
if (position.height < this.settings.min.height || position.top + position.height > maxSize.height) {
position.height -= yValue;
}
} else {
position.height -= yValue;
position.left -= xValue;
}
if (downRate >= xy.width / xy.height) {
//以父盒子的宽为基准
position.height = position.width / downRate;
} else {
position.width = position.height * downRate;
//以父盒子的高为基准
}
if (position.width + position.left > maxSize.width) {
position.width = maxSize.width - position.left;
position.height = position.width / downRate;
}
if (position.height + position.top > maxSize.height) {
position.height = maxSize.height - position.top;
position.width = position.height * downRate;
}
this.handlePosition(position);
},
handleResizeRightDown: function (startXY, xy, downRate) {
var position = this.getTargetPosition();
var maxSize = this.getMaxSize();
var xValue = xy.x - startXY.x;
var yValue = xy.y - startXY.y;
position.width += xValue;
position.height += yValue;
if (position.width + position.left > maxSize.width || position.width < this.settings.min.width) {
position.width -= xValue;
}
if (position.height + position.top > maxSize.height || position.height < this.settings.min.height) {
position.height -= yValue;
}
if (downRate >= xy.width / xy.height) {
//以父盒子的宽为基准
position.height = position.width / downRate;
} else {
//以父盒子的高为基准
position.width = position.height * downRate;
}
if (position.height + position.top > maxSize.height) {
position.height -= yValue;
position.width = position.height * downRate;
}
if (position.width + position.left > maxSize.width) {
position.width = maxSize.width - position.left;
position.height = position.width / downRate;
}
this.handlePosition(position);
},
getTargetPosition: function () { //获取控件位置大小
var left = $(this.settings.data.target)[0].offsetLeft;
var top = $(this.settings.data.target)[0].offsetTop;
var width = $(this.settings.data.target).width();
var height = $(this.settings.data.target).height();
return {
left: left,
top: top,
width: width,
height: height
}
},
handlePosition: function (position) {
//目标元素位置大小的改变
$(this.settings.data.target).css({
width: position.width,
height: position.height,
top: position.top,
left: position.left
});
//四个拖点的位置改变
//调整中间4个点的位置居中
var parentWidth = $(this.settings.data.target).width();
var parentHeight = $(this.settings.data.target).height();
var up = $(this.settings.data.target).find(this.settings.directions.up);
var down = $(this.settings.data.target).find(this.settings.directions.down);
var left = $(this.settings.data.target).find(this.settings.directions.left);
var right = $(this.settings.data.target).find(this.settings.directions.right);
var size = this.settings.pointSize;
$(up).css({
left: (parentWidth - size) / 2 + ‘px‘
});
$(down).css({
left: (parentWidth - size) / 2 + ‘px‘
});
$(left).css({
top: (parentHeight - size) / 2 + ‘px‘
});
$(right).css({
top: (parentHeight - size) / 2 + ‘px‘
});
},
getMaxSize: function () {
if (!this.settings.data.fullScreen) {
var height = $(this.settings.data.target).parent().height();
var width = $(this.settings.data.target).parent().width();
return {
height: height,
width: width
}
} else {
// TODO
}
}
}
}(jQuery))
html代码:
<!DOCTYPE html>
<html>
<head>
<title>移动</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./Drag.css" />
</head>
<body>
<div id="container" style="position: relative;">
</div>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="./Drag.js"></script>
<script type="text/javascript" src="./resize.js"></script>
<script type="text/javascript">
/**
* 使用说明
* 参数:
* fullScreen: 可移动区域是否全屏 false true --- 尚未实现,
* container: 可移动区域,默认为目标的上一层元素空间,
* drag: 可拖动 默认true,
* resize: 可改变大小 默认true,
*/
var textHtml =
‘<div class="textDiv" style="position:absolute;"><div class="preTextarea" maxlength="128" contentEditable style="white-space:pre;text-overflow: ellipsis;font-size:40px; display:inline; ">测试</div></div>‘;
$("#container").html(textHtml);
$(".textDiv").xingquanDrag();
$(".preTextarea").keyup(function () {
var inputWidth = $(this).css("width");
$(".textDiv").css("width", inputWidth);
});
// 求斜边的方法
function XieBian(widths, heights) {
// 获得初始宽高
let width = parseFloat(heights),
height = parseFloat(heights);
// 根据三角函数求斜边
let boxWidth = Math.pow(width, 2),
boxHeight = Math.pow(height, 2),
He = parseFloat(boxWidth) + parseFloat(boxHeight),
DUIJiao = Math.sqrt(He);
// 返回求得斜边
return Math.floor(DUIJiao)
};
// 获得初始文字大小;
var initSize=parseFloat($(".preTextarea").css("fontSize"));
// 获得初始斜边
var initXB=XieBian($(".textDiv").css("width"),$(".textDiv").css("height"));
</script>
</body>
</html>
原始代码没有盒子伸缩内容跟随放大,自己就修改了下源码,计算伸缩后字体的大小,原理如下:
(斜边求法就是数学里得三角求斜边)
初始斜边长度=开根号(初始盒子宽度平方+初始盒子高度平方)
变化后斜边长度=开根号(变化后盒子宽度平方+变化后盒子高度平方)
比值=变化后斜边长度/初始斜边长度
变化后字体大小=初始字体大小*比值
源码修改的代码在js代码中已标红。
效果图:
以上是关于四角拖拽-文本可伸缩的主要内容,如果未能解决你的问题,请参考以下文章