Skip to content
This repository was archived by the owner on Jan 26, 2024. It is now read-only.

Commit 72b1a81

Browse files
authored
Merge pull request #25 from benox3/bundling
Fix bundling and loading of images
2 parents f682d9a + 7451750 commit 72b1a81

File tree

5 files changed

+150
-143
lines changed

5 files changed

+150
-143
lines changed

lib/client/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
22
import Image from '../common/Image';
33
import shallowCompare from 'react-addons-shallow-compare';
44

5-
export default class ImageClient extends Component {
5+
export default class ImageBase extends Component {
66
shouldComponentUpdate(nextProps, nextState) {
77
return shallowCompare(this, nextProps, nextState);
88
}

lib/common/Pic.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import React, { Component } from 'react';
2+
import getResponsiveImage from '../utils/getResponsiveImage';
3+
import debounce from '../utils/debounce';
4+
import isElementInView from '../utils/isElementInView';
5+
import ImageBase from '../server/index';
6+
7+
/**
8+
* Pic Component
9+
*/
10+
export default class Pic extends Component {
11+
constructor(props) {
12+
super(props);
13+
this.state = {
14+
image: props.images[props.defaultIndex],
15+
noScriptImage: props.noscriptIndex ?
16+
props.images[props.noScriptIndex] :
17+
props.images[props.images.length-1],
18+
isBlurred: props.shouldBlur
19+
};
20+
21+
this.setResponsiveImage = this.setResponsiveImage.bind(this);
22+
this.loadHandler = this.loadHandler.bind(this);
23+
}
24+
componentDidMount() {
25+
this.loadHandler();
26+
}
27+
28+
componentWillUnmount() {
29+
window.removeEventListener('scroll', debounce(() => {
30+
this.inViewHandler();
31+
}, 150));
32+
33+
window.removeEventListener('resize', debounce(this.setResponsiveImage, 150));
34+
}
35+
36+
loadHandler() {
37+
// set optimal image if in view or if elected to render out of view on mount
38+
this.props.renderOutOfView ? this.setResponsiveImage() : this.inViewHandler();
39+
40+
// set responsive image on scroll
41+
window.addEventListener('scroll', debounce(() => {
42+
this.inViewHandler();
43+
}, 150));
44+
45+
// set responsive image on resize
46+
window.addEventListener('resize', debounce(this.setResponsiveImage, 150));
47+
}
48+
49+
inViewHandler() {
50+
if (isElementInView(this.refs.base)) {
51+
this.setResponsiveImage();
52+
}
53+
}
54+
55+
/**
56+
* Set the optimal image src
57+
*/
58+
setResponsiveImage() {
59+
try {
60+
const parent = this.refs.base.parentNode;
61+
const imageSlotWidth = parent.getBoundingClientRect().width;
62+
63+
const responsiveImage = getResponsiveImage(
64+
imageSlotWidth,
65+
this.props.images,
66+
this.state.image
67+
);
68+
this.setState({
69+
image: responsiveImage,
70+
isBlurred: false
71+
});
72+
} catch (e) {
73+
// failed to update image
74+
}
75+
}
76+
77+
render() {
78+
if (!this.state.image) {
79+
return null;
80+
}
81+
82+
return (
83+
<div ref='base' style={this.props.baseStyle} onLoad={this.loadHandler}>
84+
<ImageBase {...this.props} {...this.state} />
85+
</div>
86+
);
87+
}
88+
}
89+
90+
/** Default Props */
91+
Pic.defaultProps = {
92+
alt: '',
93+
defaultIndex: 0,
94+
shouldBlur: true,
95+
blurAmmount: '10px',
96+
baseStyle: {
97+
position: 'relative',
98+
margin: '-5px',
99+
overflow: 'hidden'
100+
},
101+
imgStyle: {
102+
margin: '0 auto',
103+
maxWidth: '100%',
104+
width: '100%'
105+
},
106+
images: [],
107+
renderOutOfView: false
108+
};
109+
110+
/** Prop Types */
111+
Pic.propTypes = {
112+
// The collection of images
113+
images: function(props, propName, componentName) {
114+
const collectionLength = props[propName].length;
115+
if (collectionLength <= 0) {
116+
return new Error(
117+
'No images are found in `' + propName + '` supplied to ' +
118+
componentName + '. Validation failed.'
119+
);
120+
}
121+
for (let i = 0; i < collectionLength; i++) {
122+
const imageObj = props[propName][i];
123+
if (typeof imageObj.url !== 'string') {
124+
return new Error(
125+
'Invalid or no url found in `' + propName + '` supplied to ' +
126+
componentName + '. Validation failed.'
127+
);
128+
}
129+
if (typeof imageObj.width !== 'number') {
130+
return new Error(
131+
'Invalid or no width found in`' + propName + '` supplied to ' +
132+
componentName + '. Validation failed.'
133+
);
134+
}
135+
}
136+
},
137+
defaultIndex: React.PropTypes.number, // The default image to render
138+
noscriptIndex: React.PropTypes.number, // The default image to render on noscript
139+
alt: React.PropTypes.string,
140+
imgStyle: React.PropTypes.object,
141+
baseStyle: React.PropTypes.object,
142+
shouldBlur: React.PropTypes.bool,
143+
blurAmmount: React.PropTypes.string,
144+
renderOutOfView: React.PropTypes.bool
145+
};

lib/index.js

Lines changed: 2 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,3 @@
1-
import React, { Component } from 'react';
2-
import getResponsiveImage from './utils/getResponsiveImage';
3-
import debounce from './utils/debounce';
4-
import isElementInView from './utils/isElementInView';
5-
import ImageBase from './server/';
1+
import Pic from './common/Pic';
62

7-
/**
8-
* Pic Component
9-
*/
10-
export default class Pic extends Component {
11-
constructor(props) {
12-
super(props);
13-
this.state = {
14-
image: props.images[props.defaultIndex],
15-
noScriptImage: props.noscriptIndex ?
16-
props.images[props.noScriptIndex] :
17-
props.images[props.images.length-1],
18-
isBlurred: props.shouldBlur
19-
};
20-
21-
this.setResponsiveImage = this.setResponsiveImage.bind(this);
22-
}
23-
24-
componentDidMount() {
25-
// set optimal image if in view or if elected to render out of view on mount
26-
this.props.renderOutOfView ? this.setResponsiveImage(): this.inViewHandler();
27-
28-
// set responsive image on scroll
29-
window.addEventListener('scroll', debounce(() => {
30-
this.inViewHandler();
31-
}, 150));
32-
33-
// set responsive image on resize
34-
window.addEventListener('resize', debounce(this.setResponsiveImage, 150));
35-
}
36-
37-
componentWillUnmount() {
38-
window.removeEventListener('scroll', debounce(() => {
39-
this.inViewHandler();
40-
}, 150));
41-
42-
window.removeEventListener('resize', debounce(this.setResponsiveImage, 150));
43-
}
44-
45-
inViewHandler() {
46-
if (isElementInView(this.refs.base)) {
47-
this.setResponsiveImage();
48-
}
49-
}
50-
51-
/**
52-
* Set the optimal image src
53-
*/
54-
setResponsiveImage() {
55-
try {
56-
const parent = this.refs.base.parentNode;
57-
const imageSlotWidth = parent.getBoundingClientRect().width;
58-
59-
const responsiveImage = getResponsiveImage(
60-
imageSlotWidth,
61-
this.props.images,
62-
this.state.image
63-
);
64-
this.setState({
65-
image: responsiveImage,
66-
isBlurred: false
67-
});
68-
} catch (e) {
69-
// failed to update image
70-
}
71-
}
72-
73-
render() {
74-
if (!this.state.image) {
75-
return null;
76-
}
77-
78-
return (
79-
<div ref='base' style={this.props.baseStyle}>
80-
<ImageBase {...this.props} {...this.state} />
81-
</div>
82-
);
83-
}
84-
}
85-
86-
/** Default Props */
87-
Pic.defaultProps = {
88-
alt: '',
89-
defaultIndex: 0,
90-
shouldBlur: true,
91-
blurAmmount: '10px',
92-
baseStyle: {
93-
position: 'relative',
94-
margin: '-5px',
95-
overflow: 'hidden'
96-
},
97-
imgStyle: {
98-
margin: '0 auto',
99-
maxWidth: '100%',
100-
width: '100%'
101-
},
102-
images: [],
103-
renderIfOutOfView: false
104-
};
105-
106-
/** Prop Types */
107-
Pic.propTypes = {
108-
// The collection of images
109-
images: function(props, propName, componentName) {
110-
const collectionLength = props[propName].length;
111-
if (collectionLength <= 0) {
112-
return new Error(
113-
'No images are found in `' + propName + '` supplied to ' +
114-
componentName + '. Validation failed.'
115-
);
116-
}
117-
for (let i = 0; i < collectionLength; i++) {
118-
const imageObj = props[propName][i];
119-
if (typeof imageObj.url !== 'string') {
120-
return new Error(
121-
'Invalid or no url found in `' + propName + '` supplied to ' +
122-
componentName + '. Validation failed.'
123-
);
124-
}
125-
if (typeof imageObj.width !== 'number') {
126-
return new Error(
127-
'Invalid or no width found in`' + propName + '` supplied to ' +
128-
componentName + '. Validation failed.'
129-
);
130-
}
131-
}
132-
},
133-
defaultIndex: React.PropTypes.number, // The default image to render
134-
noscriptIndex: React.PropTypes.number, // The default image to render on noscript
135-
alt: React.PropTypes.string,
136-
imgStyle: React.PropTypes.object,
137-
baseStyle: React.PropTypes.object,
138-
shouldBlur: React.PropTypes.bool,
139-
blurAmmount: React.PropTypes.string,
140-
renderOutOfView: React.PropTypes.bool
141-
};
3+
export default Pic;

lib/server/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import NoScriptImg from './NoScriptImg';
33
import Image from '../common/Image';
44
import shallowCompare from 'react-addons-shallow-compare';
55

6-
export default class ImageServer extends Component {
6+
export default class ImageBase extends Component {
77
shouldComponentUpdate(nextProps, nextState) {
88
return shallowCompare(this, nextProps, nextState);
99
}

webpack.config.commonjs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const config = {
77
],
88
devtool: 'source-map',
99
output: {
10-
libraryTarget: 'commonjs',
10+
libraryTarget: 'commonjs2',
1111
library: 'Pic'
1212
},
1313
target: 'node',

0 commit comments

Comments
 (0)