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