Add avif support

This commit is contained in:
Jonatan Nilsson 2021-01-05 19:12:10 +00:00
parent 44bcbe2647
commit 5645572bb6
16 changed files with 99 additions and 50 deletions

View file

@ -24,10 +24,14 @@ export function serve(docRoot, pathname, options = {}) {
|| filepath.endsWith('.png') || filepath.endsWith('.png')
|| filepath.endsWith('.js') || filepath.endsWith('.js')
|| filepath.endsWith('.css') || filepath.endsWith('.css')
|| filepath.endsWith('.avif')
|| filepath.endsWith('.svg')) { || filepath.endsWith('.svg')) {
if (filepath.indexOf('admin') === -1) { if (filepath.indexOf('admin') === -1) {
opts = defaults({ maxage: 2592000 * 1000 }, opts) opts = defaults({ maxage: 2592000 * 1000 }, opts)
} }
if (filepath.endsWith('.avif')) {
ctx.type = 'image/avif'
}
} }
if (filepath === '/index.html') { if (filepath === '/index.html') {
@ -48,6 +52,7 @@ export function serve(docRoot, pathname, options = {}) {
return send(ctx, filepath, opts).catch((er) => { return send(ctx, filepath, opts).catch((er) => {
if (er.code === 'ENOENT' && er.status === 404) { if (er.code === 'ENOENT' && er.status === 404) {
ctx.type = null
return serveIndex(ctx, filepath) return serveIndex(ctx, filepath)
// return send(ctx, '/index.html', options) // return send(ctx, '/index.html', options)
} }

View file

@ -50,10 +50,9 @@ const Article = {
}) })
}, },
onupdate: function(vnode) { onbeforeupdate: function(vnode) {
if (this.path !== m.route.param('id')) { if (this.path !== m.route.param('id')) {
this.fetchArticle(vnode) this.fetchArticle(vnode)
m.redraw()
} }
}, },

View file

@ -6,11 +6,11 @@ const Darkmode = {
setDarkMode: function(setOn) { setDarkMode: function(setOn) {
if (setOn) { if (setOn) {
localStorage.setItem(storageName, true) localStorage.setItem(storageName, true)
document.body.className = 'darkmodeon' document.body.className = 'darkmodeon' + ' ' + (window.supportsavif ? 'avifsupport' : 'jpegonly')
Darkmode.darkIsOn = true Darkmode.darkIsOn = true
} else { } else {
localStorage.removeItem(storageName) localStorage.removeItem(storageName)
document.body.className = 'daymode' document.body.className = 'daymode' + ' ' + (window.supportsavif ? 'avifsupport' : 'jpegonly')
Darkmode.darkIsOn = false Darkmode.darkIsOn = false
} }
}, },

View file

@ -87,14 +87,18 @@ footer {
} }
} }
.daymode footer .footer-logo { .daymode.jpegonly footer .footer-logo {
background-image: url("/assets/img/tsun_small.jpg"); background-image: url("/assets/img/tsun_small.jpg");
} }
.darkmodeon footer .footer-logo { .darkmodeon.jpegonly footer .footer-logo {
background-image: url("/assets/img/dark_tsun_small.jpg"); background-image: url("/assets/img/dark_tsun_small.jpg");
} }
.avifsupport footer .footer-logo {
background-image: url("/assets/img/tsun.avif");
}
@media @media
only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2),
@ -102,11 +106,11 @@ only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2), only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) { only screen and ( min-resolution: 2dppx) {
.daymode .footer-logo { .daymode.jpegonly .footer-logo {
background-image: url("/assets/img/tsun.jpg"); background-image: url("/assets/img/tsun.jpg");
} }
.darkmodeon .footer-logo { .darkmodeon.jpegonly .footer-logo {
background-image: url("/assets/img/dark_tsun.jpg"); background-image: url("/assets/img/dark_tsun.jpg");
} }
} }

View file

@ -107,7 +107,8 @@ const Frontpage = {
return [ return [
(bannerPath (bannerPath
? m('a.frontpage-banner', { ? m(m.route.Link, {
class: 'frontpage-banner',
href: '/article/' + this.featured.path, href: '/article/' + this.featured.path,
style: { 'background-image': 'url("' + bannerPath + '")' }, style: { 'background-image': 'url("' + bannerPath + '")' },
}, },
@ -131,7 +132,9 @@ const Frontpage = {
}) })
), ),
]), ]),
m('div.asunaside'), m('div.asunaside', {
class: window.supportsavif ? 'avif' : 'jpeg'
}),
]), ]),
m('.frontpage-news', [ m('.frontpage-news', [
(this.loading (this.loading

View file

@ -137,13 +137,19 @@ frontpage {
} }
} }
.daymode frontpage .asunaside { .daymode.jpegonly frontpage .asunaside {
background-image: url("/assets/img/asuna_frontpage.jpg"); background-image: url("/assets/img/asuna_frontpage.jpg");
} }
.daymode.avifsupport frontpage .asunaside {
background-image: url("/assets/img/asuna_frontpage.avif");
}
.darkmodeon frontpage .asunaside { .darkmodeon.jpegonly frontpage .asunaside {
background-image: url("/assets/img/dark_asuna_frontpage.jpg"); background-image: url("/assets/img/dark_asuna_frontpage.jpg");
} }
.darkmodeon.avifsupport frontpage .asunaside {
background-image: url("/assets/img/dark_asuna_frontpage.avif");
}
@media screen and (max-width: 480px){ @media screen and (max-width: 480px){
.frontpage-banner { .frontpage-banner {

View file

@ -3,15 +3,6 @@ require('./polyfill')
const m = require('mithril') const m = require('mithril')
window.m = m window.m = m
/*
* imgsupport.js from leechy/imgsupport
*/
const AVIF = new Image();
AVIF.onload = AVIF.onerror = function () {
window.supportsavif = (AVIF.height === 2)
}
AVIF.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=';
m.route.setOrig = m.route.set m.route.setOrig = m.route.set
m.route.set = function(path, data, options){ m.route.set = function(path, data, options){
m.route.setOrig(path, data, options) m.route.setOrig(path, data, options)
@ -119,6 +110,18 @@ const allRoutes = {
'/admin/:path/:id': AdminResolver, '/admin/:path/:id': AdminResolver,
} }
// Wait until we finish checking avif support, some views render immediately and will ask for this immediately before the callback gets called.
/*
* imgsupport.js from leechy/imgsupport
*/
const AVIF = new Image();
AVIF.onload = AVIF.onerror = function () {
window.supportsavif = (AVIF.height === 2)
document.body.className = document.body.className + ' ' + (window.supportsavif ? 'avifsupport' : 'jpegonly')
m.route(mainRoot, '/', allRoutes) m.route(mainRoot, '/', allRoutes)
m.mount(menuRoot, Menu) m.mount(menuRoot, Menu)
m.mount(footerRoot, Footer) m.mount(footerRoot, Footer)
}
AVIF.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=';

View file

@ -26,7 +26,6 @@
display: flex; display: flex;
color: $primary-dark-fg; color: $primary-dark-fg;
text-decoration: none; text-decoration: none;
background-image: url("/assets/img/logo_small.jpg");
} }
h2 { h2 {
@ -127,6 +126,14 @@
} }
} }
.avifsupport #nav .top a.logo {
background-image: url("/assets/img/logo.avif");
}
.jpegonly #nav .top a.logo {
background-image: url("/assets/img/logo_small.jpg");
}
@media @media
only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2),
@ -134,7 +141,7 @@ only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2), only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) { only screen and ( min-resolution: 2dppx) {
#nav .top a.logo { .jpegonly #nav .top a.logo {
background-image: url("/assets/img/logo.jpg"); background-image: url("/assets/img/logo.jpg");
} }
} }

View file

@ -51,13 +51,11 @@ const Page = {
}) })
}, },
onupdate: function(vnode) { onbeforeupdate: function(vnode) {
if (this.path !== m.route.param('id')) { if (this.path !== m.route.param('id')) {
this.fetchPage(vnode) this.fetchPage(vnode)
m.redraw()
} else if (m.route.param('page') && m.route.param('page') !== this.lastpage) { } else if (m.route.param('page') && m.route.param('page') !== this.lastpage) {
this.fetchArticles(vnode) this.fetchArticles(vnode)
m.redraw()
} }
}, },

View file

@ -146,9 +146,9 @@ newsitem {
width: 400px; width: 400px;
text-align: center; text-align: center;
img { picture {
max-height: 360px; max-height: 400px;
max-width: 360px; max-width: 400px;
width: auto; width: auto;
} }
} }
@ -224,7 +224,7 @@ pages {
newsitem a.cover { newsitem a.cover {
width: 300px; width: 300px;
img { picture {
max-width: 300px; max-width: 300px;
width: auto; width: auto;
} }
@ -237,7 +237,7 @@ pages {
width: 100%; width: 100%;
margin-bottom: 20px; margin-bottom: 20px;
img { picture {
max-height: unset; max-height: unset;
max-width: unset; max-width: unset;
width: 100%; width: 100%;

View file

@ -25,9 +25,15 @@ const Newsentry = {
} }
return m('newsentry', [ return m('newsentry', [
imagePath imagePath
? m('a.cover', { ? m(m.route.Link, {
class: 'cover',
href: '/article/' + vnode.attrs.path, href: '/article/' + vnode.attrs.path,
}, m('img', { src: imagePath, alt: 'Article image for ' + vnode.attrs.name })) }, m('picture', [
m('source', { srcset:
vnode.attrs.media.small_url + ''
}),
m('img', { src: imagePath, alt: 'Article image for ' + vnode.attrs.name }),
]))
: m('a.cover.nobg'), : m('a.cover.nobg'),
m('div.entrycontent', [ m('div.entrycontent', [
m('div.title', [ m('div.title', [

View file

@ -1,10 +1,21 @@
const Fileinfo = require('./fileinfo') const Fileinfo = require('./fileinfo')
const Newsitem = { const Newsitem = {
oninit: function(vnode) {
this.srcsetJpeg = vnode.attrs.media.small_url + ' 500w, '
+ vnode.attrs.media.medium_url + ' 800w '
if (vnode.attrs.media.small_url_avif) {
this.srcsetAvif = vnode.attrs.media.small_url_avif + ' 500w, '
+ vnode.attrs.media.medium_url_avif + ' 800w '
} else {
this.srcsetAvif = null
}
this.coverSizes = '(max-width: 639px) calc(100vw - 40px), '
+ '(max-width: 1000px) 300px, '
+ '400px'
},
view: function(vnode) { view: function(vnode) {
var pixelRatio = window.devicePixelRatio || 1
var jpegImage = pixelRatio > 1 ? vnode.attrs.media.medium_url : vnode.attrs.media.small_url
var avifImage = pixelRatio > 1 ? vnode.attrs.media.medium_url_avif : vnode.attrs.media.small_url_avif
return m('newsitem', [ return m('newsitem', [
m(m.route.Link, m(m.route.Link,
{ href: '/article/' + vnode.attrs.path, class: 'title' }, { href: '/article/' + vnode.attrs.path, class: 'title' },
@ -12,16 +23,23 @@ const Newsitem = {
), ),
m('div.newsitemcontent', [ m('div.newsitemcontent', [
vnode.attrs.media vnode.attrs.media
? m('a.cover', { ? m(m.route.Link, {
class: 'cover',
href: '/article/' + vnode.attrs.path, href: '/article/' + vnode.attrs.path,
}, },
m('picture', [ m('picture', [
avifImage ? m('source', { this.srcsetAvif ? m('source', {
srcset: avifImage, srcset: this.srcsetAvif,
sizes: this.coverSizes,
type: 'image/avif', type: 'image/avif',
}) : null, }) : null,
m('img', { alt: 'Image for news item ' + vnode.attrs.name, src: jpegImage }) m('img', {
])) srcset: this.srcsetJpeg,
sizes: this.coverSizes,
alt: 'Image for news item ' + vnode.attrs.name,
src: vnode.attrs.media.small_url }),
])
)
: null, : null,
m('div.entrycontent', { m('div.entrycontent', {
class: vnode.attrs.media ? '' : 'extrapadding', class: vnode.attrs.media ? '' : 'extrapadding',

Binary file not shown.

Binary file not shown.

BIN
public/assets/img/logo.avif Normal file

Binary file not shown.

BIN
public/assets/img/tsun.avif Normal file

Binary file not shown.