浏览代码

Stag popup - draggable and resizable

Vijayakrishnan 3 年之前
父节点
当前提交
9a96ccb2fd
共有 3 个文件被更改,包括 188 次插入2 次删除
  1. 1 1
      config/app.php
  2. 164 1
      js-dev/stag-popup.js
  3. 23 0
      public/css/style.css

+ 1 - 1
config/app.php

@@ -65,7 +65,7 @@ return [
 
     'hrm2_url' => env('HRM2_URL'),
 
-    'asset_version' => 91,
+    'asset_version' => 92,
 
     'temp_dir' => env('TEMP_DIR'),
 

+ 164 - 1
js-dev/stag-popup.js

@@ -116,7 +116,7 @@ function openDynamicStagPopup(_url, initer, title, updateParent, style = '', rep
             popup = $('.dynamic-popup[stag-popup-key="' + url + '"]');
             if(!popup.length) {
                 $('main.stag-content').append(
-                    '<div class="stag-popup ' + (style ? style : 'stag-popup-lg') + ' dynamic-popup mcp-theme-1" stag-popup-key="' + url + '">' +
+                    '<div class="stag-popup ' + (style ? style : 'stag-popup-lg') + ' dynamic-popup draggable resizable mcp-theme-1" stag-popup-key="' + url + '">' +
                     '<div class="stag-popup-content p-0">' +
                     '<h3 class="stag-popup-title mb-0 mt-3 mx-3 pb-0 border-bottom-0"><span></span>' +
                     '<a href="#" class="ml-auto text-secondary" onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>\n' +
@@ -296,6 +296,169 @@ function hasResponseError(_data) {
                 closeStagPopup();
                 return false;
             });
+
+        // draggable
+        let dragging = false, dragX, dragY;
+        $(document)
+            .off('mousedown.start-drag', '.stag-popup.dynamic-popup.draggable .stag-popup-title')
+            .on('mousedown.start-drag', '.stag-popup.dynamic-popup.draggable .stag-popup-title', function(_e) {
+                if(dragging && dragging.length) {
+                    dragging = false;
+                }
+                dragging = $(this).closest('.stag-popup-content');
+                dragX = _e.screenX;
+                dragY = _e.screenY;
+            });
+        $(document)
+            .off('mousemove.drag')
+            .on('mousemove.drag', function(_e) {
+                if(dragging && dragging.length) {
+                    let targetX = dragging.position().left + (_e.screenX - dragX),
+                        targetY = dragging.position().top + (_e.screenY - dragY);
+                    if(targetX >= 0) dragX = _e.screenX;
+                    if(targetY >= 0) dragY = _e.screenY;
+                    if(targetX < 0) targetX = 0;
+                    if(targetY < 0) targetY = 0;
+                    dragging[0].style.left = targetX + 'px';
+                    dragging[0].style.top = targetY + 'px';
+                    dragging[0].style.transform = 'none';
+                    return false;
+                }
+            });
+
+        // resizable
+        let resizeHighlighting = false, resizeDirection = false, resizeAnchor = false, resizing = false, resizeGutter = 8, resizeX, resizeY;
+        $(document)
+            .off('mousemove.highlight-resize', '.stag-popup.dynamic-popup.resizable .stag-popup-content')
+            .on('mousemove.highlight-resize', '.stag-popup.dynamic-popup.resizable .stag-popup-content', function(_e) {
+                if(dragging && dragging.length) return;
+                if(resizing && resizing.length) return;
+                let mouseX = _e.pageX - $(this).offset().left,
+                    mouseY = _e.pageY - $(this).offset().top;
+                if((mouseX >= 0 && mouseX <= resizeGutter) || (mouseX >= $(this).outerWidth() - resizeGutter && mouseX <= $(this).outerWidth())) {
+                    $(this).addClass('resizing-x');
+                    resizeHighlighting = $(this);
+                    resizeDirection = 'x';
+                    resizeAnchor = (mouseX >= 0 && mouseX <= resizeGutter) ? 'left' : 'right';
+                }
+                else if((mouseY >= 0 && mouseY <= resizeGutter) || (mouseY >= $(this).outerHeight() - resizeGutter && mouseY <= $(this).outerHeight())) {
+                    $(this).addClass('resizing-y');
+                    resizeHighlighting = $(this);
+                    resizeDirection = 'y';
+                    resizeAnchor = (mouseY >= 0 && mouseY <= resizeGutter) ? 'top' : 'bottom';
+                }
+                else {
+                    $(this).removeClass('resizing-x');
+                    $(this).removeClass('resizing-y');
+                    resizeHighlighting = false;
+                }
+            });
+        $(document)
+            .off('mousedown.start-resize', '.stag-popup.dynamic-popup.resizable .stag-popup-content')
+            .on('mousedown.start-resize', '.stag-popup.dynamic-popup.resizable .stag-popup-content', function(_e) {
+                if(resizeHighlighting && resizeHighlighting.length) {
+                    if(resizing && resizing.length) {
+                        resizing.removeClass('resizing-x resizing-y');
+                        resizing = false;
+                    }
+                    resizing = $(this);
+                    resizeX = _e.screenX;
+                    resizeY = _e.screenY;
+                }
+            });
+        $(document)
+            .off('mousemove.resize')
+            .on('mousemove.resize', function(_e) {
+                if(resizing && resizing.length) {
+
+                    console.log(resizeDirection);
+                    console.log(resizeAnchor);
+
+                    // x
+                    if(resizeDirection === 'x') {
+
+                        let deltaX = _e.screenX - resizeX;
+
+                        // anchor: left => update left and width of the popup
+                        if(resizeAnchor === 'left') {
+                            resizing[0].style.left = resizing.position().left + deltaX + 'px';
+                            resizing[0].style.width = resizing.outerWidth() - deltaX + 'px';
+                            resizing[0].style.transform = 'none';
+                        }
+
+                        // anchor: right => update width of the popup
+                        else if(resizeAnchor === 'right') {
+                            resizing[0].style.left = resizing.position().left + 'px'
+                            resizing[0].style.width = resizing.outerWidth() + deltaX + 'px';
+                            resizing[0].style.transform = 'none';
+                        }
+                    }
+
+                    // x
+                    if(resizeDirection === 'y') {
+
+                        let deltaY = _e.screenY - resizeY;
+
+                        // anchor: top => update top and height of the popup
+                        if(resizeAnchor === 'top') {
+                            resizing[0].style.top = resizing.position().top + deltaY + 'px';
+                            resizing[0].style.height = resizing.outerHeight() - deltaY + 'px';
+                        }
+
+                        // anchor: bottom => update height of the popup
+                        else if(resizeAnchor === 'bottom') {
+                            resizing[0].style.height = resizing.outerHeight() + deltaY + 'px';
+                        }
+                    }
+
+                    resizeX = _e.screenX;
+                    resizeY = _e.screenY;
+                    return false;
+                }
+            });
+        $(document)
+            .off('mouseleave.stop-resize', '.stag-popup.dynamic-popup.resizable .stag-popup-content')
+            .on('mouseleave.stop-resize', '.stag-popup.dynamic-popup.resizable .stag-popup-content', function(_e) {
+                if(resizing && resizing.length) return;
+                if(resizeHighlighting && resizeHighlighting.length) {
+                    resizeHighlighting.removeClass('resizing-x resizing-y');
+                    resizeHighlighting = false;
+                    return false;
+                }
+            });
+
+        // common
+        $(document)
+            .off('mouseleave.stop-drag-resize')
+            .on('mouseleave.stop-drag-resize', function() {
+                if(dragging && dragging.length) {
+                    dragging = false;
+                }
+                if(resizeHighlighting && resizeHighlighting.length) {
+                    resizeHighlighting.removeClass('resizing-x resizing-y');
+                    resizeHighlighting = false;
+                }
+                if(resizing && resizing.length) {
+                    resizing.removeClass('resizing-x resizing-y');
+                    resizing = false;
+                }
+            });
+        $(document)
+            .off('mouseup.stop-drag-resize')
+            .on('mouseup.stop-drag-resize', function() {
+                if(dragging && dragging.length) {
+                    dragging = false;
+                }
+                if(resizeHighlighting && resizeHighlighting.length) {
+                    resizeHighlighting.removeClass('resizing-x resizing-y');
+                    resizeHighlighting = false;
+                }
+                if(resizing && resizing.length) {
+                    resizing.removeClass('resizing-x resizing-y');
+                    resizing = false;
+                }
+            });
+
     }
     addMCInitializer('stag-popups', window.initStagPopupEvents);
 })();

+ 23 - 0
public/css/style.css

@@ -1325,6 +1325,29 @@ body .node input[type="number"] {
     border-top: 1px solid #e1e1e1;
 }
 
+/* draggable popup */
+.stag-popup.draggable .stag-popup-content {
+    position: absolute;
+    left: 50%;
+    transform: translate(-50%, 0);
+}
+.stag-popup.dynamic-popup.draggable .stag-popup-title {
+    cursor: move;
+}
+
+/* resizable popup */
+.stag-popup.resizable .stag-popup-content.resizing-x {
+    outline: 1px solid rgba(0, 128, 128, 0.3);
+    cursor: ew-resize;
+}
+.stag-popup.resizable .stag-popup-content.resizing-y {
+    outline: 1px solid rgba(0, 128, 128, 0.3);
+    cursor: ns-resize;
+}
+.stag-popup.resizable .stag-popup-content {
+    overflow: auto !important;
+}
+
 /* slide-in stag-popups */
 .stag-popup.stag-slide {
     display: block;