Skip to content

Commit

Permalink
Add Avif Support Merge pull request #1 from iWangJiaxiang/avif
Browse files Browse the repository at this point in the history
Add Avif Support
  • Loading branch information
iWangJiaxiang authored Feb 27, 2025
2 parents e9daabc + 5b5fe73 commit 97bc550
Show file tree
Hide file tree
Showing 16 changed files with 1,287 additions and 81 deletions.
4 changes: 4 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ menus = [
{ name = "作者 Github", url = "https://github.com/iWangJiaxiang", internal = false},
]

# 其他设置
[extra.other]
# AVIF 图片优化,大幅降低图片尺寸
avif_enable = true

# 主页小组件 按顺序渲染
[[extra.index.widgets]]
Expand Down
Binary file removed static/img/beian.avif
Binary file not shown.
Binary file removed static/img/blog-event.avif
Binary file not shown.
Binary file removed static/img/blog.avif
Binary file not shown.
Binary file removed static/img/homepage-single.avif
Binary file not shown.
Binary file removed static/img/theme-single.avif
Binary file not shown.
84 changes: 29 additions & 55 deletions static/js/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
// 获取具有特定 class 的兄弟节点,返回第一个
function getSiblingNodesWithClass(element, className) {
const parent = element.parentNode;

// Iterate through the child nodes of the parent
for (let i = 0; i < parent.children.length; i++) {
const sibling = parent.children[i];
// Check if the sibling has the specified class and is not the original element
if (sibling !== element && sibling.classList.contains(className)) {
return sibling;
}
}

return null;
}

// 渐进加载图片
window.progressiveLoad = function(element) {
if (!element) return;
// 隐藏缩略图
var sibing = getSiblingNodesWithClass(element, 'progressive-thumbnail')
if (sibing)
sibing.classList.add('loaded');
// 加载主图
element.classList.add('loaded');
// 去除模糊效果
element.parentNode.classList.add('loaded');
}

// 添加视差效果
var image = document.getElementsByClassName('banner-pic-img');
new simpleParallax(image, {
Expand Down Expand Up @@ -29,57 +58,6 @@ document.querySelector('.menu-list').addEventListener('wheel',(e)=>{
e.preventDefault()
})


// 检查AVIF图片是否支持,并处理图片加载格式
// 如不支持,则换成webp格式
function checkAvif() {
// 从页面中提取第一个AVIF图片链接
function getFirstAvifUrl() {
const images = document.querySelectorAll('img');
for (let img of images) {
if (img.src.endsWith('.avif')) {
return img.src;
}
}
return null;
}

// 检测浏览器是否支持AVIF格式
function supportsAvif(url) {
return new Promise(resolve => {
const avif = new Image();
avif.src = url;
avif.onload = () => {
resolve(true);
};
avif.onerror = () => {
resolve(false);
};
});
}

// 替换图片URL中的avif为webp
function replaceAvifWithWebp() {
const images = document.querySelectorAll('img');
images.forEach(img => {
if (img.src.endsWith('.avif')) {
console.log("Replacing AVIF with WebP for image:", img.src);
img.src = img.src.replace('.avif', '.webp');
}
});
}

const firstAvifUrl = getFirstAvifUrl(); // 获取第一个AVIF图片链接
if (firstAvifUrl) {
// 使用第一个AVIF图片链接进行检测
supportsAvif(firstAvifUrl).then(supported => {
if (!supported) {
replaceAvifWithWebp();
}
});
}
}

var homepage = {
//显示菜单
showMenu: function() {
Expand Down Expand Up @@ -157,7 +135,3 @@ window.addEventListener('scroll',function(){
})

initNav()

document.addEventListener('DOMContentLoaded', function () {
checkAvif()
})
1,164 changes: 1,163 additions & 1 deletion static/main.css

Large diffs are not rendered by default.

100 changes: 81 additions & 19 deletions templates/_macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,41 +51,103 @@
{{ macro::open_graph(title=title, _permalink=_permalink, cover=cover, excerpt=excerpt, type=type) }}
{% endmacro %}

{# 生成缩略图,跳过avif格式和webp格式 {{ macro::thumbnail(url=post.cover) }} #}
{% macro thumbnail(url, width=800, height=500, op="fit", format="webp") %}
{% if url is ending_with(".avif") or url is ending_with(".webp") %}

{# 生成缩略图,跳过avif格式和svg格式 {{ macro::thumbnail(url=post.cover) }} #}
{% macro thumbnail(url, width=800, height=500, op="fit", quality=75, format="webp") %}
{%- if url is ending_with(".avif") or url is ending_with(".svg") -%}
{{ url | trim | safe }}
{% else %}
{% if url %}
{% set thumbnail = resize_image(path=url | safe, width=width, height=height, op=op, format="webp", quality=75) %}
{% set result = thumbnail.url %}
{% else %}
{% set result = config.extra.site.default_cover %}
{% endif %}
{%- else -%}
{%- if url -%}
{%- if format == "avif" -%}
{%- if not config.extra.other.avif_enable -%}
{%- set format = "webp" -%}
{%- else -%}
{%- set quality = 75 -%}
{%- endif -%}
{%- endif -%}
{%- set thumbnail = resize_image(path=url | trim, width=width, height=height, op=op, format=format, quality=quality) -%}
{%- set result = thumbnail.url -%}
{%- else -%}
{%- set result = config.extra.site.default_cover -%}
{%- endif -%}
{{ result | trim | safe }}
{% endif %}
{%- endif -%}
{% endmacro %}

{# 生成缩略图 小 {{ macro::thumbnail_s(url=post.cover) }} #}
{% macro thumbnail_s(url, width=200, height=120, op="fit") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op) -}}
{% macro thumbnail_s(url, width=200, height=120, op="fit", format="webp") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op, format=format) -}}
{% endmacro %}

{# 生成缩略图 中等 {{ macro::thumbnail_m(url=post.cover) }} #}
{% macro thumbnail_m(url, width=500, height=300, op="fit") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op) -}}
{% macro thumbnail_m(url, width=500, height=300, op="fit", format="webp") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op, format=format) -}}
{% endmacro %}

{# 生成缩略图 大 {{ macro::thumbnail_l(url=post.cover) }} #}
{% macro thumbnail_l(url, width=800, height=500, op="fit") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op) -}}
{% macro thumbnail_l(url, width=800, height=500, op="fit", format="webp") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op, format=format) -}}
{% endmacro %}

{# 生成缩略图 大 {{ macro::thumbnail_l(url=post.cover) }} #}
{% macro thumbnail_xl(url, width=1200, height=800, op="fit") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op) -}}
{% macro thumbnail_xl(url, width=1200, height=800, op="fit", format="webp") %}
{{- macro::thumbnail(url=url | safe, width=width, height=height, op=op, format=format) -}}
{% endmacro %}

{# 渐进式加载图片 src 本地路径 #}
{% macro img_progressive_loading(src, alt="", id="", class="", style="") %}
<picture {% if id != "" %}id="{{ id }}" {% endif %} class="{% if class != "" %}{{ class }} {% endif %}progressive-picture"{% if style != "" %} {{ style }}{% endif %}>
{#- the small image that will be blurred -#}
<img class="progressive-thumbnail" src="{{ macro::thumbnail(url=src, width=16, op="fit_width", quality=1) | trim | safe }}" loading="lazy" decoding="async">
{#- a lazy responsive image with data-srcset -#}
{#- 75em = 1200px -#}
<source media="(min-width: 75em)" srcset="{{ macro::thumbnail(url=src, width=1200, op="fit_width", format="avif") | trim | safe }}?w=75em" />
{#- 60em = 960px -#}
<source media="(min-width: 60em)" srcset="{{ macro::thumbnail(url=src, width=960, op="fit_width", format="avif") | trim | safe }}?w=60em" />
{#- 45em = 720px -#}
<source media="(min-width: 45em)" srcset="{{ macro::thumbnail(url=src, width=720, op="fit_width", format="avif") | trim | safe }}?w=45em" />
{#- 30em = 500px -#}
<source media="(min-width: 30em)" srcset="{{ macro::thumbnail(url=src, width=500, op="fit_width", format="avif") | trim | safe }}?w=30em" />
{#- 22em = 360px -#}
<source media="(min-width: 22em)" srcset="{{ macro::thumbnail(url=src, width=360, op="fit_width", format="avif") | trim | safe }}?w=22em" />
{#- Generate a webp image as fallback if avif is not supported -#}
<img class="progressive-content"{% if alt != "" %} alt="{{ alt }}"{% endif %}
onload="progressiveLoad(this)" loading="lazy" decoding="async"
src="{{ macro::thumbnail(url=src, width=500, op="fit_width", format="webp") | trim | safe }}?w=30em"
srcset="{{ macro::thumbnail(url=src, width=360, op="fit_width", format="webp") | trim | safe }}?w=22em 360w,
{{ macro::thumbnail(url=src, width=500, op="fit_width", format="webp") | trim | safe }}?w=30em 500w,
{{ macro::thumbnail(url=src, width=720, op="fit_width", format="webp") | trim | safe }}?w=45em 720w,
{{ macro::thumbnail(url=src, width=960, op="fit_width", format="webp") | trim | safe }}?w=60em 960w,
{{ macro::thumbnail(url=src, width=1200, op="fit_width", format="webp") | trim | safe }}?w=75em 1200w"/>
{#- a noscript fallback -#}
<noscript>
<img loading="lazy" decoding="async"{% if alt != "" %} alt="{{ alt }}"{% endif %}
src="{{ macro::thumbnail(url=src, width=500, op="fit_width", format="webp") | trim | safe }}?w=30em">
</noscript>
</picture>
{% endmacro %}


{# 渐进式加载图片 src 本地路径,无尺寸自适应,用于提供avif和webp支持 #}
{% macro img_progressive_loading_single_size(src, alt="", id="", class="", style="", onclick="") %}
<picture {% if id != "" %}id="{{ id }}" {% endif %} class="progressive-picture{% if class != "" %} {{ class }}{% endif %}"{% if style != "" %} style="{{ style }}"{% endif %}{% if onclick != "" %} onclick="{{ onclick }}"{% endif %}>
{#- the small image that will be blurred -#}
<img class="progressive-thumbnail" src="{{ macro::thumbnail(url=src, width=16, op="fit_width", quality=1) | trim | safe }}" loading="lazy" decoding="async">
{#- avif image -#}
<source media="(min-width: 1em)" srcset="{{ macro::thumbnail(url=src, format="avif") | trim | safe }}" />
{#- webp image -#}
<img class="progressive-content"{% if alt != "" %} alt="{{ alt }}"{% endif %}
onload="progressiveLoad(this)" loading="lazy" decoding="async"
src="{{ macro::thumbnail(url=src, format="webp") | trim | safe }}"/>
{#- a noscript fallback -#}
<noscript>
<img loading="lazy" decoding="async"{% if alt != "" %} alt="{{ alt }}"{% endif %}
src="{{ macro::thumbnail(url=src, format="webp") | trim | safe }}">
</noscript>
</picture>
{% endmacro %}


{# 动态加载侧边小组件 #}
{% macro render_widget(widget, value) %}

Expand Down
2 changes: 1 addition & 1 deletion templates/partial/layout/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="info-group">
{% if config.extra.site.compliance_security and config.extra.site.compliance_security_link %}
<a class="info" href="{{ config.extra.site.compliance_security_link }}" target="_blank">
<img class="beian-icon" src="/img/beian.avif" style="vertical-align: middle; margin-right: 3px;">
{{ macro::img_progressive_loading_single_size(src="/img/beian.webp", alt="beian", class="beian-icon", style="vertical-align: middle; margin-right: 3px;") }}
{{ config.extra.site.compliance_security }}
</a>
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion templates/partial/layout/nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="nav-content">
<div class="nav-left">
<a href="javascript:scrollToTopWithAnimation()" class="site-logo">
<img src="{{ config.extra.site.nav_logo | default(value=config.extra.site.logo) }}" alt="logo" class="site-logo-img">
{{ macro::img_progressive_loading_single_size(src=config.extra.site.nav_logo | default(value=config.extra.site.logo), alt="logo", class="site-logo-img") }}
<span class="site-name">{{ config.author }}</span>
</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/partial/widget/author.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</p>
</span>
<div class="avatar-info">
<img loading="lazy" class="avatar-image" src="{{ value.avatar | safe }}">
{{ macro::img_progressive_loading_single_size(src=value.avatar, class="avatar-image") }}
<span class="avatar-name">{{ value.name }}</span>
<span class="avatar-title">{{ value.title }}</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/partial/widget/event.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
<span class="linkbotton-tips">{{ value.note | safe }}</span>
</div>
</div>
<img class="special-card-right" src="{{ value.img | safe }}"></img>
{{ macro::img_progressive_loading_single_size(src=value.img, class="special-card-right") }}
</div>
{% endmacro %}
2 changes: 1 addition & 1 deletion templates/partial/widget/product-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h2 class="group-title">{{ value.title | safe }}</h2>
{% for item in value.items %}
<div class="group-item">
<a class="group-item-icon" href="{{ item.url | safe }}" target="_blank">
<img class="group-item-icon-img" src="{{ item.logo | safe }}" alt="product-icon" title="product-icon">
{{ macro::img_progressive_loading_single_size(src=item.logo, class="group-item-icon-img") }}
</a>
<div class="group-info-group">
<div class="group-info">
Expand Down
2 changes: 1 addition & 1 deletion templates/partial/widget/product-single.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</div>
</div>
<div class="banner-pic">
<img class="banner-pic-img" src="{{ value.img | safe }}" alt="banner image">
{{ macro::img_progressive_loading_single_size(src=value.img, class="banner-pic-img") }}
</div>
</div>
{% endmacro %}
4 changes: 4 additions & 0 deletions theme.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ menus = [
{ name = "作者 Github", url = "https://github.com/iWangJiaxiang", internal = false},
]

# 其他设置
[extra.other]
# AVIF 图片优化,大幅降低图片尺寸
avif_enable = true

# 主页小组件 按顺序渲染
[[extra.index.widgets]]
Expand Down

0 comments on commit 97bc550

Please sign in to comment.