Issues (6)

src/coverimage.js (6 issues)

1
const elementResizeDetectorMaker = require('element-resize-detector');
2
3
class CoverImage {
4
	constructor(el, cb) {
5
		const _this = this;
6
7
		_this.$el = el ? el : window;
8
		_this.$img = _this.getElementForSizing();
9
		_this.disableOnMobile = _this.$el.dataset['cover-image-mobile'] === 'false';
10
		_this.cb = cb || (() => {
11
			//DEBUG console.log("Default callback");
12
		});
13
14
		_this.positioning = {
15
			x : 0.5,
16
			y : 0.5
17
		};
18
		_this.options = {
19
			parallax : _this.$el.dataset.coverImageParallax === 'true'
20
		};
21
22
		if (!_this.$img) {
23
			console.log('Error:', 'no image found', _this.$img );
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
24
			return;
25
		}
26
27
		_this.imageWidth = _this.$img.getAttribute('width');
28
		_this.imageHeight = _this.$img.getAttribute('height');
29
30
		// If the image doesn't have harcoded width|height
31
		// attributes then load the image to calculate
32
		// the dimensions
33
		if (!_this.imageWidth || !_this.imageHeight) {
34
			console.log('No dimensions found. Generating image:', _this.$img.src)
35
			_this.img = new Image();
0 ignored issues
show
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
36
			_this.img.src = _this.$img.src;
37
38
			_this.imageWidth = _this.img.width;
39
			_this.imageHeight = _this.img.height;
40
		}
41
42
		if ( _this.disableOnMobile && window.innerWidth < 480 ) {
43
			return;
44
		}
45
46
		_this.elementDimensions = {
47
			height : _this.$el.clientHeight,
48
			width  : _this.$el.clientWidth
49
		};
50
51
		_this.$el.style = `
52
			overflow : hidden;
53
			position : relative;
54
		`;
55
56
		if (!_this.$img) {
57
			// TODO: Implement load
58
			setTimeout( () => {
59
				new CoverImage( _this.$el );
0 ignored issues
show
Unused Code Best Practice introduced by
The object created with new CoverImage(_this.$el) is not used but discarded. Consider invoking another function instead of a constructor if you are doing this purely for side effects.
Loading history...
60
			}, 1000);
61
62
		} else {
63
			_this.resizeImage();
64
		}
65
66
		_this.$img.addEventListener('load', () => {
67
			_this.resizeImage();
68
		}, false);
69
70
		_this.$el.addEventListener('transitionend', () => {
71
			_this.resizeImage();
72
		}, false)
73
74
		var erd = elementResizeDetectorMaker({
75
			strategy: 'scroll'
76
		});
77
78
		erd.listenTo(_this.$el, () => {
79
			_this.resizeImage();
80
		})
81
82
		_this.$el.addEventListener('animationend', () => {
83
			_this.resizeImage();
84
		}, false)
85
86
		window.addEventListener('resize', () => {
87
			_this.resizeImage();
88
		}, true);
89
90
		window.addEventListener('ci.resize', () => {
91
			_this.resizeImage();
92
		}, true);
93
94
		if (_this.options.parallax) {
95
			_this.draw();
96
		}
97
	}
98
99
	/**
100
	 * Parallax FX
101
	 *
102
	 */
103
	draw() {
104
		const _this = this;
105
		const friction = 0.5;
106
		const imageOffsetX = document.body.scrollTop * friction;
107
		const imageOffsetY = document.body.scrollTop * friction;
108
		const maximumMovementY = ( _this.imageDimensions.height - _this.elementDimensions.height) * _this.positioning.y;
109
		const maximumMovementX = ( _this.imageDimensions.width - _this.elementDimensions.width) * _this.positioning.x;
110
111
		if ( maximumMovementX > 0 ) {
112
			if (imageOffsetX < maximumMovementX ) {
113
				// console.log('New position:', maximumMovementX - imageOffsetX);
114
				_this.$img.css({
115
					'transform': `translateX(${maximumMovementX - imageOffsetX}px)`
116
				});
117
			}
118
119
		} else {
120
			if ( imageOffsetY < maximumMovementY ) {
121
				_this.$img.css('transform', `translateY(${maximumMovementY - imageOffsetY}px)`);
122
			}
123
		}
124
125
		window.requestAnimationFrame(() => {
126
			_this.draw();
127
		});
128
	}
129
130
	/**
131
	 *
132
	 * @return DOM Element
133
	 */
134
	getElementForSizing() {
135
		let _this = this;
136
		let selector = _this.$el.dataset['coverImageEl'];
137
138
		if ( selector )  {
139
140
			console.log( 'Element selector Present', _this.$el.find( selector ) );
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
141
142
			return _this.$el.find( selector ) ? _this.$el.find( selector ) : _this.$el.find('img');
143
		}
144
145
		return _this.$el.querySelector('img');
146
	}
147
148
	resizeImage() {
149
		const _this = this;
150
		const elementWidth = _this.$el.clientWidth;
151
		const elementHeight = _this.$el.clientHeight;
152
		const dimensions = _this.coverDimensions( _this.imageWidth, _this.imageHeight, elementWidth, elementHeight );
153
154
		_this.imageDimensions = dimensions;
155
156
		if ( isNaN( dimensions.width ) ) {
157
			console.log('Failed to calculate image sizes.');
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
158
		}
159
160
		_this.setImageSize();
161
	}
162
163
	setImageSize() {
164
		const _this = this;
165
166
		_this.$img.width = _this.imageDimensions.width;
167
		_this.$img.height = _this.imageDimensions.height;
168
169
		let transform = _this.getTransform(
170
				( _this.$el.clientWidth - _this.imageDimensions.width) * _this.positioning.y,
171
				( _this.$el.clientHeight - _this.imageDimensions.height) * _this.positioning.x
172
			);
173
174
		_this.$img.style = `
175
			position: absolute;
176
			width: ${_this.imageDimensions.width};
177
			height: ${_this.imageDimensions.height};
178
			transform: ${transform};
179
			max-width: none;
180
		`;
181
182
		_this.$img.classList.add('ci--sized');
183
		_this.cb();
184
	}
185
186
	getTransform(x, y) {
187
		return `translate3d(${x}px,${y}px,0)`;
188
	}
189
190
	coverDimensions(child_w, child_h, container_w, container_h) {
191
		const scale_factor = this.max( container_w / child_w, container_h / child_h );
192
193
		return {
194
			width: Math.ceil(child_w * scale_factor),
195
			height: Math.ceil(child_h * scale_factor)
196
		};
197
	}
198
199
	containDimensions(child_w, child_h, container_w, container_h) {
200
		const scale_factor = this.min( container_w / child_w, container_h / child_h );
201
202
		return {
203
			width: child_w * scale_factor,
204
			height: child_h * scale_factor
205
		};
206
	}
207
208
	min(a, b) {
209
		return a > b ? b : a;
210
	}
211
212
	max(a, b) {
213
		return a > b ? a : b;
214
	}
215
}
216
217
const elems = document.body.querySelectorAll('[data-cover-image]');
218
219
elems.forEach(el => {
220
	new CoverImage( el );
0 ignored issues
show
Unused Code Best Practice introduced by
The object created with new CoverImage(el) is not used but discarded. Consider invoking another function instead of a constructor if you are doing this purely for side effects.
Loading history...
221
});