-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxsdaliclock-local.html
More file actions
142 lines (137 loc) · 5.31 KB
/
xsdaliclock-local.html
File metadata and controls
142 lines (137 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!DOCTYPE html>
<html>
<head>
<title>Current time</title>
<style>
* {
box-sizing: border-box;
}
html {
box-sizing: border-box;
font-size: 16px;
}
fieldset {
border: none;
}
body {
background-color: black;
color: white;
}
h1, div { opacity: 0.5;}
#clockface{
width: 100vw;
height: 50vw;
position: fixed;
bottom: 0;
left: 0;
z-index: 1;
}
#signature {
position: fixed;
bottom: 0.5in;
right: 0.5in;
font-size: 0.5in;
z-index: 100;
}
</style>
</head>
<body>
<h1>
Diffusion Local Time, Raspberry Pi interactive edition
</h1>
<div>
<fieldset id="prompt">
<input type="radio" id="face1" name="face" value="Seashells on a beach" checked>
<label for="face1">Seashells</label>
<input type="radio" id="face2" name="face" value="Photo of cinnamon sticks and cardamom pods and cloves and peppercorns and star anise on a marble countertop">
<label for="face2">Spices</label>
<input type="radio" id="face3" name="face" value="Aerial photo of arches and mesas and buttes in the desert">
<label for="face3">Arches</label>
<input type="radio" id="face5" name="face" value="Ferns in a redwood forest">
<label for="face5">Redwoods</label>
<input type="radio" id="face6" name="face" value="Colored pencil drawing of bees on flowers">
<label for="face6">Meadow</label>
<input type="radio" id="face7" name="face" value="Underwater photo of kelp and starfish and sea anemones and turtles and small fish and sponges and coral">
<label for="face7">Reef</label>
<input type="radio" id="face4" name="face" value="face4">
<label for="face4"><input type="text" id="textface" value="a fruit basket"> </label>
</fieldset>
</div>
<div id="signature">
by Lee Butterman
</div>
<img id="clockface">
<script>
// const smoothstep6 = (frac) => 924 * Math.pow(frac, 13) - 6006 * Math.pow(frac, 12) + 16380 * Math.pow(frac, 11) - 24024 * Math.pow(frac, 10) + 20020 * Math.pow(frac, 9) - 9009 * Math.pow(frac, 8) + 1716 * Math.pow(frac, 7);
const face4 = document.getElementById('face4');
const textface = document.getElementById('textface');
const face = document.querySelector('fieldset#prompt input[name="face"]:checked').value;
const text = textface.value;
face4.value = text;
console.log(face, text);
textface.addEventListener('input', (event) => {
face4.value = textface.value;
face4.checked = true;
});
let currentSrc = "";
let loadTime = 0;
// let shouldRenderLatch = true;
// let promptAtStartOfMinute = "";
// let currentPrompt = "";
// let prefetchQueue = []; // of current params
// let alreadyPrefetched = []; // of current params
// let currentSlideshow = []; // of current params
// let currentParams = {prompt: "", hour: 0, minute: 0, microminute: 0, seed: 42};
function getCurrentParams() {
const prompt = document.querySelector('fieldset#prompt input[name="face"]:checked').value;
const now = new Date();
now.setMilliseconds(now.getMilliseconds() + loadTime);
const hour = now.getHours();
const minute = now.getMinutes();
const microminute = (now.getSeconds() + now.getMilliseconds() / 1000) * 1000000 / 60;
const seed = 42;
return {prompt, hour, minute, microminute, seed};
}
function urlForParams({prompt, hour, minute, microminute, seed}) {
microminute = 0; // TODO FIXME
return `./image?hour=${hour}&minute=${minute}µminute=${microminute}&seed=${seed}&prompt=${encodeURIComponent(prompt.trim())}`;
}
async function prefetchLoop() {
// TODO
}
async function prefetchImage(src) {
const img = new Image();
img.src = src;
await img.decode();
return;
}
async function loadNewFace(src) {
const start = new Date();
await prefetchImage(src);
const end = new Date();
loadTime = (end - start);
document.getElementById('clockface').src = src;
}
async function renderLoop() {
// rely on the prefetchLoop() to generate images quickly
// if the current slideshow is empty, and the current params is in the prefetch queue, we're not ready to render, just wait
// if there is no we don't have the current prompt in the current slideshow, stick it into the prefetch queue
// if we don't have the next minute's prompt in the next slideshow, stick it into the prefetch queue
// if the prefetch queue is empty, add exponentially more images into it
// dumbest thing that could work: just render the current image
const newURL = urlForParams(getCurrentParams());
const oldURL = currentSrc;
if(newURL !== oldURL) {
// console.log("loading new face: ", newURL)
await loadNewFace(newURL);
currentSrc = newURL;
} else {
// wait a second
await new Promise((resolve) => setTimeout(resolve, 1000));
}
requestAnimationFrame(renderLoop);
};
renderLoop();
</script>
</body>
</html>