diff --git a/README.md b/README.md index 76b803d..3edf6e2 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,10 @@ all normal `` props can be used - `{x} {y}`: (eg. `focalPoint=".75 .5"` or `focalPoint="75% 50%"`) focus on the point `x%` from the left and `y%` from the top. ![img](http://i.imgur.com/XY3jVPX.png) - `scale`: (work if resizeMode = 'cover') if provided, the image will scale from container width. (Not image original width) - - scale = 1, the image will cover the whole area perfectly + - scale = 1, the image will cover the whole area precisely. +- `clickToZoom` (Boolean: default = false) if true then user can click to zoomIn +- `zoomInScale` determine value of zoomed-in scale when clickToZoom +![img](http://i.giphy.com/3o84TYe7Y9yOFHFnIQ.gif) Note: If you do not provide resizeMode, `` will just render normal `` diff --git a/dev/containers/App.js b/dev/containers/App.js index 9c7b65c..2f48f8f 100644 --- a/dev/containers/App.js +++ b/dev/containers/App.js @@ -1,5 +1,4 @@ import React, { Component } from 'react'; -// import BetterImg from '../../dist'; import BetterImg from '../../src'; export default class App extends Component { @@ -21,9 +20,10 @@ export default class App extends Component {
diff --git a/dev/img/puppy-line.jpg b/dev/img/puppy-line.jpg new file mode 100644 index 0000000..e8e10a0 Binary files /dev/null and b/dev/img/puppy-line.jpg differ diff --git a/src/index.js b/src/index.js index c62c72d..d788ec0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,24 @@ import React, { Component, PropTypes } from 'react'; -import omit from 'lodash/omit'; +import pick from 'lodash/pick'; const elementResizeDetectorMaker = require("element-resize-detector"); +const imgAttrs = [ + "align", + "alt", + "crossorigin", + "height", + "hspace", + "ismap", + "longdesc", + "sizes", + "src", + "srcset", + "usemap", + "vspace", + "width", +]; + const calculateScale = (resizeMode, containerWidth, containerHeight, imgWidth, imgHeight) => { const containerImgWidthRatio = containerWidth / imgWidth; @@ -68,7 +84,9 @@ class BetterImg extends Component { width: PropTypes.number, height: PropTypes.number, scale: PropTypes.number, + zoomInScale: PropTypes.number, focalPoint: PropTypes.string, + clickToZoom: PropTypes.bool, resizeMode: PropTypes.oneOf([ 'cover', 'contain', @@ -80,11 +98,17 @@ class BetterImg extends Component { static defaultProps = { scale: 1, focalPoint: 'center', + zoomInScale: 2, + clickToZoom: false, } state = { imgWidth: 0, imgHeight: 0, + imgLoaded: false, + imgClicked: false, + currentZoomScale: this.props.scale, + focalPoint: this.props.focalPoint, containerWidth: undefined, containerHeight: undefined, } @@ -97,6 +121,7 @@ class BetterImg extends Component { this.setState({ imgWidth, imgHeight, + imgLoaded: true, containerHeight: this.props.height || imgHeight, }); @@ -122,11 +147,42 @@ class BetterImg extends Component { }); } + handleClick = (e) => { + e.stopPropagation(); + const { clickToZoom } = this.props; + if (clickToZoom) { + // console.log('BetterImg', e.nativeEvent.clientX, e.nativeEvent.clientY); + // console.log('Parent', this.container.getBoundingClientRect()); + const { left, top } = this.container.getBoundingClientRect(); + const pointX = e.nativeEvent.clientX - left; + const pointY = e.nativeEvent.clientY - top; + // console.log('pointX,Y = ', pointX, pointY); + const containerWidth = this.props.width || this.state.containerWidth; + const containerHeight = this.state.containerHeight; + + if (!this.state.isZoomedIn) { + this.setState({ + isZoomedIn: true, + imgClicked: true, + currentZoomScale: this.props.zoomInScale, + focalPoint: `${pointX/containerWidth} ${pointY/containerHeight}` + }); + } else { + this.setState({ + isZoomedIn: false, + imgClicked: true, + currentZoomScale: this.props.scale, + focalPoint: 'center', + }); + } + } + } + render() { // If no resizeMode is provided, be normal if (!this.props.resizeMode) { - const imgProps = omit(this.props, ['focalPoint', 'resizeMode', 'scale']); + const imgProps = pick(this.props, imgAttrs); return (); } @@ -147,16 +203,16 @@ class BetterImg extends Component { // Calculate Scale let { scaleX, scaleY } = calculateScale(resizeMode, containerWidth, containerHeight, imgWidth, imgHeight); - if (resizeMode === 'cover' && this.props.scale) { - scaleX = this.props.scale * scaleX; - scaleY = this.props.scale * scaleY; + if (resizeMode === 'cover' && this.state.currentZoomScale) { + scaleX = this.state.currentZoomScale * scaleX; + scaleY = this.state.currentZoomScale * scaleY; } // Focal Point (cover only) let focalPointX = .5; let focalPointY = .5; if (resizeMode === 'cover') { - let focalPoint = mapFocalPointProps(this.props.focalPoint); + let focalPoint = mapFocalPointProps(this.state.focalPoint); focalPointX = focalPoint.focalPointX; focalPointY = focalPoint.focalPointY; } @@ -170,10 +226,20 @@ class BetterImg extends Component { transform: `translate3d(${x}px, ${y}px, 0) scale(${scaleX}, ${scaleY})`, transformOrigin: '0% 0%', } + if (this.props.clickToZoom && this.state.imgClicked) imgStyle.transition = 'all .3s ease-out'; - const imgProps = omit(this.props, ['width', 'height', 'focalPoint', 'scale', 'resizeMode']); + const containerProps = {}; + if (this.props.clickToZoom) { + containerProps.onClick = this.handleClick; + } + const imgProps = pick(this.props, imgAttrs); return ( -
this.container = container}> +
this.container = container} + {...containerProps} + >