Popup layer add drag to resize function
This commit is contained in:
parent
cc127696c5
commit
1f4c6feafa
@ -46,11 +46,21 @@ div.focus.popup-layer {
|
|||||||
div.popup-layer {
|
div.popup-layer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
overflow: hidden;
|
|
||||||
transition: none;
|
transition: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: 0.8px solid transparent;
|
border: 0.8px solid transparent;
|
||||||
|
|
||||||
|
div.popup-layer-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.popup-layer-root-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
div.popup-layer-header {
|
div.popup-layer-header {
|
||||||
min-height: $header-height;
|
min-height: $header-height;
|
||||||
max-height: $header-height;
|
max-height: $header-height;
|
||||||
@ -68,7 +78,7 @@ div.popup-layer {
|
|||||||
span {
|
span {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: bottom;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -92,6 +102,44 @@ div.popup-layer {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.drag-line-root.drag-line-y {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.drag-line-root {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
div.drag-line {
|
||||||
|
transition: all 300ms ease-in-out;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.render-drag-block-root {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
div.render-drag-block {
|
||||||
|
min-width: 5px;
|
||||||
|
min-height: 5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.drag-line:hover {
|
||||||
|
background-color: $lt-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.drag-line.hover {
|
||||||
|
background-color: $lt-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.popup-layer.dark {
|
div.popup-layer.dark {
|
||||||
|
@ -2,7 +2,7 @@ import { Component, ReactNode } from "react";
|
|||||||
import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status";
|
import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status";
|
||||||
import { IMixinSettingProps, useSettingWithEvent } from "@Context/Setting";
|
import { IMixinSettingProps, useSettingWithEvent } from "@Context/Setting";
|
||||||
import { BackgroundLevel, FontLevel, getClassList, Theme } from "@Component/Theme/Theme";
|
import { BackgroundLevel, FontLevel, getClassList, Theme } from "@Component/Theme/Theme";
|
||||||
import { Popup as PopupModel } from "@Context/Popups";
|
import { Popup as PopupModel, ResizeDragDirection } from "@Context/Popups";
|
||||||
import { Icon } from "@fluentui/react";
|
import { Icon } from "@fluentui/react";
|
||||||
import "./Popup.scss";
|
import "./Popup.scss";
|
||||||
|
|
||||||
@ -79,9 +79,6 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro
|
|||||||
popup.lastMouseLeft = e.clientX;
|
popup.lastMouseLeft = e.clientX;
|
||||||
popup.lastMouseTop = e.clientY;
|
popup.lastMouseTop = e.clientY;
|
||||||
}}
|
}}
|
||||||
onMouseUp={() => {
|
|
||||||
popup.isOnMouseDown = false;
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{popup.onRenderHeader()}
|
{popup.onRenderHeader()}
|
||||||
</div>
|
</div>
|
||||||
@ -108,6 +105,129 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private renderDragBlock(dir: ResizeDragDirection, popup: PopupModel) {
|
||||||
|
return <div className="render-drag-block-root">
|
||||||
|
<div
|
||||||
|
draggable={false}
|
||||||
|
style={{
|
||||||
|
cursor: this.mapDirToCursor.get(dir),
|
||||||
|
zIndex: popup.zIndex() + 2
|
||||||
|
}}
|
||||||
|
className="render-drag-block"
|
||||||
|
onMouseDown={(e) => {
|
||||||
|
popup.lastMouseLeft = e.clientX;
|
||||||
|
popup.lastMouseTop = e.clientY;
|
||||||
|
popup.resizeDragDirection = dir;
|
||||||
|
popup.isResizeMouseDown = true;
|
||||||
|
}}
|
||||||
|
onMouseEnter={() => {
|
||||||
|
popup.resizeHoverDirection = dir;
|
||||||
|
this.forceUpdate();
|
||||||
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
popup.resizeHoverDirection = undefined;
|
||||||
|
this.forceUpdate();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapDirToCursor = new Map<ResizeDragDirection, string>([
|
||||||
|
[ResizeDragDirection.rightTop, "sw-resize"],
|
||||||
|
[ResizeDragDirection.rightBottom, "nw-resize"],
|
||||||
|
[ResizeDragDirection.leftBottom, "sw-resize"],
|
||||||
|
[ResizeDragDirection.LeftTop, "nw-resize"]
|
||||||
|
]);
|
||||||
|
|
||||||
|
private renderDragLine(dir: ResizeDragDirection, popup: PopupModel) {
|
||||||
|
let xy: boolean = false;
|
||||||
|
const dragLineCList: string[] = ["drag-line"];
|
||||||
|
|
||||||
|
if (dir === ResizeDragDirection.top || dir === ResizeDragDirection.bottom) {
|
||||||
|
xy = false;
|
||||||
|
}
|
||||||
|
if (dir === ResizeDragDirection.left || dir === ResizeDragDirection.right) {
|
||||||
|
xy = true;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
dir === ResizeDragDirection.top &&
|
||||||
|
(
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.LeftTop ||
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.rightTop
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
dir === ResizeDragDirection.bottom &&
|
||||||
|
(
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.leftBottom ||
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.rightBottom
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
dir === ResizeDragDirection.right &&
|
||||||
|
(
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.rightTop ||
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.rightBottom
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
dir === ResizeDragDirection.left &&
|
||||||
|
(
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.leftBottom ||
|
||||||
|
popup.resizeHoverDirection === ResizeDragDirection.LeftTop
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
dragLineCList.push("hover")
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div
|
||||||
|
className={"drag-line-root" + (xy ? " drag-line-y" : "")}
|
||||||
|
style={{
|
||||||
|
width: xy ? "0" : "100%",
|
||||||
|
height: xy ? "100%" : "0",
|
||||||
|
zIndex: popup.zIndex() + 1
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
xy && dir === ResizeDragDirection.left ? this.renderDragBlock(
|
||||||
|
ResizeDragDirection.LeftTop, popup
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
xy && dir === ResizeDragDirection.right ? this.renderDragBlock(
|
||||||
|
ResizeDragDirection.rightTop, popup
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!xy && dir === ResizeDragDirection.bottom ? this.renderDragBlock(
|
||||||
|
ResizeDragDirection.leftBottom, popup
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
<div
|
||||||
|
draggable={false}
|
||||||
|
className={dragLineCList.join(" ")}
|
||||||
|
style={{
|
||||||
|
cursor: xy ? "e-resize" : "n-resize",
|
||||||
|
minWidth: xy ? "4px" : "calc( 100% + 2px )",
|
||||||
|
minHeight: xy ? "calc( 100% + 2px )" : "4px"
|
||||||
|
}}
|
||||||
|
onMouseDown={(e) => {
|
||||||
|
popup.lastMouseLeft = e.clientX;
|
||||||
|
popup.lastMouseTop = e.clientY;
|
||||||
|
popup.resizeDragDirection = dir;
|
||||||
|
popup.isResizeMouseDown = true;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
!xy && dir === ResizeDragDirection.bottom ? this.renderDragBlock(
|
||||||
|
ResizeDragDirection.rightBottom, popup
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
private renderLayer(popup: PopupModel) {
|
private renderLayer(popup: PopupModel) {
|
||||||
const pageWidth = document.documentElement.clientWidth;
|
const pageWidth = document.documentElement.clientWidth;
|
||||||
const pageHeight = document.documentElement.clientHeight;
|
const pageHeight = document.documentElement.clientHeight;
|
||||||
@ -132,8 +252,16 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro
|
|||||||
backgroundLevel: BackgroundLevel.Level4,
|
backgroundLevel: BackgroundLevel.Level4,
|
||||||
}, this.props.setting).join(" ")}
|
}, this.props.setting).join(" ")}
|
||||||
>
|
>
|
||||||
{this.renderHeader(popup)}
|
{this.renderDragLine(ResizeDragDirection.top, popup)}
|
||||||
{this.renderContent(popup)}
|
<div className="popup-layer-container">
|
||||||
|
{this.renderDragLine(ResizeDragDirection.left, popup)}
|
||||||
|
<div className="popup-layer-root-content">
|
||||||
|
{this.renderHeader(popup)}
|
||||||
|
{this.renderContent(popup)}
|
||||||
|
</div>
|
||||||
|
{this.renderDragLine(ResizeDragDirection.right, popup)}
|
||||||
|
</div>
|
||||||
|
{this.renderDragLine(ResizeDragDirection.bottom, popup)}
|
||||||
</Theme>
|
</Theme>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,9 +273,54 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro
|
|||||||
|
|
||||||
private handelMouseUp = () => {
|
private handelMouseUp = () => {
|
||||||
this.isMouseDown = false;
|
this.isMouseDown = false;
|
||||||
|
if (this.props.status) {
|
||||||
|
this.props.status.popup.popups.forEach((popup) => {
|
||||||
|
popup.isOnMouseDown = false;
|
||||||
|
popup.resizeDragDirection = undefined;
|
||||||
|
popup.isResizeMouseDown = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private resize(popup: PopupModel, dis: number, dir: boolean, lsk: boolean) {
|
||||||
|
|
||||||
|
if (dir) {
|
||||||
|
// Y
|
||||||
|
popup.isResizeOverFlowY = false;
|
||||||
|
const heightBackup = popup.height
|
||||||
|
const topBackup = popup.top;
|
||||||
|
if (lsk) {
|
||||||
|
popup.height += dis;
|
||||||
|
} else {
|
||||||
|
popup.top += dis;
|
||||||
|
popup.height -= dis;
|
||||||
|
}
|
||||||
|
if (popup.height < popup.minHeight) {
|
||||||
|
popup.height = heightBackup;
|
||||||
|
popup.top = topBackup;
|
||||||
|
popup.isResizeOverFlowY = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// X
|
||||||
|
popup.isResizeOverFlowX = false;
|
||||||
|
const leftBackup = popup.left
|
||||||
|
const widthBackup = popup.width;
|
||||||
|
if (lsk) {
|
||||||
|
popup.width += dis;
|
||||||
|
} else {
|
||||||
|
popup.left += dis;
|
||||||
|
popup.width -= dis;
|
||||||
|
}
|
||||||
|
if (popup.width < popup.minWidth) {
|
||||||
|
popup.width = widthBackup;
|
||||||
|
popup.left = leftBackup;
|
||||||
|
popup.isResizeOverFlowX = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handelMouseMove = (e: MouseEvent) => {
|
private handelMouseMove = (e: MouseEvent) => {
|
||||||
|
let isActionSuccess: boolean = false;
|
||||||
if (
|
if (
|
||||||
this.isMouseDown &&
|
this.isMouseDown &&
|
||||||
this.props.status &&
|
this.props.status &&
|
||||||
@ -159,10 +332,69 @@ class Popup extends Component<IPopupProps & IMixinStatusProps & IMixinSettingPro
|
|||||||
popup.left += e.clientX - popup.lastMouseLeft;
|
popup.left += e.clientX - popup.lastMouseLeft;
|
||||||
popup.lastMouseLeft = e.clientX;
|
popup.lastMouseLeft = e.clientX;
|
||||||
popup.lastMouseTop = e.clientY;
|
popup.lastMouseTop = e.clientY;
|
||||||
|
isActionSuccess = true;
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (this.props.status) {
|
||||||
|
this.props.status.popup.popups.forEach((popup) => {
|
||||||
|
if (popup.resizeDragDirection) {
|
||||||
|
|
||||||
|
let moveX = e.clientX - popup.lastMouseLeft;
|
||||||
|
let moveY = e.clientY - popup.lastMouseTop;
|
||||||
|
switch (popup.resizeDragDirection) {
|
||||||
|
|
||||||
|
case ResizeDragDirection.LeftTop:
|
||||||
|
this.resize(popup, moveX, false, false);
|
||||||
|
this.resize(popup, moveY, true, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.leftBottom:
|
||||||
|
this.resize(popup, moveX, false, false);
|
||||||
|
this.resize(popup, moveY, true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.rightTop:
|
||||||
|
this.resize(popup, moveX, false, true);
|
||||||
|
this.resize(popup, moveY, true, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.rightBottom:
|
||||||
|
this.resize(popup, moveX, false, true);
|
||||||
|
this.resize(popup, moveY, true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.top:
|
||||||
|
this.resize(popup, moveY, true, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.left:
|
||||||
|
this.resize(popup, moveX, false, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.bottom:
|
||||||
|
this.resize(popup, moveY, true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ResizeDragDirection.right:
|
||||||
|
this.resize(popup, moveX, false, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!popup.isResizeOverFlowX) {
|
||||||
|
popup.lastMouseLeft = e.clientX;
|
||||||
|
}
|
||||||
|
if (!popup.isResizeOverFlowY) {
|
||||||
|
popup.lastMouseTop = e.clientY;
|
||||||
|
}
|
||||||
|
isActionSuccess = true;
|
||||||
|
this.forceUpdate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (isActionSuccess) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
|
@ -3,6 +3,17 @@ import { Emitter } from "@Model/Emitter";
|
|||||||
import { Localization } from "@Component/Localization/Localization";
|
import { Localization } from "@Component/Localization/Localization";
|
||||||
import { IAnyObject } from "@Model/Renderer";
|
import { IAnyObject } from "@Model/Renderer";
|
||||||
|
|
||||||
|
enum ResizeDragDirection {
|
||||||
|
top = 1,
|
||||||
|
rightTop = 2,
|
||||||
|
right = 3,
|
||||||
|
rightBottom = 4,
|
||||||
|
bottom = 5,
|
||||||
|
leftBottom = 6,
|
||||||
|
left = 7,
|
||||||
|
LeftTop = 8
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 弹窗类型
|
* 弹窗类型
|
||||||
*/
|
*/
|
||||||
@ -15,22 +26,23 @@ class Popup<P extends IAnyObject = IAnyObject> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public zIndex() {
|
public zIndex() {
|
||||||
return this.index * 2 + this.controller.zIndex;
|
return this.index * 5 + this.controller.zIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public width: number = 300;
|
public width: number = 300;
|
||||||
|
|
||||||
public height: number = 200;
|
public height: number = 200;
|
||||||
|
public minWidth: number = 300;
|
||||||
|
public minHeight: number = 200;
|
||||||
public top: number = NaN;
|
public top: number = NaN;
|
||||||
|
|
||||||
public left: number = NaN;
|
public left: number = NaN;
|
||||||
|
|
||||||
public lastMouseTop: number = 0;
|
public lastMouseTop: number = 0;
|
||||||
|
|
||||||
public lastMouseLeft: number = 0;
|
public lastMouseLeft: number = 0;
|
||||||
|
|
||||||
public isOnMouseDown: boolean = false;
|
public isOnMouseDown: boolean = false;
|
||||||
|
public resizeHoverDirection?: ResizeDragDirection;
|
||||||
|
public resizeDragDirection?: ResizeDragDirection;
|
||||||
|
public isResizeMouseDown: boolean = false;
|
||||||
|
public isResizeOverFlowX: boolean = false;
|
||||||
|
public isResizeOverFlowY: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否关闭
|
* 是否关闭
|
||||||
@ -178,4 +190,4 @@ class PopupController extends Emitter<IPopupControllerEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Popup, PopupController }
|
export { Popup, PopupController, ResizeDragDirection }
|
Loading…
Reference in New Issue
Block a user