From 45dbdad2600754322d7c2fbcff89f3dcc23d9c8c Mon Sep 17 00:00:00 2001 From: Elizabeth Cray Date: Fri, 23 Jun 2023 11:58:32 -0400 Subject: [PATCH] Image Preloading --- image.csv | 49 ++++++++++++++++++++ scripts/scene.js | 118 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 image.csv diff --git a/image.csv b/image.csv new file mode 100644 index 0000000..0aaeb5d --- /dev/null +++ b/image.csv @@ -0,0 +1,49 @@ +Name,Template,Reference +aces,image/aces,[SMPTE][Howard_Lukk] +apng,image/apng,[W3C][W3C_PNG_Working_Group] +avci,image/avci,[ISO-IEC_JTC_1][David_Singer] +avcs,image/avcs,[ISO-IEC_JTC_1][David_Singer] +avif,image/avif,[Alliance_for_Open_Media][Cyril_Concolato] +bmp,image/bmp,[RFC7903] +cgm,image/cgm,[Alan_Francis] +dicom-rle,image/dicom-rle,[DICOM_Standard_Committee][David_Clunie] +dpx,image/dpx,[SMPTE][SMPTE_Director_of_Standards_Development] +emf,image/emf,[RFC7903] +fits,image/fits,[RFC4047] +g3fax,image/g3fax,[RFC1494] +gif,image/gif,[RFC2045][RFC2046] +heic,image/heic,[ISO-IEC_JTC_1][David_Singer] +heic-sequence,image/heic-sequence,[ISO-IEC_JTC_1][David_Singer] +heif,image/heif,[ISO-IEC_JTC_1][David_Singer] +heif-sequence,image/heif-sequence,[ISO-IEC_JTC_1][David_Singer] +hej2k,image/hej2k,[ISO-IEC_JTC_1][ITU-T] +hsj2,image/hsj2,[ISO-IEC_JTC_1][ITU-T] +j2c,image/j2c,[ISO-IEC_JTC_1_SC_29_WG_1][ISO-IEC_JTC_1][ITU-T] +jls,image/jls,[DICOM_Standard_Committee][David_Clunie] +jp2,image/jp2,[RFC3745] +jpeg,image/jpeg,[RFC2045][RFC2046] +jpg,image/jpeg,[RFC2045][RFC2046] +jph,image/jph,[ISO-IEC_JTC_1][ITU-T] +jphc,image/jphc,[ISO-IEC_JTC_1][ITU-T] +jpm,image/jpm,[RFC3745] +jpx,image/jpx,[RFC3745] +jxr,image/jxr,[ISO-IEC_JTC_1][ITU-T] +jxrA,image/jxrA,[ISO-IEC_JTC_1][ITU-T] +jxrS,image/jxrS,[ISO-IEC_JTC_1][ITU-T] +jxs,image/jxs,[ISO-IEC_JTC_1] +jxsc,image/jxsc,[ISO-IEC_JTC_1] +jxsi,image/jxsi,[ISO-IEC_JTC_1] +jxss,image/jxss,[ISO-IEC_JTC_1] +ktx,image/ktx,[Khronos][Mark_Callow] +ktx2,image/ktx2,[Khronos][Mark_Callow] +naplps,image/naplps,[Ilya_Ferber] +png,image/png,[W3C][PNG_Working_Group] +prs.btif,image/prs.btif,[Ben_Simon] +prs.pti,image/prs.pti,[Juern_Laun] +pwg-raster,image/pwg-raster,[Michael_Sweet] +svg+xml,image/svg+xml,[W3C][http://www.w3.org/TR/SVG/mimereg.html] +t38,image/t38,[RFC3362] +tiff,image/tiff,[RFC3302] +tiff-fx,image/tiff-fx,[RFC3950] +webp,image/webp,[RFC-zern-webp-12] +wmf,image/wmf,[RFC7903] diff --git a/scripts/scene.js b/scripts/scene.js index 839a59b..6faf127 100644 --- a/scripts/scene.js +++ b/scripts/scene.js @@ -1,11 +1,10 @@ // TODO: -// - Support removal of images -// - Add adjustable slideshow speed // - Add image fading let socket let socketStatus = false +let mimes = {} let jsonValid = (json) => { try { @@ -19,11 +18,86 @@ let jsonValid = (json) => { return true; } +let loadMime = () => { + return new Promise((resolve, reject) => { + let request = new XMLHttpRequest() + request.open('GET', 'image.csv', true) + request.onload = () => { + if (request.readyState = 4 && request.status === 200) { + let mimeCSV = request.responseText + mimeCSV.split('\n').forEach(line => { + line = line.split(',') + let extension = line[0] + let mime = line[1] + let RFC = line[2] + mimes[extension] = { + mime: mime, + RFC: RFC + } + }) + resolve() + }else{ + reject('Failed to load image.csv') + } + } + request.send() + }) +} + +let urlExists = (url, callback) => { + var request = new XMLHttpRequest() + request.open('GET', url, true) + request.onreadystatechange = () => { + if (request.readyState === 4){ + if (request.status === 404) { + callback(false) + } else { + callback(true) + } + } + }; + request.send(); +} + +let preloadImage = (url, callback) => { + console.log(`%cPreloading ${url}`, 'color: #ECEFF4; font-family: monospace;') + let request = new XMLHttpRequest() + request.responseType = 'blob' + request.open('GET', url, true) + request.onload = () => { + console.log(`%cLoaded (${request.status}) ${url} `, 'color: #ECEFF4; font-family: monospace;') + if (request.readyState = 4 && request.status === 200) { + let reader = new FileReader() + reader.readAsArrayBuffer(request.response) + reader.onload = () => { + let imageData = btoa(new Uint8Array(reader.result).reduce((data, byte) => data + String.fromCharCode(byte), '')) + let header = "data:"//";base64," + let extension = url.split('.').pop() + "" + if (mimes[extension.toLowerCase()]) { + header += mimes[extension].mime + } else { + header += "image/" + extension + } + header += ";base64," + console.log(("%c" + header + imageData), "color: #A3BE8C; font-family: monospace; font-size: 8px;") + callback(header + imageData) + } + }else { + callback(false) + } + } + request.send() +} + let setWallpaper = (path) => { - console.log(`Setting wallpaper to ${path}`) - let wallpaper = document.getElementById('wallpaper') - // wallpaper.src = path - wallpaper.style.backgroundImage = `url(${path})` + preloadImage(path, (image) => { + if (image) { + console.log(`Setting wallpaper to ${path}`) + let wallpaper = document.getElementById('wallpaper') + // wallpaper.style.backgroundImage = `url(${path})` + wallpaper.style.backgroundImage = `url(${image})` + } + }) } let dumpStorage = () => { @@ -64,25 +138,34 @@ let pickWallpaper = () => { wallpapers = [] console.log('%cWallpapers not found in Local Storage', 'color: #BF616A; font-size: 18px; font-family: monospace;') } - // for (let index = wallpapers.length-1; index >= 0; index--) { - // if (!wallpapers.includes(localStorage.getItem('member'))) { - // wallpapers.splice(index, 1) - // } - // } let validWallpapers = [] wallpapers.forEach(wp => { if (wp.includes(localStorage.getItem('member'))) { validWallpapers.push(wp) } }) - let wallpaper = "file:///" + validWallpapers[Math.floor(Math.random() * validWallpapers.length)] + let chosenWallpaper = validWallpapers[Math.floor(Math.random() * validWallpapers.length)] + let wallpaper = "file:///" + chosenWallpaper if (validWallpapers.length == 0) { wallpaper = "https://picsum.photos/3840/2160" } - setWallpaper(wallpaper) - setTimeout(() => { - pickWallpaper() - }, 30000) + urlExists(wallpaper, (exists) => { + if (exists) { + setWallpaper(wallpaper) + setTimeout(() => { + pickWallpaper() + }, 30000) + } else { + console.log(`%c${wallpaper} does not exist`, 'color: #BF616A; font-size: 18px; font-family: monospace;') + // Remove wallpaper from list + let index = wallpapers.indexOf(chosenWallpaper) + if (index > -1) { + wallpapers.splice(index, 1) + } + localStorage.setItem('wallpapers', JSON.stringify(wallpapers)) + pickWallpaper() + } + }) } let loadSocket = () => { @@ -169,10 +252,11 @@ window.wallpaperPropertyListener = { }, } -window.onload = () => { +window.onload = async () => { console.log("%cPage Loaded.", "background: #2E3440; color: #A3BE8C; font-size: 24px;") // Set default member dumpStorage() grabLatestFronter() + await loadMime() loadSocket() }