|
@@ -1,449 +0,0 @@
|
|
|
-export default class DragPage {
|
|
|
- domID: string;
|
|
|
- fullUrl: string;
|
|
|
- private target: HTMLDivElement;
|
|
|
- private title: HTMLDivElement;
|
|
|
- private leftTop: HTMLDivElement;
|
|
|
- private rightTop: HTMLDivElement;
|
|
|
- private leftBottom: HTMLDivElement;
|
|
|
- private rightBottom: HTMLDivElement;
|
|
|
- private left: HTMLDivElement;
|
|
|
- private right: HTMLDivElement;
|
|
|
- private _top: HTMLDivElement;
|
|
|
- private bottom: HTMLDivElement;
|
|
|
- private mask: HTMLDivElement;
|
|
|
- private options: PageOptiosn;
|
|
|
- private newWidth: number;
|
|
|
- private newHeight: number;
|
|
|
- private distanceX: number;
|
|
|
- private distanceY: number;
|
|
|
- private width = 0;
|
|
|
- private height = 0;
|
|
|
- private maxWidth = 0;
|
|
|
- private maxHeight = 0;
|
|
|
- private tx = 0;
|
|
|
- private ty = 0;
|
|
|
- private startX = 0;
|
|
|
- private startY = 0;
|
|
|
- constructor(dragBox: HTMLDivElement, fullUrl: string, options: PageOptiosn) {
|
|
|
- this.target = dragBox;
|
|
|
- dragBox.className = 'drag';
|
|
|
- this.options = Object.assign(
|
|
|
- {
|
|
|
- limit: true,
|
|
|
- drag: true,
|
|
|
- zoom: true,
|
|
|
- minWidth: 340,
|
|
|
- minHeight: 200,
|
|
|
- header: true,
|
|
|
- background: true,
|
|
|
- canClose: false,
|
|
|
- left: '0px',
|
|
|
- top: '0px',
|
|
|
- width: '340px',
|
|
|
- height: '200px',
|
|
|
- name: '这是一个标题',
|
|
|
- },
|
|
|
- options
|
|
|
- );
|
|
|
- this.fullUrl = fullUrl;
|
|
|
- this.init();
|
|
|
- }
|
|
|
- destory() {
|
|
|
- let dragDom = document.getElementById(this.domID);
|
|
|
- const iframe = dragDom.getElementsByTagName('iframe')[0];
|
|
|
- iframe.src = 'about:blank';
|
|
|
-
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- iframe.contentWindow.document.write('');
|
|
|
- iframe.contentWindow.document.clear();
|
|
|
-
|
|
|
- //把dom从页面移除
|
|
|
- dragDom.parentElement.removeChild(dragDom);
|
|
|
-
|
|
|
- resolve(null);
|
|
|
- }, 100);
|
|
|
- });
|
|
|
- }
|
|
|
- // 初始化
|
|
|
- private init() {
|
|
|
- let id: string = uuidv4();
|
|
|
- let target = this.target;
|
|
|
- // 保存id
|
|
|
- this.domID = target.id = id;
|
|
|
-
|
|
|
- this.initDom();
|
|
|
- this.initStyle();
|
|
|
- }
|
|
|
- // 初始化target样式
|
|
|
- private initStyle() {
|
|
|
- let target = this.target;
|
|
|
- let options = this.options;
|
|
|
- let style = target.style;
|
|
|
- style.position = 'absolute';
|
|
|
- style.top = options.top;
|
|
|
- style.width = options.width;
|
|
|
- style.height = options.height;
|
|
|
- style.backgroundColor = options.background ? '#0d1a2b' : 'transparent';
|
|
|
-
|
|
|
- if (!options.header) {
|
|
|
- style.width = '100%';
|
|
|
- style.height = '100%';
|
|
|
- style.paddingTop = '0';
|
|
|
- let dom = <HTMLElement>target.getElementsByClassName('content')[0];
|
|
|
- dom.style.border = 'none';
|
|
|
- }
|
|
|
- // 居右
|
|
|
- if (options.right) {
|
|
|
- style.left =
|
|
|
- document.body.clientWidth -
|
|
|
- target.clientWidth -
|
|
|
- Number(options.right.replace('px', '')) +
|
|
|
- 'px';
|
|
|
- } else {
|
|
|
- style.left = options.left;
|
|
|
- }
|
|
|
- }
|
|
|
- // 初始化dom
|
|
|
- private initDom() {
|
|
|
- let options = this.options;
|
|
|
- this.getBoundary();
|
|
|
- this.addIframe();
|
|
|
-
|
|
|
- if (options.header) {
|
|
|
- this.addTitle();
|
|
|
- if (options.drag) {
|
|
|
- this.drag();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (options.zoom) {
|
|
|
- this.addHorn();
|
|
|
- this.addBorder();
|
|
|
- this.leftZoom();
|
|
|
- this.rightZoom();
|
|
|
- this.topZoom();
|
|
|
- this.bottomZoom();
|
|
|
- this.leftTopZoom();
|
|
|
- this.leftBottomZoom();
|
|
|
- this.rightTopZoom();
|
|
|
- this.rightBottomZoom();
|
|
|
- }
|
|
|
- }
|
|
|
- private addIframe() {
|
|
|
- let iframe: HTMLIFrameElement = document.createElement('iframe');
|
|
|
- iframe.src = this.fullUrl;
|
|
|
- iframe.className = 'content';
|
|
|
- iframe.style.width = '100%';
|
|
|
- iframe.style.height = '100%';
|
|
|
- this.target.append(iframe);
|
|
|
- }
|
|
|
- // 获取父元素的宽高
|
|
|
- private getBoundary() {
|
|
|
- this.maxWidth = this.target.parentElement.clientWidth;
|
|
|
- this.maxHeight = this.target.parentElement.clientHeight;
|
|
|
- }
|
|
|
- // 获取自身起始信息
|
|
|
- private getInfo(e: MouseEvent) {
|
|
|
- this.width = this.target.clientWidth;
|
|
|
- this.height = this.target.clientHeight;
|
|
|
- let top = this.target.style.top;
|
|
|
- let left = this.target.style.left;
|
|
|
- this.tx = Number(left.replace('px', ''));
|
|
|
- this.ty = Number(top.replace('px', ''));
|
|
|
- this.startX = e.clientX;
|
|
|
- this.startY = e.clientY;
|
|
|
- }
|
|
|
- // 拖动实现
|
|
|
- private drag() {
|
|
|
- this.title.addEventListener('mousedown', e => {
|
|
|
- this.getInfo(e);
|
|
|
- let _this = this;
|
|
|
- document.onmousemove = e => {
|
|
|
- if (_this.options.limit) {
|
|
|
- _this.distanceX = Math.max(
|
|
|
- 0,
|
|
|
- Math.min(_this.tx + e.clientX - _this.startX, _this.maxWidth - _this.width)
|
|
|
- );
|
|
|
- _this.distanceY = Math.max(
|
|
|
- 0,
|
|
|
- Math.min(_this.ty + e.clientY - _this.startY, _this.maxHeight - _this.height)
|
|
|
- );
|
|
|
- } else {
|
|
|
- _this.distanceX = _this.tx + e.clientX - _this.startX;
|
|
|
- _this.distanceY = _this.ty + e.clientY - _this.startY;
|
|
|
- }
|
|
|
- // _this.target.style.transform = `translate(${_this.distanceX}px, ${_this.distanceY}px)`;
|
|
|
- _this.target.style.left = _this.distanceX + 'px';
|
|
|
- _this.target.style.top = _this.distanceY + 'px';
|
|
|
- };
|
|
|
- document.onmouseup = () => {
|
|
|
- document.onmousemove = null;
|
|
|
- };
|
|
|
- });
|
|
|
- }
|
|
|
- private handleBtns() {
|
|
|
- // const onActive = this.options.onActive;
|
|
|
- this.target.addEventListener('mousedown', (e: MouseEvent) => {
|
|
|
- this.toogleMask(true);
|
|
|
- let eventTarget: HTMLElement = e.target as HTMLElement;
|
|
|
- let style = this.target.style;
|
|
|
- // onActive && onActive();
|
|
|
- if (eventTarget.nodeName.toLocaleLowerCase() == 'i') {
|
|
|
- e.stopPropagation();
|
|
|
- if (eventTarget.className == 'btn icon-zoom-in') {
|
|
|
- // 放大按钮
|
|
|
- this.startX = 0;
|
|
|
- this.startY = 0;
|
|
|
- this.tx = 0;
|
|
|
- this.ty = 0;
|
|
|
- style.width = '100%';
|
|
|
- style.height = '100%';
|
|
|
- style.top = '0px';
|
|
|
- style.left = '0px';
|
|
|
- } else if (eventTarget.className == 'btn icon-zoom-out') {
|
|
|
- // 缩小按钮
|
|
|
- this.startX = 0;
|
|
|
- this.startY = 0;
|
|
|
- this.tx = 0;
|
|
|
- this.ty = 0;
|
|
|
- style.top = '0px';
|
|
|
- style.left = '0px';
|
|
|
- style.width = this.options.minWidth + 'px';
|
|
|
- style.height = this.options.minHeight + 'px';
|
|
|
- } else if (eventTarget.className == 'btn icon-close') {
|
|
|
- // 关闭窗口事件
|
|
|
- this.options.onClose?.();
|
|
|
- this.destory()
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- this.target.addEventListener('mouseup', () => {
|
|
|
- this.toogleMask(false);
|
|
|
- });
|
|
|
- }
|
|
|
- private addTitle() {
|
|
|
- const title = document.createElement('div');
|
|
|
- title.className = 'title';
|
|
|
- title.innerHTML = `<h3>${this.options.name}</h3>
|
|
|
- <div class="btns">
|
|
|
- <i class="btn icon-zoom-out"></i>
|
|
|
- <i class="btn icon-zoom-in"></i>
|
|
|
- ${this.options.canClose?'<i class="btn icon-close"></i>':''}
|
|
|
- </div>`;
|
|
|
- this.target.append(title);
|
|
|
- this.title = title;
|
|
|
-
|
|
|
- this.handleBtns();
|
|
|
- }
|
|
|
- // 添加四个角
|
|
|
- private addHorn() {
|
|
|
- this.leftTop = document.createElement('div');
|
|
|
- this.rightTop = document.createElement('div');
|
|
|
- this.leftBottom = document.createElement('div');
|
|
|
- this.rightBottom = document.createElement('div');
|
|
|
- this.leftTop.className = 'horn leftTop';
|
|
|
- this.rightTop.className = 'horn rightTop';
|
|
|
- this.leftBottom.className = 'horn leftBottom';
|
|
|
- this.rightBottom.className = 'horn rightBottom';
|
|
|
- this.target.append(this.leftTop);
|
|
|
- this.target.append(this.rightTop);
|
|
|
- this.target.append(this.leftBottom);
|
|
|
- this.target.append(this.rightBottom);
|
|
|
- }
|
|
|
- // 添加四条边
|
|
|
- private addBorder() {
|
|
|
- this.left = document.createElement('div');
|
|
|
- this.right = document.createElement('div');
|
|
|
- this._top = document.createElement('div');
|
|
|
- this.bottom = document.createElement('div');
|
|
|
- this.mask = document.createElement('div');
|
|
|
- this.left.className = 'vertical left';
|
|
|
- this.right.className = 'vertical right';
|
|
|
- this._top.className = 'horizontal top';
|
|
|
- this.bottom.className = 'horizontal bottom';
|
|
|
- this.mask.className = 'mask';
|
|
|
- this.target.append(this.mask);
|
|
|
- this.target.append(this.left);
|
|
|
- this.target.append(this.right);
|
|
|
- this.target.append(this._top);
|
|
|
- this.target.append(this.bottom);
|
|
|
- }
|
|
|
- // 缩放实现
|
|
|
- private zoom(el: HTMLElement, direction: string) {
|
|
|
- el.addEventListener('mousedown', e => {
|
|
|
- this.toogleMask(true);
|
|
|
- e.stopPropagation();
|
|
|
- this.getInfo(e);
|
|
|
- document.onmousemove = e => {
|
|
|
- switch (direction) {
|
|
|
- case 'left':
|
|
|
- this.leftInfo(e);
|
|
|
- break;
|
|
|
- case 'right':
|
|
|
- this.rightInfo(e);
|
|
|
- break;
|
|
|
- case 'top':
|
|
|
- this.topInfo(e);
|
|
|
- break;
|
|
|
- case 'bottom':
|
|
|
- this.bottomInfo(e);
|
|
|
- break;
|
|
|
- case 'leftTop':
|
|
|
- this.leftTopInfo(e);
|
|
|
- break;
|
|
|
- case 'leftBottom':
|
|
|
- this.leftBottomInfo(e);
|
|
|
- break;
|
|
|
- case 'rightTop':
|
|
|
- this.rightTopInfo(e);
|
|
|
- break;
|
|
|
- case 'rightBottom':
|
|
|
- this.rightBottomInfo(e);
|
|
|
- break;
|
|
|
- }
|
|
|
- // 这里不能直接使用对this.newWidth隐式类型转换来判断,因为this.newWidth===0时,会使用this.width
|
|
|
- let width = this.newWidth !== undefined ? this.newWidth : this.width;
|
|
|
- let height = this.newHeight !== undefined ? this.newHeight : this.height;
|
|
|
- let translateX = this.distanceX !== undefined ? this.distanceX : this.tx;
|
|
|
- let translateY = this.distanceY !== undefined ? this.distanceY : this.ty;
|
|
|
- this.target.style.width = `${width}px`;
|
|
|
- this.target.style.height = `${height}px`;
|
|
|
- // this.target.style.transform = `translate(${translateX}px, ${translateY}px)`;
|
|
|
- this.target.style.left = translateX + 'px';
|
|
|
- this.target.style.top = translateY + 'px';
|
|
|
- };
|
|
|
- document.onmouseup = () => {
|
|
|
- document.onmousemove = null;
|
|
|
-
|
|
|
- this.toogleMask(false);
|
|
|
- };
|
|
|
- });
|
|
|
- }
|
|
|
- private toogleMask(show: boolean) {
|
|
|
- let display: string = show ? 'block' : 'none';
|
|
|
- // 查询所有mask
|
|
|
- document.querySelectorAll('.drag .mask').forEach((ele: HTMLElement) => {
|
|
|
- ele.style.display = display;
|
|
|
- });
|
|
|
- }
|
|
|
- // 获取缩放时宽高、translate等参数的值
|
|
|
- private leftInfo(e: MouseEvent) {
|
|
|
- this.newWidth = this.width - (e.clientX - this.startX);
|
|
|
- this.distanceX = this.tx + (e.clientX - this.startX);
|
|
|
- if (this.options.limit) {
|
|
|
- this.newWidth = Math.max(
|
|
|
- this.options.minWidth,
|
|
|
- Math.min(this.newWidth, this.width + this.tx)
|
|
|
- );
|
|
|
- this.distanceX = Math.max(
|
|
|
- 0,
|
|
|
- Math.min(this.distanceX, this.width + this.tx - this.options.minWidth)
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- private rightInfo(e: MouseEvent) {
|
|
|
- this.newWidth = this.width + (e.clientX - this.startX);
|
|
|
- if (this.options.limit) {
|
|
|
- this.newWidth = Math.max(
|
|
|
- this.options.minWidth,
|
|
|
- Math.min(this.newWidth, this.maxWidth - this.tx)
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- private topInfo(e: MouseEvent) {
|
|
|
- this.newHeight = this.height - (e.clientY - this.startY);
|
|
|
- this.distanceY = this.ty + (e.clientY - this.startY);
|
|
|
- if (this.options.limit) {
|
|
|
- this.newHeight = Math.max(
|
|
|
- this.options.minHeight,
|
|
|
- Math.min(this.newHeight, this.height + this.ty)
|
|
|
- );
|
|
|
- this.distanceY = Math.max(
|
|
|
- 0,
|
|
|
- Math.min(this.distanceY, this.height + this.ty - this.options.minHeight)
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- private bottomInfo(e: MouseEvent) {
|
|
|
- this.newHeight = this.height + (e.clientY - this.startY);
|
|
|
- if (this.options.limit) {
|
|
|
- this.newHeight = Math.max(
|
|
|
- this.options.minHeight,
|
|
|
- Math.min(this.newHeight, this.maxHeight - this.ty)
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
- private leftTopInfo(e: MouseEvent) {
|
|
|
- this.leftInfo(e);
|
|
|
- this.topInfo(e);
|
|
|
- }
|
|
|
- private leftBottomInfo(e: MouseEvent) {
|
|
|
- this.leftInfo(e);
|
|
|
- this.bottomInfo(e);
|
|
|
- }
|
|
|
- private rightTopInfo(e: MouseEvent) {
|
|
|
- this.rightInfo(e);
|
|
|
- this.topInfo(e);
|
|
|
- }
|
|
|
- private rightBottomInfo(e: MouseEvent) {
|
|
|
- this.rightInfo(e);
|
|
|
- this.bottomInfo(e);
|
|
|
- }
|
|
|
- private leftZoom() {
|
|
|
- this.zoom(this.left, 'left');
|
|
|
- }
|
|
|
- private rightZoom() {
|
|
|
- this.zoom(this.right, 'right');
|
|
|
- }
|
|
|
- private topZoom() {
|
|
|
- this.zoom(this._top, 'top');
|
|
|
- }
|
|
|
- private bottomZoom() {
|
|
|
- this.zoom(this.bottom, 'bottom');
|
|
|
- }
|
|
|
- private leftTopZoom() {
|
|
|
- this.zoom(this.leftTop, 'leftTop');
|
|
|
- }
|
|
|
- private leftBottomZoom() {
|
|
|
- this.zoom(this.leftBottom, 'leftBottom');
|
|
|
- }
|
|
|
- private rightTopZoom() {
|
|
|
- this.zoom(this.rightTop, 'rightTop');
|
|
|
- }
|
|
|
- private rightBottomZoom() {
|
|
|
- this.zoom(this.rightBottom, 'rightBottom');
|
|
|
- }
|
|
|
-}
|
|
|
-export interface PageOptiosn {
|
|
|
- name?: string; // 页面标题
|
|
|
- drag?: boolean; // 是否可拖拽
|
|
|
- zoom?: boolean; // 是否可放大
|
|
|
- limit?: boolean; // 拖拽是否可超出父级
|
|
|
- minWidth?: number; // 最小宽度
|
|
|
- minHeight?: number; // 最小高度
|
|
|
- header?: boolean; // 是否有title
|
|
|
- background?: boolean; // 背景色
|
|
|
-
|
|
|
- // 初始化坐标
|
|
|
- left?: string;
|
|
|
- top?: string;
|
|
|
- right?: string;
|
|
|
-
|
|
|
- // 初始化尺寸
|
|
|
- width?: string;
|
|
|
- height?: string;
|
|
|
-
|
|
|
-
|
|
|
- canClose?: boolean; // 是否可以关闭
|
|
|
- // 回调函数
|
|
|
- onClose?: () => null;
|
|
|
-}
|
|
|
-function uuidv4(): string {
|
|
|
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
|
- const r = (Math.random() * 16) | 0,
|
|
|
- v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
|
- return v.toString(16);
|
|
|
- });
|
|
|
-}
|