From c78051cc51032d4e29d35ca356d11d77a473eced Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期一, 09 八月 2021 18:20:08 +0800
Subject: [PATCH] 2021-08-09

---
 src/components/imgScale/index.jsx |  146 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 141 insertions(+), 5 deletions(-)

diff --git a/src/components/imgScale/index.jsx b/src/components/imgScale/index.jsx
index f948dd7..9d82112 100644
--- a/src/components/imgScale/index.jsx
+++ b/src/components/imgScale/index.jsx
@@ -22,6 +22,12 @@
     index: 0
   }
 
+  imgNode = null
+  wrapNode = null
+  visible = false
+  originPositionRef = null
+  position = {x: 0, y: 0}
+
   componentDidMount () {
     MKEmitter.addListener('mkImageScale', this.mkImageScale)
   }
@@ -46,21 +52,141 @@
       _list = list
     }
 
-    this.setState({url: src, className: 'opening', list: _list, scale: 1, rotate: 0, index})
+    this.setState({url: src, className: 'opening', list: _list, scale: 1, rotate: 0, index, position: {x: 0, y: 0}})
     setTimeout(() => {
       this.setState({className: 'open'})
+
+      window.addEventListener('mouseup', this.onMouseUp)
+      window.addEventListener('mousemove', this.onMouseMove)
+      window.addEventListener('wheel', this.onWheelMove, {passive: false})
+      this.imgNode && this.imgNode.addEventListener('mousedown', this.onMouseDown)
+      this.wrapNode.style.transform = 'translate3d(0px, 0px, 0px)'
+
+      this.position = {x: 0, y: 0}
+      this.originPositionRef = {
+        originX: 0,
+        originY: 0,
+        deltaX: 0,
+        deltaY: 0
+      }
     }, 300)
+  }
+
+  onMouseDown = (e) => {
+    e.preventDefault()
+    e.stopPropagation()
+
+    this.visible = true
+
+    this.originPositionRef.deltaX = e.pageX
+    this.originPositionRef.deltaY = e.pageY
+    this.originPositionRef.originX = this.position.x
+    this.originPositionRef.originY = this.position.y
+  }
+
+  onMouseUp = (e) => {
+    const { scale, rotate } = this.state
+    this.visible = false
+
+    if (!this.imgNode) return
+
+    let isRotate = rotate % 180 !== 0
+
+    let nodeWidth = this.imgNode.offsetWidth * scale
+    let nodeHeight = this.imgNode.offsetHeight * scale
+    let winWidth = window.innerWidth
+    let winHeight = window.innerHeight
+    let width = isRotate ? nodeHeight : nodeWidth
+    let height = isRotate ? nodeWidth : nodeHeight
+
+    let x = this.position.x
+    let y = this.position.y
+
+    if (width <= winWidth && height <= winHeight) {
+      x = 0
+      y = 0
+    } else {
+      x = this.fixPoint(x, width, winWidth)
+      y = this.fixPoint(y, height, winHeight)
+    }
+
+    this.position.x = x
+    this.position.y = y
+
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
+  }
+
+  fixPoint(start, width, clientWidth) {
+    let startAddWidth = start + width
+    let offsetStart = (width - clientWidth) / 2
+  
+    if (width > clientWidth) {
+      if (start > 0) {
+        return offsetStart
+      }
+  
+      if (start < 0 && startAddWidth < clientWidth) {
+        return -offsetStart
+      }
+    } else if (start < 0 || startAddWidth > clientWidth) {
+      return start < 0 ? offsetStart : -offsetStart
+    }
+  
+    return start
+  }
+
+  onMouseMove = (e) => {
+    if (!this.visible) return
+
+    e.preventDefault()
+    e.stopPropagation()
+
+    let x = e.pageX - this.originPositionRef.deltaX
+    let y = e.pageY - this.originPositionRef.deltaY
+
+    this.position.x = this.originPositionRef.originX + x
+    this.position.y = this.originPositionRef.originY + y
+
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
+  }
+
+  onWheelMove = (e) => {
+    e.preventDefault()
+    let delta = -e.wheelDelta || e.deltaY
+
+    if (delta > 0) {
+      this.zoomOut()
+    } else if(delta < 0) {
+      this.zoomIn()
+    }
+
+    this.position.x = 0
+    this.position.y = 0
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
   }
 
   close = () => {
     this.setState({className: 'closeing'})
+
+    this.visible = false
+    
+    this.imgNode && this.imgNode.removeEventListener('mousedown', this.onMouseDown)
+    window.removeEventListener('mouseup', this.onMouseUp)
+    window.removeEventListener('mousemove', this.onMouseMove)
+    window.removeEventListener('wheel', this.onWheelMove)
+
     setTimeout(() => {
+      this.wrapNode.style.transform = 'translate3d(0px, 0px, 0px)'
       this.setState({className: 'close', url: ''})
     }, 300)
   }
 
   zoomIn = () => {
     this.setState({scale: this.state.scale + 1})
+
+    this.position.x = 0
+    this.position.y = 0
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
   }
 
   zoomOut = () => {
@@ -69,6 +195,10 @@
     if (scale === 1) return
 
     this.setState({scale: scale - 1})
+
+    this.position.x = 0
+    this.position.y = 0
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
   }
 
   rotateRight = () => {
@@ -82,13 +212,19 @@
   prev = () => {
     const { list, index } = this.state
     
-    this.setState({url: list[index - 1], index: index - 1})
+    this.setState({url: list[index - 1], index: index - 1, scale: 1, rotate: 0})
+    this.position.x = 0
+    this.position.y = 0
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
   }
 
   next = () => {
     const { list, index } = this.state
     
-    this.setState({url: list[index + 1], index: index + 1})
+    this.setState({url: list[index + 1], index: index + 1, scale: 1, rotate: 0})
+    this.position.x = 0
+    this.position.y = 0
+    this.wrapNode.style.transform = `translate3d(${this.position.x}px, ${this.position.y}px, 0px)`
   }
 
   render() {
@@ -118,8 +254,8 @@
                     <RotateLeftOutlined />
                   </li>
                 </ul>
-                <div className="mk-image-preview-img-wrapper" style={{transform: 'translate3d(0px, 0px, 0px)'}}>
-                  {url ? <img className="mk-image-preview-img" alt="" src={url} style={{transform: `scale3d(${scale}, ${scale}, 1) rotate(${rotate}deg)`}}/> : null}
+                <div ref={e => (this.wrapNode = e)}  className="mk-image-preview-img-wrapper">
+                  {url ? <img ref={e => (this.imgNode = e)} className="mk-image-preview-img" alt="" src={url} style={{transform: `scale3d(${scale}, ${scale}, 1) rotate(${rotate}deg)`}}/> : null}
                 </div>
                 {index ? <LeftOutlined className="mk-image-preview-switch-left" onClick={this.prev}/> : null}
                 {list.length > index + 1 ? <RightOutlined className="mk-image-preview-switch-right" onClick={this.next}/> : null}

--
Gitblit v1.8.0