成果展示:
codepen链接:https://codepen.io/ashipiling/pen/wvJyaza 该网站实现了demo,可进行拖拽尝试和代码修改。
图1 画板自由拖拽示例。
拟解决问题:
a) model builder应提供多选元素的功能,第一种方案是按住shift在选择物体,第二种则是绘制选框。第二种更加简便和直白;
b) 如果没有选中元素,则应删除选框;
c) 选中元素后,选框应紧紧包围所有被选中的元素,允许有间隙;
d) 如果对选中物体没有进行操作,则删除选框(此文章不涉及该操作)。
实现思路:
a) 画板绑定自定义onmousedown move和up函数(替换之前绑定的拖拽画板函数);
b) 在绘制之前,画板中的元素位置应保存下来。例如用全局变量dict保存元素四个角位置信息;
c) onmousedown,与画板绑定;
判断e.currentTarget的className和id是否是想要被移动的画板;
记录鼠标点击下的位置old_xy;
创建选框div 赋予classname 虚线边框,背景透明。画板挂载该div。
记录全局变量为绘制选框;
d) onmousemove,鼠标在绑定的元素内移动时高频触发;
判断当前动作是否为绘制选框;,如果是则进行下一步;
获取鼠标当前的位置,与old_xy一起计算选框div的宽高和left top信息;
更新选框div的csstext达到实时绘制选框的效果。
e) onmouseup,鼠标在绑定的元素内释放时触发一次。
计算选框内部是否含有元素,如果没有则删除选框div。如果有则修正选框位置,并高亮元素(该文章不涉及该操作)。
清理全局变量等。
实现细节:**
javascript代码
var gselectbox_down_x = 0; //mousedown时候的坐标。
var g_selectbox_down_y = 0; //mousedown时候的坐标。
var g_current_selectbox_id = “”; //当前选框的id,mousedown的时候确定。
var g_selectbox_padding = 10; //选中物体后,选框距离元素外围的距离。
var g_selectbox_down_flag = “up”; //是否开始选框的flag,防止鼠标自由移动时频繁触发函数。
var g_component_corner_position_dict = {“test_div”: {“left_x”: 300, “left_y”: 100, “right_x”: 450, “right_y”: 250,}, } //实际上是根据绘制元素时生成的,但这里为了演示,直接给定值。_
function selectboxmouse_down(e) {
var draw_canvas = document.getElementById(“draw_canvas”);
g_selectbox_down_x = e.pageX;
g_selectbox_down_y = e.pageY;
var div = document.createElement(“div”); //新建选框div
div.id = “selectbox“ + current(); //current函数返回当前时间戳,避免多次选框id一致
gcurrent_selectbox_id = div.id; //全局变量保存id,方便move和up函数使用
div.className = “selectbox”; //虚线外框
draw_canvas.append(div);
g_selectbox_down_flag = “down”; //开始绘制
}
//box mousemove函数, 更新box位置
function selectbox_mouse_move(e) {
if (g_selectbox_down_flag === “down”) { //只有flag为down的时候执行下列函数
var relative_x = e.pageX;
var relative_y = e.pageY;
var div = document.getElementById(g_current_selectbox_id);
var res_dict = calc_selectbox_whlt(relative_x, relative_y); //根据保存的xy和当前xy计算框的长宽和left top值
var csstext = combine_csstext(res_dict); //将计算出来的数值转换为csstext格式
div.style.cssText = csstext; //csstext赋值
}
}
//box mouseup函数, 修正位置,重绘box
function selectbox_mouse_up(e) {
var div = document.getElementById(g_current_selectbox_id);
var relative_x = e.pageX;
var relative_y = e.pageY;
var res_dict = calc_selectbox_whlt(relative_x, relative_y); //鼠标放开时最后计算一次宽高和left top
var selected_info = calc_which_box_selected(res_dict); //将选框位置信息和元素的位置信息进行比较,判断是否有元素在选框内部_
if (selected_info["id"].length === 0) { _//如果没有选中元素则删除选框_<br /> removeElement(div);<br /> } else {<br /> modify_selectbox_postion(selected_info["position"]); _//如果有选中元素则进行选框的位置的微调,变成紧紧围绕元素的选框_<br /> }<br /> g_selectbox_down_x = 0; _//清除全局变量_<br /> g_selectbox_down_y = 0;<br /> g_selectbox_down_flag = "up";<br />}
