feat: support LQIP for images

This commit is contained in:
Cotes Chung 2022-12-11 07:09:40 +08:00
parent ca41c7ebff
commit bffaf6374f
No known key found for this signature in database
GPG Key ID: 0D9E54843167A808
5 changed files with 100 additions and 71 deletions

View File

@ -51,23 +51,43 @@
{% assign _img_content = nil %} {% assign _img_content = nil %}
{% assign _img_snippets = _content | split: IMG_TAG %} {% assign _img_snippets = _content | split: IMG_TAG %}
<!-- CDN URL -->
{% if site.img_cdn %}
{% if site.img_cdn contains '//' %}
{% assign _path_prefix = site.img_cdn %}
{% else %}
{% assign _path_prefix = site.img_cdn | relative_url %}
{% endif %}
{% else %}
{% assign _path_prefix = site.baseurl %}
{% endif %}
<!-- Add image path -->
{% if page.img_path %}
{% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
{% assign _path_prefix = _path_prefix | append: _path %}
{% endif %}
{% for _img_snippet in _img_snippets %} {% for _img_snippet in _img_snippets %}
{% if forloop.first %} {% if forloop.first %}
{% assign _img_content = _img_snippet %} {% assign _img_content = _img_snippet %}
{% continue %} {% continue %}
{% endif %} {% endif %}
{% assign _width = nil %}
{% assign _height = nil %}
{% assign _src = nil %}
{% assign _left = _img_snippet | split: '>' | first %} {% assign _left = _img_snippet | split: '>' | first %}
{% assign _right = _img_snippet | remove: _left %} {% assign _right = _img_snippet | remove: _left %}
{% assign _left = _left | remove: ' /' %} {% unless _left contains 'src=' %}
{% assign _left = _left | replace: ' w=', ' width=' | replace: ' h=', ' height=' %} {% continue %}
{% endunless %}
{% assign _left = _left | remove: ' /' | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
{% assign _attrs = _left | split: ' ' %} {% assign _attrs = _left | split: ' ' %}
{% assign _width = nil %}
{% assign _height = nil %}
{% assign _lqip = nil %}
{% for _attr in _attrs %} {% for _attr in _attrs %}
{% assign _pair = _attr | split: '="' %} {% assign _pair = _attr | split: '="' %}
{% if _pair.size < 2 %} {% if _pair.size < 2 %}
@ -75,7 +95,7 @@
{% endif %} {% endif %}
{% capture _key %}{{ _pair | first }}{% endcapture %} {% capture _key %}{{ _pair | first }}{% endcapture %}
{% capture _value %}{{ _pair | last | replace: '"', '' }}{% endcapture %} {% capture _value %}{{ _pair | last | remove: '"' }}{% endcapture %}
{% case _key %} {% case _key %}
{% when 'width' %} {% when 'width' %}
@ -84,67 +104,61 @@
{% assign _height = _value %} {% assign _height = _value %}
{% when 'src' %} {% when 'src' %}
{% assign _src = _value %} {% assign _src = _value %}
{% when 'lqip' %}
{% assign _lqip = _value %}
{% endcase %} {% endcase %}
{% if _width and _height and _src %}
{% break %}
{% endif %}
{% endfor %} {% endfor %}
{% if _src %} {% unless _src contains '//' %}
{% unless _src contains '://' %} {% assign _final_src = _path_prefix | append: _src %}
<!-- Add CDN URL --> {% capture _src_from %}"{{ _src }}"{% endcapture %}
{% if site.img_cdn %} {% capture _src_to %}"{{ _final_src }}"{% endcapture %}
{% if site.img_cdn contains '//' %} {% assign _left = _left | replace: _src_from, _src_to %}
{% assign _src_prefix = site.img_cdn %} {% endunless %}
{% else %}
{% assign _src_prefix = site.img_cdn | relative_url %}
{% endif %}
{% else %}
{% assign _src_prefix = site.baseurl %}
{% endif %}
<!-- Add image path -->
{% if page.img_path %}
{% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
{% assign _src_prefix = _src_prefix | append: _path %}
{% endif %}
{% assign _final_src = _src_prefix | append: _src %}
{% assign _left = _left | replace: _src, _final_src %}
{% if _lqip %}
{% unless _lqip contains ':' %}
{% assign _final_lqip = _path_prefix | append: _lqip %}
{% capture _lqip_from %}"{{ _lqip }}"{% endcapture %}
{% capture _lqip_to %}"{{ _final_lqip }}"{% endcapture %}
{% assign _left = _left | replace: _lqip_from, _lqip_to %}
{% endunless %} {% endunless %}
<!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
{% if _left contains 'class=' %}
{% assign _left = _left | replace: 'class="', 'class="lazyload ' %}
{% else %}
{% assign _left = _left | replace: 'src=', 'class="lazyload" src=' %}
{% endif %}
{% assign _left = _left | replace: 'src=', 'data-src=' %}
{% endif %} {% endif %}
<!-- Add SVG placehoder to prevent layout reflow --> <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
{% if _left contains 'class=' %}
{% assign _left = _left | replace: 'class="', 'class="lazyload ' %}
{% else %}
{% assign _left = _left | replace: 'src=', 'class="lazyload" src=' %}
{% endif %}
{% if _width and _height %} {% assign _left = _left | replace: 'src=', 'data-src=' %}
{%- capture _svg -%}
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
{%- endcapture -%}
{% assign _left = _svg | append: ' ' | append: _left %} <!-- add placeholder -->
{% if _lqip %}
{% assign _left = _left | replace: ' lqip=', ' data-lqip="true" src=' %}
{% else %}
{% if _width and _height %}
<!-- Add SVG placehoder to prevent layout reflow -->
{%- capture _svg -%}
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
{%- endcapture -%}
{% assign _left = _svg | append: ' ' | append: _left %}
{% endif %}
{% endif %} {% endif %}
<!-- Bypass the HTML-proofer test --> <!-- Bypass the HTML-proofer test -->
{% assign _left = _left | append: ' data-proofer-ignore' %} {% assign _left = _left | append: ' data-proofer-ignore' %}
<!-- Combine -->
{% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %} {% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
{% endfor %} {% endfor %}
{% assign _content = _img_content %} {% if _img_content %}
{% assign _content = _img_content %}
{% endif %}
{% endif %} {% endif %}

View File

@ -27,12 +27,9 @@ tail_includes:
{% endif %} {% endif %}
{% if page.image %} {% if page.image %}
{% capture bg %}
{% unless page.image.no_bg %}{{ 'bg' }}{% endunless %}
{% endcapture %}
<div class="mt-3 mb-3"> <div class="mt-3 mb-3">
<img src="{{ page.image.path | default: page.image }}" class="preview-img {{ bg | strip }}" <img src="{{ page.image.path | default: page.image }}"
class="preview-img{% if page.image.no_bg %}{{ ' no-bg' }}{% endif %}"
alt="{{ page.image.alt | default: "Preview Image" }}" alt="{{ page.image.alt | default: "Preview Image" }}"
{% if page.image.width %} {% if page.image.width %}
@ -45,12 +42,17 @@ tail_includes:
height="{{ page.image.height }}" height="{{ page.image.height }}"
{% elsif page.image.h %} {% elsif page.image.h %}
height="{{ page.image.h }}" height="{{ page.image.h }}"
{% endif %}> {% endif %}
{% if page.image.lqip %}
lqip="{{ page.image.lqip }}"
{% endif %}
><!-- endof img tag -->
{% if page.image.alt %} {% if page.image.alt %}
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption> <figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}

View File

@ -184,16 +184,27 @@ i { /* fontawesome icons */
} }
img[data-src] { img[data-src] {
margin: 0.5rem 0; @at-root #main #{&} {
margin: 0.5rem 0;
&.lazyload,
&.lazyloading {
opacity: 0;
} }
&.lazyloaded { &[data-lqip="true"] {
opacity: 1; &.lazyload,
transition: opacity 0.5s; &.lazyloading {
filter: blur(20px);
}
}
&:not([data-lqip="true"]) {
&.lazyload,
&.lazyloading {
opacity: 0;
}
&.lazyloaded {
opacity: 1;
transition: opacity 0.5s;
}
} }
&.left { &.left {
@ -395,6 +406,10 @@ img[data-src] {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
img[data-src]:not(.normal):not(.left):not(.right) {
@include align-center;
}
a { a {
&.img-link { &.img-link {
@extend %no-cursor; @extend %no-cursor;
@ -403,10 +418,6 @@ img[data-src] {
/* created by `_includes/img-extra.html` */ /* created by `_includes/img-extra.html` */
&.popup { &.popup {
cursor: zoom-in; cursor: zoom-in;
> img[data-src]:not(.normal):not(.left):not(.right) {
@include align-center;
}
} }
&:hover { &:hover {

View File

@ -96,8 +96,10 @@
--timeline-year-dot-color: var(--timeline-color); --timeline-year-dot-color: var(--timeline-color);
.post img[data-src] { .post img[data-src] {
-webkit-filter: brightness(95%); &.lazyloaded {
filter: brightness(95%); -webkit-filter: brightness(95%);
filter: brightness(95%);
}
} }
hr { hr {

View File

@ -30,7 +30,7 @@ img.preview-img {
margin: 0; margin: 0;
border-radius: 6px; border-radius: 6px;
&.bg { &:not(.no-bg) {
background: var(--preview-img-bg); background: var(--preview-img-bg);
} }
} }