diff --git a/src/ViewerCavans.tsx b/src/ViewerCavans.tsx index 751865b..f910771 100644 --- a/src/ViewerCavans.tsx +++ b/src/ViewerCavans.tsx @@ -11,7 +11,7 @@ export interface ViewerCavansProps { rotate: number; onChangeImgState: (width: number, height: number, top: number, left: number) => void; onResize: () => void; - onZoom: (targetX: number, targetY: number, direct: number) => void; + onZoom: (targetX: number, targetY: number, direct: number, scale: number) => void; zIndex: number; scaleX: 1 | -1; scaleY: 1 | -1; @@ -88,7 +88,7 @@ export default class ViewerCavans extends React.Component; + } + return (
- + {imgNode}
); } diff --git a/src/ViewerCore.tsx b/src/ViewerCore.tsx index e867912..bcfe622 100644 --- a/src/ViewerCore.tsx +++ b/src/ViewerCore.tsx @@ -8,7 +8,12 @@ import Icon, { ActionType } from './Icon'; function noop() {} +const transitionDuration = 300; + export interface ViewerCoreState { + visible?: boolean; + visibleStart?: boolean; + transitionEnd?: boolean; activeIndex?: number; width?: number; height?: number; @@ -38,6 +43,9 @@ export default class ViewerCore extends React.Component { + this.setState({ + visible: true, + }); + setTimeout(() => { + this.bindEvent(); + this.loadImg(this.state.activeIndex); + }, 300); + }, 10); } - loadImg(activeIndex) { + componentDidMount() { + this.startVisible(); + } + + getImgWidthHeight(imgWidth, imgHeight) { + let width = 0; + let height = 0; + let aspectRatio = imgWidth / imgHeight; + let footerHeight = 84; + if (aspectRatio > 1) { + width = Math.min(window.innerWidth * .9, imgWidth); + height = (width / imgWidth) * imgHeight; + }else { + height = Math.min((window.innerHeight - footerHeight) * .8, imgHeight); + width = (height / imgHeight) * imgWidth; + } + return [width, height]; + } + + loadImg(activeIndex, firstLoad: boolean = true) { let imgSrc = ''; let images = this.props.images || []; if (images.length > 0) { @@ -80,33 +117,44 @@ export default class ViewerCore extends React.Component { - let width = 0; - let height = 0; let imgWidth = img.width; let imgHeight = img.height; - let aspectRatio = imgWidth / imgHeight; let footerHeight = 84; - if (aspectRatio > 1) { - width = Math.min(window.innerWidth * .9, imgWidth); - height = (width / imgWidth) * imgHeight; + if (firstLoad) { + this.setState({ + activeIndex: activeIndex, + width: 0, + height: 0, + left: window.innerWidth / 2, + top: (window.innerHeight - footerHeight) / 2, + rotate: 0, + imageWidth: imgWidth, + imageHeight: imgHeight, + scaleX: 1, + scaleY: 1, + }); + setTimeout(() => { + let imgCenterXY = this.getImageCenterXY(); + this.handleZoom(imgCenterXY.x, imgCenterXY.y, 1, 1); + }, 50); }else { - height = Math.min((window.innerHeight - footerHeight) * .8, imgHeight); - width = (height / imgHeight) * imgWidth; + const [ width, height ] = this.getImgWidthHeight(imgWidth, imgHeight); + let left = ( window.innerWidth - width ) / 2; + let top = (window.innerHeight - height - footerHeight) / 2; + this.setState({ + activeIndex: activeIndex, + width: width, + height: height, + left: left, + top: top, + rotate: 0, + imageWidth: imgWidth, + imageHeight: imgHeight, + scaleX: 1, + scaleY: 1, + }); } - let left = ( window.innerWidth - width ) / 2; - let top = (window.innerHeight - height - footerHeight) / 2; - this.setState({ - activeIndex: activeIndex, - width: width, - height: height, - left: left, - top: top, - rotate: 0, - imageWidth: imgWidth, - imageHeight: imgHeight, - scaleX: 1, - scaleY: 1, - }); + }; img.onerror = () => { this.setState({ @@ -125,7 +173,11 @@ export default class ViewerCore extends React.Component { + this.loadImg(newIndex, false); + }, transitionDuration); } handleChangeImgState(width, height, top, left) { @@ -141,21 +193,21 @@ export default class ViewerCore extends React.Component= 0) { - this.loadImg(this.state.activeIndex - 1); + this.handleChangeImg(this.state.activeIndex - 1); } break; case ActionType.next: if (this.state.activeIndex + 1 < this.props.images.length) { - this.loadImg(this.state.activeIndex + 1); + this.handleChangeImg(this.state.activeIndex + 1); } break; case ActionType.zoomIn: let imgCenterXY = this.getImageCenterXY(); - this.handleZoom(imgCenterXY.x, imgCenterXY.y, 1); + this.handleZoom(imgCenterXY.x, imgCenterXY.y, 1, .05); break; case ActionType.zoomOut: let imgCenterXY2 = this.getImageCenterXY(); - this.handleZoom(imgCenterXY2.x, imgCenterXY2.y, -1); + this.handleZoom(imgCenterXY2.x, imgCenterXY2.y, -1, .05); break; case ActionType.rotateLeft: this.handleRotate(); @@ -164,7 +216,7 @@ export default class ViewerCore extends React.Component { + this.setState({ + visible: false, + transitionEnd: false, + }); + }, transitionDuration); + return; + } + if (this.state.activeIndex !== nextProps.activeIndex) { + this.handleChangeImg(nextProps.activeIndex); + return; } } @@ -297,10 +376,6 @@ export default class ViewerCore extends React.Component 0) { - activeImg = images[this.state.activeIndex]; - } let zIndex = 1000; @@ -308,8 +383,29 @@ export default class ViewerCore extends React.Component 0 && this.state.activeIndex >= 0) { + activeImg = images[this.state.activeIndex]; + } + } + return ( -
+
{ return (
-
    +
      {this.props.images.map((item, index) =>