From 2fb72bac4c9f30012793a9f228a4948724c31efd Mon Sep 17 00:00:00 2001 From: Tam Date: Wed, 4 Mar 2020 16:06:11 +0000 Subject: [PATCH] Add method of re-initializing dynamic image JS --- CHANGELOG.md | 4 + README.md | 9 + composer.json | 2 +- package.json | 11 + resources/dynamic.js | 63 ++ src/Variable.php | 2 +- src/assets/dynamic.js | 1 + yarn.lock | 2133 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 2223 insertions(+), 2 deletions(-) create mode 100644 package.json create mode 100644 resources/dynamic.js create mode 100644 src/assets/dynamic.js create mode 100644 yarn.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c428ed..2875cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.4 - 2020-03-04 +### Added +- Add method of re-initializing dynamic image JS + ## 1.0.3 - 2020-03-02 ### Added - Add support for passing URLs to transform methods diff --git a/README.md b/README.md index 9d8d56e..567b85d 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,15 @@ Will disable the automatic injection of the lazy loading JavaScript. Will convert the lazy loading to eager loading when true, meaning the image will instantly load in most cases. + +#### JS + +You can re-initialize the thumbro dynamic picture function by calling: + +```javascript +window.thumbro(); +``` + #### CSS You will need to include some CSS to ensure the picture tag appears correctly. diff --git a/composer.json b/composer.json index be06442..d18d529 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "ether/thumbro", "description": "Craft CMS image transformations powered by Thumbor", - "version": "1.0.3", + "version": "1.0.4", "type": "craft-plugin", "license": "proprietary", "minimum-stability": "dev", diff --git a/package.json b/package.json new file mode 100644 index 0000000..58d54f8 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "@babel/cli": "^7.8.4", + "@babel/core": "^7.8.6", + "@babel/preset-env": "^7.8.6", + "babel-preset-minify": "^0.5.1" + }, + "scripts": { + "build": "babel resources/dynamic.js --out-file src/assets/dynamic.js --presets=@babel/preset-env,minify --minified --no-comments --compact=true && sed -i '' -e 's/\\\"use strict\\\";//g' src/assets/dynamic.js" + } +} diff --git a/resources/dynamic.js b/resources/dynamic.js new file mode 100644 index 0000000..eb52115 --- /dev/null +++ b/resources/dynamic.js @@ -0,0 +1,63 @@ +window.thumbro = function () { + // Images + function visible (p) { + const b = p.getBoundingClientRect(); + + return b.top <= (window.innerHeight || document.documentElement.clientHeight); + } + + function showImage (p) { + const l = p.lastElementChild; + l.setAttribute('src', l.dataset.src); + l.setAttribute('srcset', l.dataset.srcset); + l.removeAttribute('data-src'); + l.removeAttribute('data-srcset'); + } + + const images = document.querySelectorAll('picture'); + + const ioImages = new IntersectionObserver((entries, observer) => { + for (let p of entries) { + if (p.intersectionRatio <= 0) + continue; + + const t = p.target; + + observer.unobserve(t); + showImage(t); + } + }, { + rootMargin: '20px 0px', + threshold: 0.01, + }); + + for (let i = 0, l = images.length; i < l; i++) { + const p = images[i]; + + const o = document.createElement('div'); + const n = p.querySelector('noscript'); + + if (!n) + continue; + + o.innerHTML = n.textContent; + + const g = o.firstElementChild; + g.style.opacity = 0; + g.setAttribute('data-src', g.getAttribute('src')); + g.setAttribute('data-srcset', g.getAttribute('srcset')); + g.removeAttribute('src'); + g.removeAttribute('srcset'); + + g.addEventListener('load', () => { + g.removeAttribute('style'); + }); + + p.appendChild(g); + + // Delay immediate load to allow fonts to load first + if (visible(p)) setTimeout(() => showImage(p), 150); + else ioImages.observe(p); + } +}; +window.thumbro(); diff --git a/src/Variable.php b/src/Variable.php index 4e8a7e4..586c950 100644 --- a/src/Variable.php +++ b/src/Variable.php @@ -134,7 +134,7 @@ public function picture ($asset, array $transform, array $config = []) if (!$noJS) { Craft::$app->getView()->registerJs( - '!function(){for(var t=function(t){var e=t.lastElementChild;e.setAttribute("src",e.dataset.src),e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-src"),e.removeAttribute("data-srcset")},e=document.querySelectorAll("picture"),r=new IntersectionObserver(function(e,r){var n=!0,i=!1,o=void 0;try{for(var s,c=e[Symbol.iterator]();!(n=(s=c.next()).done);n=!0){var u=s.value;if(!(u.intersectionRatio<=0)){var a=u.target;r.unobserve(a),t(a)}}}catch(t){i=!0,o=t}finally{try{n||null==c.return||c.return()}finally{if(i)throw o}}},{rootMargin:"20px 0px",threshold:.01}),n=function(n,i){var o=e[n],s=document.createElement("div"),c=o.querySelector("noscript");if(!c)return"continue";s.innerHTML=c.textContent;var u=s.firstElementChild;u.style.opacity=0,u.setAttribute("data-src",u.getAttribute("src")),u.setAttribute("data-srcset",u.getAttribute("srcset")),u.removeAttribute("src"),u.removeAttribute("srcset"),u.addEventListener("load",function(){u.removeAttribute("style")}),o.appendChild(u),!function(t){return t.getBoundingClientRect().top<=(window.innerHeight||document.documentElement.clientHeight)}(o)?r.observe(o):setTimeout(function(){return t(o)},150)},i=0,o=e.length;i=h.intersectionRatio)){var j=h.target;c.unobserve(j),b(j)}}catch(a){e=!0,f=a}finally{try{d||null==i["return"]||i["return"]()}finally{if(e)throw f}}},{rootMargin:"20px 0px",threshold:.01}),f=function(c){var f=d[c],h=document.createElement("div"),i=f.querySelector("noscript");if(!i)return"continue";h.innerHTML=i.textContent;var j=h.firstElementChild;j.style.opacity=0,j.setAttribute("data-src",j.getAttribute("src")),j.setAttribute("data-srcset",j.getAttribute("srcset")),j.removeAttribute("src"),j.removeAttribute("srcset"),j.addEventListener("load",function(){j.removeAttribute("style")}),f.appendChild(j),a(f)?setTimeout(function(){return b(f)},150):e.observe(f)},g=0,h=d.length;g