PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.4.2
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.4.2
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / assets / js / jquery.twentytwenty.js

jquery.twentytwenty.js in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 1.4.2, at assets/js/jquery.twentytwenty.js

471 lines 17.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function(window, $, undefined){
2
3 $.fn.twentytwenty = function(options, callback) {
4 var options = $.extend({
5 handlePosition : 0.5,
6 orientation : 'horizontal',
7 labelBefore : 'Before',
8 labelAfter : 'After'
9 }
10 , options);
11 return this.each(function() {
12
13 var sliderPct = options.handlePosition,
14 $container = $(this),
15 sliderOrientation = options.orientation,
16 beforeDirection = (sliderOrientation === 'vertical') ? 'down' : 'left',
17 afterDirection = (sliderOrientation === 'vertical') ? 'up' : 'right',
18 $beforeImg = $container.find('img:first'),
19 $afterImg = $container.find('img:last');
20
21
22 $container.wrap('<div class="twentytwenty-wrapper twentytwenty-' + sliderOrientation + '"></div>');
23 $container.append('<div class="twentytwenty-overlay"></div>');
24 $container.append('<div class="twentytwenty-handle"></div>');
25
26 var $slider = $container.find('.twentytwenty-handle');
27
28 $slider.append('<span class="twentytwenty-' + beforeDirection + '-arrow"></span>');
29 $slider.append('<span class="twentytwenty-' + afterDirection + '-arrow"></span>');
30 $container.addClass('twentytwenty-container');
31 $beforeImg.addClass('twentytwenty-before');
32 $afterImg.addClass('twentytwenty-after');
33
34 var $overlay = $container.find('.twentytwenty-overlay');
35
36 $overlay.append('<div class="twentytwenty-labels twentytwenty-before-label"><span class="twentytwenty-label-content">' + options.labelBefore + '</span></div>');
37 $overlay.append('<div class="twentytwenty-labels twentytwenty-after-label"><span class="twentytwenty-label-content">' + options.labelAfter + '</span></div>');
38
39
40 // some usefull function and vars declarations
41
42 var calcOffset = function(dimensionPct) {
43 var w = $beforeImg.width();
44 var h = $beforeImg.height();
45 return {
46 w: w+"px",
47 h: h+"px",
48 cw: (dimensionPct*w)+"px",
49 ch: (dimensionPct*h)+"px"
50 };
51 },
52
53 adjustContainer = function( offset ) {
54 // make it dynamic, in case "before" image change
55 var $beforeImg = $container.find('.twentytwenty-before');
56
57 if ( sliderOrientation === 'vertical' ) {
58 $beforeImg.css( 'clip', 'rect(0,' + offset.w + ',' + offset.ch + ',0)' );
59 }
60 else {
61 $beforeImg.css( 'clip', 'rect(0,' + offset.cw + ',' + offset.h + ',0)' );
62 }
63 $container.css( 'height', offset.h );
64
65 if ( typeof callback === 'function' ) {
66 callback();
67 }
68 },
69 adjustSlider = function( pct ) {
70 var offset = calcOffset(pct);
71 $slider.css( ( sliderOrientation === 'vertical' ) ? 'top' : 'left', ( sliderOrientation === 'vertical' ) ? offset.ch : offset.cw );
72 adjustContainer( offset );
73 },
74 offsetX = 0,
75 offsetY = 0,
76 imgWidth = 0,
77 imgHeight = 0;
78
79 $(window).on('resize.twentytwenty', function(e) {
80 adjustSlider( sliderPct );
81 });
82
83 $slider.on('movestart', function(e) {
84 if ( ( ( e.distX > e.distY && e.distX < -e.distY ) || ( e.distX < e.distY && e.distX > -e.distY ) ) && sliderOrientation !== 'vertical' ) {
85 e.preventDefault();
86 }
87 else if ( ( ( e.distX < e.distY && e.distX < -e.distY ) || ( e.distX > e.distY && e.distX > -e.distY ) ) && sliderOrientation === 'vertical' ) {
88 e.preventDefault();
89 }
90 $container.addClass('active');
91 offsetX = $container.offset().left;
92 offsetY = $container.offset().top;
93 imgWidth = $beforeImg.width();
94 imgHeight = $beforeImg.height();
95 });
96
97 $slider.on('moveend', function(e) {
98 $container.removeClass('active');
99 });
100
101 $slider.on('move', function(e) {
102 if ( $container.hasClass('active') ) {
103
104 sliderPct = ( sliderOrientation === 'vertical' ) ? ( e.pageY-offsetY )/imgHeight : ( e.pageX-offsetX )/imgWidth;
105
106 if ( sliderPct < 0 ) {
107 sliderPct = 0;
108 }
109 if ( sliderPct > 1 ) {
110 sliderPct = 1;
111 }
112 adjustSlider( sliderPct );
113 }
114 });
115
116 $container.find('img').on('mousedown', function(event) {
117 event.preventDefault();
118 });
119
120 $(window).trigger('resize.twentytwenty');
121 });
122 };
123
124 })(window, jQuery);
125
126 /**
127 * Twentytwenty Imagify Init
128 */
129 (function(window, $, undefined){
130
131 /*
132 * Mini chart
133 *
134 * @param {element} canvas
135 */
136 var draw_me_a_chart = function ( canvas ) {
137 canvas.each(function(){
138 var the_value = parseInt( $(this).closest('.imagify-chart').next('.imagify-chart-value').text() ),
139 overviewData = [
140 {
141 value: the_value,
142 color: '#00B3D3'
143 },
144 {
145 value: 100 - the_value,
146 color: '#D8D8D8'
147 }
148 ],
149 overviewDoughnut = new Chart( $(this)[0].getContext('2d')).Doughnut(overviewData, {
150 segmentStrokeColor : '#2A2E3C',
151 segmentStrokeWidth : 1,
152 animateRotate : true,
153 percentageInnerCutout: 60,
154 tooltipEvents : []
155 });
156 });
157 };
158
159 $('.imagify-visual-comparison-btn').on('click', function(){
160
161 if ( $('.twentytwenty-wrapper').length === 1) {
162 return;
163 }
164
165 $( $(this).data('target') ).find('.imagify-modal-content').css('width', ($(window).outerWidth()*0.95) + 'px');
166
167 if ( $('.twentytwenty-container').length > 0 && $(window).outerWidth() > 800 ) {
168
169 var $tt = $('.twentytwenty-container'),
170 imgs_loaded = 0,
171 loader = $tt.data('loader'),
172 label_original = $tt.data('label-original'),
173 label_normal = $tt.data('label-normal'),
174 label_aggressive = $tt.data('label-aggressive'),
175 label_ultra = $tt.data('label-ultra'),
176
177 original_label = $tt.data('original-label').replace(/\*\*/, '<strong>').replace(/\*\*/, '</strong>'),
178 original_alt = $tt.data('original-alt'),
179 original_src = $tt.data('original-img'),
180 original_dim = $tt.data('original-dim').split('x'),
181
182 normal_label = $tt.data('normal-label').replace(/\*\*/, '<strong>').replace(/\*\*/, '</strong>'),
183 normal_alt = $tt.data('normal-alt'),
184 normal_src = $tt.data('normal-img'),
185 normal_dim = $tt.data('normal-dim').split('x'),
186
187 aggressive_label = $tt.data('aggressive-label').replace(/\*\*/, '<strong>').replace(/\*\*/, '</strong>'),
188 aggressive_alt = $tt.data('aggressive-alt'),
189 aggressive_src = $tt.data('aggressive-img'),
190 aggressive_dim = $tt.data('aggressive-dim').split('x'),
191
192 ultra_label = $tt.data('ultra-label').replace(/\*\*/, '<strong>').replace(/\*\*/, '</strong>'),
193 ultra_alt = $tt.data('ultra-alt'),
194 ultra_src = $tt.data('ultra-img'),
195 ultra_dim = $tt.data('ultra-dim').split('x'),
196
197 tt_before_buttons = '<span class="twentytwenty-duo-buttons twentytwenty-duo-left">' +
198 '<button type="button" class="imagify-comparison-original selected" data-img="original">' + label_original + '</button>' +
199 '<button type="button" class="imagify-comparison-normal" data-img="normal">' + label_normal + '</button>' +
200 '<button type="button" class="imagify-comparison-aggressive" data-img="aggressive">' + label_aggressive + '</button>' +
201 '</span>',
202 tt_after_buttons = '<span class="twentytwenty-duo-buttons twentytwenty-duo-right">' +
203 '<button type="button" class="imagify-comparison-normal" data-img="normal">' + label_normal + '</button>' +
204 '<button type="button" class="imagify-comparison-aggressive" data-img="aggressive">' + label_aggressive + '</button>' +
205 '<button type="button" class="imagify-comparison-ultra selected" data-img="ultra">' + label_ultra + '</button>' +
206 '</span>';
207
208 // loader
209 $tt.before('<img class="loader" src="' + loader + '" alt="Loading…" width="64" height="64">')
210
211 // add switchers button only if needed
212 // should be more locally integrate...
213 var duo_buttons = ( $('.twentytwenty-left-buttons').lenght ) ? tt_before_buttons + tt_after_buttons : '';
214 // should be more locally integrate...
215 $('.twentytwenty-left-buttons').append(tt_before_buttons);
216 $('.twentytwenty-right-buttons').append(tt_after_buttons);
217
218 // add images to 50/50 area
219 $tt.closest('.imagify-modal-content').addClass('loading').find('.twentytwenty-container').append(
220 '<img class="img-original" alt="' + original_alt + '" width="' + original_dim[0] + '" height="' + original_dim[1] + '">' +
221 '<img class="img-normal" alt="' + normal_alt + '" width="' + normal_dim[0] + '" height="' + normal_dim[1] + '">' +
222 '<img class="img-aggressive" alt="' + aggressive_alt + '" width="' + aggressive_dim[0] + '" height="' + aggressive_dim[1] + '">' +
223 '<img class="img-ultra" alt="' + ultra_alt + '" width="' + ultra_dim[0] + '" height="' + ultra_dim[1] + '">' +
224 duo_buttons
225 );
226
227 // load image original
228 $('.img-original').on('load', function(){
229 imgs_loaded++;
230 }).attr('src', original_src);
231
232 // load image normal
233 $('.img-normal').on('load', function(){
234 imgs_loaded++;
235 }).attr('src', normal_src);
236
237 // load image aggressive
238 $('.img-aggressive').on('load', function(){
239 imgs_loaded++;
240 }).attr('src', aggressive_src);
241
242 // load image ultra
243 $('.img-ultra').on('load', function(){
244 imgs_loaded++;
245 }).attr('src', ultra_src);
246
247 var twenty_me = setInterval(function(){
248 if ( imgs_loaded === 4 ) {
249 $tt.twentytwenty({
250 handlePosition: 0.6,
251 orientation: 'horizontal',
252 labelBefore: original_label,
253 labelAfter: ultra_label
254 }, function(){
255 // fires on initialisation & each time the handle is moving
256 if ( ! $tt.closest('.imagify-modal-content').hasClass('loaded') ) {
257 $tt.closest('.imagify-modal-content').removeClass('loading').addClass('loaded');
258 draw_me_a_chart( $('.imagify-level-ultra').find('.imagify-chart').find('canvas') );
259 }
260 });
261 clearInterval( twenty_me );
262 twenty_me = null;
263 }
264 }, 75);
265
266 // on click on button choices
267
268 $('.imagify-comparison-title').on('click', '.twentytwenty-duo-buttons button:not(.selected)', function(e){
269
270 e.stopPropagation();
271
272 var $_this = $(this),
273 $container = $_this.closest('.imagify-comparison-title').nextAll('.twentytwenty-wrapper').find('.twentytwenty-container'),
274 side = $_this.closest('.twentytwenty-duo-buttons').hasClass('twentytwenty-duo-left') ? 'left' : 'right',
275 $other_side = side === 'left' ? $_this.closest('.imagify-comparison-title').find('.twentytwenty-duo-right') : $_this.closest('.imagify-comparison-title').find('.twentytwenty-duo-left'),
276 $duo = $_this.closest('.twentytwenty-duo-buttons').find('button'),
277 $img_before = $container.find('.twentytwenty-before'),
278 $img_after = $container.find('.twentytwenty-after'),
279 image = $_this.data('img');
280
281 // button coloration
282 $duo.removeClass('selected');
283 $_this.addClass('selected');
284
285 // other side action (to not compare same images)
286 if ( $other_side.find('.selected').data('img') === image ) {
287 $other_side.find('button:not(.selected)').eq(0).trigger('click');
288 }
289
290 // left buttons
291 if ( side === 'left' ) {
292 var clip_styles = $img_before.css('clip');
293 $img_before.attr('style', '');
294 $img_before.removeClass('twentytwenty-before');
295 $container.find( '.img-' + image ).addClass('twentytwenty-before').css('clip', clip_styles);
296 $('.twentytwenty-before-label').find('.twentytwenty-label-content').text( $container.data( image + '-label' ) );
297 $('.imagify-c-level.go-left').attr('aria-hidden', 'true').removeClass('go-left go-right');
298 $('.imagify-level-' + image).attr('aria-hidden', 'false').addClass('go-left');
299 }
300
301 // right buttons
302 if ( side === 'right' ) {
303 $img_after.removeClass('twentytwenty-after')
304 $container.find( '.img-' + image ).addClass('twentytwenty-after');
305 $('.twentytwenty-after-label').find('.twentytwenty-label-content').text( $container.data( image + '-label' ) );
306 $('.imagify-c-level.go-right').attr('aria-hidden', 'true').removeClass('go-left go-right');
307 $('.imagify-level-' + image).attr('aria-hidden', 'false').addClass('go-right');
308 }
309
310 draw_me_a_chart( $('.imagify-level-' + image).find('.imagify-chart').find('canvas') );
311
312 return false;
313
314 });
315 }
316
317 });
318
319 // Imagify comparison inside Media post visualization
320
321 if ( $('.post-php').find('.wp_attachment_image').find('.thumbnail').length > 0 ) {
322 var $ori_parent = $('.post-php').find('.wp_attachment_image'),
323 $thumbnail = $ori_parent.find('.thumbnail'),
324 thumb = { src: $thumbnail.prop('src'), width: $thumbnail.width(), height: $thumbnail.height() },
325 ori_source = { src: $('#imagify-full-original').val(), size: $('#imagify-full-original-size').val() },
326 $optimize_btn = $('#misc-publishing-actions').find('.misc-pub-imagify').find('.button-primary');
327
328 // if shown image > 300, use twentytwenty
329 if ( thumb.width > 300 && $('#imagify-full-original').length > 0 && $('#imagify-full-original').val() !== '' ) {
330
331 var imgs_loaded = 0,
332 filesize = $('.misc-pub-filesize').find('strong').text(),
333 saving = $('.imagify-data-item').find('.imagify-chart-value').text();
334
335 // create button to trigger
336 $('[id^="imgedit-open-btn-"]').before('<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-visual-comparison" id="imagify-start-comparison">' + imagifyTTT.labels.compare + '</button>')
337
338 // create modal box
339 $ori_parent.append(''
340 + '<div id="imagify-visual-comparison" class="imagify-modal" aria-hidden="true">'
341 + '<div class="imagify-modal-content loading">'
342 + '<div class="twentytwenty-container">'
343 + '<img class="imagify-img-before" alt="" width="' + thumb.width + '" height="' + thumb.height + '">'
344 + '<img class="imagify-img-after" alt="" width="' + thumb.width + '" height="' + thumb.height + '">'
345 + '</div>'
346 + '<div class="imagify-comparison-levels">'
347 + '<div class="imagify-c-level imagify-level-original go-left">'
348 + '<p class="imagify-c-level-row">'
349 + '<span class="label">' + imagifyTTT.labels.filesize + '</span>'
350 + '<span class="value level">' + ori_source.size + '</span>'
351 + '</p>'
352 + '</div>'
353 + '<div class="imagify-c-level imagify-level-optimized go-right">'
354 + '<p class="imagify-c-level-row">'
355 + '<span class="label">' + imagifyTTT.labels.filesize + '</span>'
356 + '<span class="value level">' + filesize + '</span>'
357 + '</p>'
358 + '<p class="imagify-c-level-row">'
359 + '<span class="label">' + imagifyTTT.labels.saving + '</span>'
360 + '<span class="value"><span class="imagify-chart"><span class="imagify-chart-container"><canvas id="imagify-consumption-chart-normal" width="15" height="15"></canvas></span></span><span class="imagify-chart-value">' + saving + '</span>%</span>'
361 + '</p>'
362 +'</div>'
363 + '</div>'
364 + '<button class="close-btn absolute" type="button"><i aria-hidden="true" class="dashicons dashicons-no-alt"></i><span class="screen-reader-text">' + imagifyTTT.labels.close + '</span></button>'
365 + '</div>'
366 + '</div>'
367 );
368
369 $('#imagify-start-comparison').on('click.imagify', function(){
370
371 var $modal = $( $(this).data('target') );
372
373 $modal.find('.imagify-modal-content').css({
374 'width' : ($(window).outerWidth()*0.95) + 'px',
375 'max-width' : thumb.width
376 });
377
378 // load before img
379 $('.imagify-img-before').on('load', function(){
380 imgs_loaded++;
381 }).attr('src', ori_source.src);
382
383 // load after img
384 $('.imagify-img-after').on('load', function(){
385 imgs_loaded++;
386 }).attr('src', thumb.src);
387
388 var $tt = $('.twentytwenty-container'),
389 check_load = setInterval( function(){
390
391 if ( imgs_loaded === 2 ) {
392 $tt.twentytwenty({
393 handlePosition: 0.3,
394 orientation: 'horizontal',
395 labelBefore: imagifyTTT.labels.original_l,
396 labelAfter: imagifyTTT.labels.optimized_l
397 }, function(){
398
399 var windowH = $(window).height(),
400 ttH = $('.twentytwenty-container').height(),
401 ttTop = $('.twentytwenty-wrapper').position().top;
402
403 if ( ! $tt.closest('.imagify-modal-content').hasClass('loaded') ) {
404 $tt.closest('.imagify-modal-content').removeClass('loading').addClass('loaded');
405 draw_me_a_chart( $('.imagify-level-optimized').find('.imagify-chart').find('canvas') );
406 }
407
408 // check if image height is to big
409 if ( windowH < ttH && ! $modal.hasClass('modal-is-too-high') ) {
410 $modal.addClass('modal-is-too-high');
411
412 var $handle = $modal.find('.twentytwenty-handle'),
413 $labels = $modal.find('.twentytwenty-label-content'),
414 $datas = $modal.find('.imagify-comparison-levels'),
415 datasH = $datas.outerHeight(),
416 handle_pos = ( windowH - ttTop - $handle.height() ) / 2,
417 labels_pos = ( windowH - ttTop * 3 - datasH );
418
419 $handle.css({
420 top: handle_pos
421 });
422 $labels.css({
423 top: labels_pos,
424 bottom: 'auto'
425 });
426 $modal.find('.twentytwenty-wrapper').css({
427 paddingBottom: datasH
428 });
429
430 $modal.find('.imagify-modal-content').on('scroll.imagify', function(){
431 $handle.css({
432 top: handle_pos + $(this).scrollTop()
433 });
434 $labels.css({
435 top: labels_pos + $(this).scrollTop()
436 });
437 $datas.css({
438 bottom: - ( $(this).scrollTop() )
439 });
440 });
441 }
442
443 });
444 clearInterval( check_load );
445 check_load = null;
446 }
447 }, 75 );
448
449 });
450 }
451 // else put images next to next
452 else if ( thumb.width < 300 && $('#imagify-full-original').length > 0 && $('#imagify-full-original').val() !== '' ) {
453
454 }
455 // if image has no backup
456 else if ( $('#imagify-full-original').length > 0 && $('#imagify-full-original').val() === '' ) {
457 // do nothing ?
458 }
459 // in case image is not optimized
460 else {
461 $('[id^="imgedit-open-btn-"]').before('<span class="spinner imagify-hidden"></span><a class="imagify-button-primary button-primary imagify-optimize-trigger" id="imagify-optimize-trigger" href="' + $optimize_btn.attr('href') + '">' + imagifyTTT.labels.optimize + '</a>');
462
463 $('#imagify-optimize-trigger').on('click', function(){
464 $(this).prev('.spinner').removeClass('imagify-hidden').addClass('is-active');
465 });
466 }
467
468 }
469
470 })(window, jQuery);
471