diff --git a/.travis.yml b/.travis.yml index 6894888..842797d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: node_js cache: directories: - node_modules +branches: + only: + - master notifications: email: false node_js: diff --git a/README.md b/README.md index 18bfdd5..0093e1e 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,14 @@ all normal `` props can be used - `cover`: Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding). - `contain`: Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding). - `stretch`: Scale width and height independently, This may change the aspect ratio of the src. +- `focalPoint`: default=`.5 .5` (work if resizeMode = 'cover') + Decides origin of the where to focus on the image, + - `left`: Keep left most part of the image. + - `right`: Keep right most part of the image. + - `top`: Keep top most part of the image. + - `bottom`: Keep bottom most part of the image. + - `{x} {y}`: (eg. `focalPoint=".75 .5"` or `focalPoint="75% 50%"`) focus on the point `x%` from the left and `y%` from the top. +- `scale`: (work if resizeMode = 'cover') if provided, the image will scale from container width. (Not image original width) Note: If you do not provide resizeMode, `` will just render normal `` @@ -34,6 +42,13 @@ render() { height={600} resizeMode="contain" /> + + ) } diff --git a/dev/containers/App.js b/dev/containers/App.js index d536b87..428e05e 100644 --- a/dev/containers/App.js +++ b/dev/containers/App.js @@ -16,6 +16,8 @@ export default class App extends Component {

resizeMode: Stretch

diff --git a/package.json b/package.json index 42f4588..ac09810 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,10 @@ "type": "git", "url": "git+https://github.com/Doppy/BetterImg.git" }, + "bugs": { + "url": "https://github.com/Doppy/BetterImg/issues" + }, + "homepage": "https://github.com/Doppy/BetterImg", "scripts": { "precommit": "npm test", "commit": "git-cz", diff --git a/src/index.js b/src/index.js index 9d245fc..4eace99 100644 --- a/src/index.js +++ b/src/index.js @@ -31,6 +31,32 @@ const calculateScale = (resizeMode, containerWidth, containerHeight, imgWidth, i } } +const convertPercentToDecimal = (num) => { + if (num.indexOf('%') !== -1) return parseFloat(num) / 100.0; + return num; +}; + +const mapFocalPointProps = (key) => { + switch (key) { + case 'center': return { focalPointX: .5, focalPointY: .5 }; + case 'left': return { focalPointX: 0, focalPointY: .5 }; + case 'right': return { focalPointX: 1, focalPointY: .5 }; + case 'top': return { focalPointX: 0.5, focalPointY: 0 }; + case 'bottom': return { focalPointX: 0.5, focalPointY: 1 }; + } + + const [focalX, focalY] = key.split(' '); + if (focalX && focalY) { + return { + focalPointX: convertPercentToDecimal(focalX), + focalPointY: convertPercentToDecimal(focalY) + }; + } + + // Else return center + return { focalPointX: .5, focalPointY: .5 }; +}; + class BetterImg extends Component { erd = null; @@ -38,7 +64,9 @@ class BetterImg extends Component { static propTypes = { src: PropTypes.string, width: PropTypes.number, - height: PropTypes.number.isRequired, + height: PropTypes.number, + scale: PropTypes.number, + focalPoint: PropTypes.string, resizeMode: PropTypes.oneOf([ 'cover', 'contain', @@ -47,7 +75,10 @@ class BetterImg extends Component { ]), } - static defaultProps = {} + static defaultProps = { + scale: 1, + focalPoint: 'center', + } state = { imgWidth: 0, @@ -92,7 +123,10 @@ class BetterImg extends Component { render() { // If no resizeMode is provided, be normal - if (!this.props.resizeMode) return (); + if (!this.props.resizeMode) { + const imgProps = _.omit(this.props, ['focalPoint', 'resizeMode', 'scale']); + return (); + } // If props.width is provide, use it, else use containerWidth for calculation const containerWidth = this.props.width || this.state.containerWidth; @@ -109,19 +143,33 @@ class BetterImg extends Component { border: '1px solid black', }; - // Calcualte Scale + // 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; + } + + // Focal Point (cover only) + let focalPointX = .5; + let focalPointY = .5; + if (resizeMode === 'cover') { + let focalPoint = mapFocalPointProps(this.props.focalPoint); + focalPointX = focalPoint.focalPointX; + focalPointY = focalPoint.focalPointY; + } - // Center by default - let x = .5 * (containerWidth - imgWidth); - let y = .5 * (containerHeight - imgHeight); + // Calculate X,Y + let x = focalPointX * (containerWidth - scaleX * imgWidth); + let y = focalPointY * (containerHeight - scaleY * imgHeight); const imgStyle = { - WebkitTransform: `translate3d(${x}px, ${y}px, 0) scaleX(${scaleX}) scaleY(${scaleY})`, - transform: `translate3d(${x}px, ${y}px, 0) scaleX(${scaleX}) scaleY(${scaleY})`, + WebkitTransform: `translate3d(${x}px, ${y}px, 0) scale(${scaleX}, ${scaleY})`, + transform: `translate3d(${x}px, ${y}px, 0) scale(${scaleX}, ${scaleY})`, + transformOrigin: '0% 0%', } - const imgProps = _.omit(this.props, ['width', 'height']); + const imgProps = _.omit(this.props, ['width', 'height', 'focalPoint', 'scale', 'resizeMode']); return (
this.container = container}>