diff --git a/.gitignore b/.gitignore index 4152a05..b7dab5e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ node_modules -build -public \ No newline at end of file +build \ No newline at end of file diff --git a/Docs/Api.md b/Docs/Api.md index c3fb690..5a96d6d 100644 --- a/Docs/Api.md +++ b/Docs/Api.md @@ -410,5 +410,48 @@ disable the web worker and process the image in the main thread (not recommended If you disable the web worker, you will need to add [this](https://github.com/nitin42/react-imgpro/blob/master/src/jimp.min.js) file in your `index.html` in order to access `Jimp` instance. +### disableRerender +disable the process image in re-render by options changed (recommended use with worker) + +**Type** - `boolean` + +**Default** - `false` + +**Example** - + +```jsx + +``` + +### customCdn +support you can add custom cdn for jimp + + +**Type** - `string` + +**Example** - + +```jsx + +``` + +### onProcessFinish + +**Type** - `function` + +**Example** - + +a callback on process finished + +```jsx + { + this.setState({ + isProcessing: false + }); + }} +/> +``` diff --git a/public/App.js b/public/App.js index cae6fab..46799cf 100644 --- a/public/App.js +++ b/public/App.js @@ -1,14 +1,17 @@ import React, { Component } from 'react'; import { render } from 'react-dom'; -import ProcessImage from '../build/main.js'; +import ProcessImage from '../src'; -const src = 'https://lh3.ggpht.com/rd52IsX4tX3ManFjv1bTM0eA21CblZ3_1tKul300NHNNqYDoXr-x3qwuiYbF_Ae450RX=h900'; +const src = 'http://orscxqn8h.bkt.clouddn.com/18-3-3/943334.jpg'; class App extends Component { state = { src: '', - err: '' + err: '', + sepia: true, + mixAmount: 10, + isProcessing: false }; render() { @@ -16,18 +19,44 @@ class App extends Component {
{ + this.setState({ + isProcessing: false + }); + }} colors={{ mix: { - color: 'purple', - amount: 10 - }, - saturate: 10, - lighten: 20 + color: 'mistyrose', + amount: this.state.mixAmount + } }} - processedImage={(src, err) => this.setState({ src, err })} /> + + +
); } @@ -37,6 +66,6 @@ render(, document.getElementById('root')); /** * processImage prop (validation) - * - * - */ \ No newline at end of file + * + * + */ diff --git a/src/components/ProcessImage.js b/src/components/ProcessImage.js index 182f8f6..ef6dcf3 100644 --- a/src/components/ProcessImage.js +++ b/src/components/ProcessImage.js @@ -54,6 +54,16 @@ class ProcessImage extends Component { ); }; + componentDidUpdate = () => { + if (this.props.image && !this.props.disableRerender) { + if (typeof Worker !== 'undefined' && !this.props.disableWebWorker) { + this.sendPropsToWorker(this.props, this.worker); + } else { + this.processInMainThread(this.props); + } + } + }; + componentWillUnmount = () => { this.worker !== null ? this.worker.terminate() : null; @@ -109,8 +119,13 @@ class ProcessImage extends Component { processInMainThread = props => { ROOT.read(props.image).then(image => { processImage(image, props, ROOT).getBase64(ROOT.AUTO, (err, src) => { - this.setState({ src, err }); - this.passPropsToParent(props, src, err); + if (this.state.src !== src || this.state.err !== err) { + this.setState({ src, err }); + this.passPropsToParent(props, src, err); + if (typeof props.onProcessFinish === 'function') { + props.onProcessFinish(); + } + } }); }); }; @@ -118,9 +133,15 @@ class ProcessImage extends Component { processInWebWorker = (worker, props, storageReference) => { if (worker !== null) { worker.onmessage = e => { - this.setState({ src: e.data.src, err: e.data.err }); - setItem('placeholder', e.data.src, storageReference); - this.passPropsToParent(props, e.data.src, e.data.err); + // avoid loop + if (e.data.src !== this.state.src || e.data.err !== this.state.err) { + this.setState({ src: e.data.src, err: e.data.err }); + setItem('placeholder', e.data.src, storageReference); + this.passPropsToParent(props, e.data.src, e.data.err); + if (typeof props.onProcessFinish === 'function') { + props.onProcessFinish(); + } + } }; } }; @@ -159,7 +180,6 @@ class ProcessImage extends Component { render() { const { src } = this.state; const restProps = getImageProps(this.props); - return this.showImage(src, this.props, restProps); } } diff --git a/src/utils/propsFactory.js b/src/utils/propsFactory.js index d3e967d..5d7868b 100644 --- a/src/utils/propsFactory.js +++ b/src/utils/propsFactory.js @@ -76,6 +76,9 @@ const getImageProps = props => { processedImage, storage, disableWebWorker, + disableRerender, + customCdn, + onProcessFinish, ...rest } = props; diff --git a/src/validators/props.js b/src/validators/props.js index 5c2f22a..127746f 100644 --- a/src/validators/props.js +++ b/src/validators/props.js @@ -83,7 +83,10 @@ const MainPropTypes = { resize: resizePropType, sepia: PropTypes.bool, scale: PropTypes.number, - scaleToFit: scaleToFitPropType + scaleToFit: scaleToFitPropType, + disableRerender: PropTypes.bool, + customCdn: PropTypes.string, + onProcessFinish: PropTypes.func }; export default MainPropTypes; diff --git a/src/worker.js b/src/worker.js index 6935b35..8147368 100644 --- a/src/worker.js +++ b/src/worker.js @@ -1,17 +1,25 @@ const processImage = require('./utils/options'); +const defaultCdn = + 'https://cdn.rawgit.com/nitin42/5fef1095f281aa0cdf36ad6e5c460c9a/raw/359af525cb063ac002ebcf39274fb6c7d12e2f3e/jimp.min.js'; module.exports = function worker(self) { self.onmessage = function(e) { - importScripts( - 'https://cdn.rawgit.com/nitin42/5fef1095f281aa0cdf36ad6e5c460c9a/raw/359af525cb063ac002ebcf39274fb6c7d12e2f3e/jimp.min.js' - ); + // how to ensure Jimp can work? + try { + if (!Jimp) { + } + } catch (error) { + const { customCdn } = e.data; + const cdn = customCdn ? customCdn : defaultCdn; + importScripts(cdn); + } + Jimp.read(e.data.image).then(function(image) { processImage(image, e.data.props, Jimp).getBase64(Jimp.AUTO, function( err, src ) { self.postMessage({ src, err }); - self.close(); }); }); };