菜单自适应示意图如下:
对象A可以拖动,缩放。菜单跟随对象A拖动,位置优先级为下面、上面、右边、左边、中间。
其实菜单放在上下左右中,都是它的left和top在变,我们只要依次计算菜单在下/上/右/左/中时的left和top,以及在这个left和top下,菜单的左\右\上\下边界有没有超出屏幕即可。
这段代码依赖于具体环境,是实际工程中拷下来的一段代码:
export default class ToolsBar{ /** * 初始化 */ init(){ this.width = em2px(13.75); //一级菜单宽度 this.height = em2px(2.75); //一级菜菜单高度 this.offsetLeft = em2px(10.083335); //左边超出宽度 this.offsetRight = em2px(1.833335); //右边超出宽度 this.offsetHeight = em2px(5.166665); //二级菜单的高度 } /** * 设置位置 * @param rect 立体图形的平面矩形框 {left, top, width, height} */ adjustPosition(rect){ let maxWidth = $(document).width(); let maxHeight = $(document).height(); //left ,top 都是指一级菜单的left和top let left = rect.left + (rect.width-this.width)/2; let top = rect.top + rect.height; left = left < this.offsetLeft ? this.offsetLeft:left; left = (left + this.width + this.offsetRight ) > maxWidth ? maxWidth - this.width - this.offsetRight:left; //下面放不下,放上面 let bottomCanPlace = (top + this.height + this.offsetHeight ) < maxHeight ; top = bottomCanPlace ? top : rect.top - this.height; // 上面放不了,放右边 let topCanPlace = bottomCanPlace || ( top > this.offsetHeight ); top = topCanPlace ? top : rect.top + rect.height/2; left = topCanPlace ? left : rect.left + rect.width + this.offsetLeft; //右边放不了,放左边 let rightCanPlace = topCanPlace || ( left + this.width + this.offsetRight < maxWidth ); left = rightCanPlace ? left : rect.left - this.offsetRight - this.width; //左边放不了,放中间 let leftCanPlace = rightCanPlace || ( left - this.offsetLeft > 0 ); left = leftCanPlace ? left : maxWidth/2; top = leftCanPlace ? top : maxHeight/2; this.view.css({left:left,top:top}); //在顶部时,二级菜单向上展开 if( !bottomCanPlace && topCanPlace ){ this.subItemList.addClass("subItemUp"); }else{ this.subItemList.removeClass("subItemUp"); } } }