-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathexample.html
More file actions
305 lines (301 loc) · 8.92 KB
/
example.html
File metadata and controls
305 lines (301 loc) · 8.92 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
<!DOCTYPE html>
<html>
<head>
<title>Quick and Dirty Testing for Surreal</title>
<!-- <script src="https://cdn.jsdelivr.net/gh/gnat/surreal@main/surreal.js"></script> -->
<script src="surreal.js"></script>
<meta http-equiv="cache-control" content="no-cache" />
</head>
<body>
<!-- Basic examples -->
<button>👁️ Click me to fade out and remove.
<script>
me().on("click", ev => { me(ev).disable(); me(ev).fadeOut() })
</script>
</button>
<button class="invisible">👻 Click me to fade in.
<script>
me().on("click", ev => {
// Simple way to limit number of actions.
if(me(ev)?.fadeInLimit <= 1) return; else { me(ev).fadeInLimit = 1; me(ev).fadeIn() }
})
</script>
</button>
<div class="yeet noot">I should be red.
<script>
any(".yeet.noot").classAdd('.active')
</script>
</div>
<!-- Basic async examples -->
<div id="random">I should turn grey after 2 seconds.
<script>
// Basic usage with id. Runs immediately.
(async ()=>{
me("#random").classAdd('active')
await sleep(2000)
me("#random").classAdd('inactive')
})()
</script>
</div>
<div>I should be animated using events.
<script>
// Now you're thinking with events!
me().on("ping", async ev => {
let e = me(ev)
e.styles({"background":"hotpink", "color":"purple"})
await sleep(1000)
e.send("pong")
})
me().on("pong", async ev => {
let e = me(ev)
e.styles({"background":"blue", "color":"#002200"})
await sleep(1000)
e.send("ping")
})
me().styles({"transition":"all 2s"}).send("pong")
</script>
</div>
<div>I should be animated using timeline / async until finished!
<script>
// Now you're thinking with async! Runs immediately. No event.
(async (e = me()) => { // Special case where we can save element right away.
e.styles({"transition": "all 2s"})
e.styles({"background":"#0030F7", "color":"#002200"})
await sleep(2000)
e.styles({"background":"#006BFF", "color":"#000033"})
await sleep(2000)
e.styles({"background":"#00A1FF", "color":"#005500"})
await sleep(2000)
e.styles({"background":"#00C08C", "color":"#660033"})
await sleep(2000)
// New element!
var e2 = me(createElement("div"))
e2.styles({"transition":"all 2s", "opacity":"0", "height":"0%"})
e2.innerText = "🔥🔥🔥🔥🔥🔥"
e.appendChild(e2)
await sleep(1000)
e2.styles({"opacity":"1", "height":"fit-content"})
})()
</script>
</div>
<div>I should be surrounded by diamonds after a few seconds.
<script>
// Now you're thinking with async! Runs immediately. No event.
(async (e = me()) => { // Special case where we can save element right away.
e.styles({"transition":"all 2s", "color":"#fff"})
// New element!
var e2 = me(createElement("div"))
e2.innerText = "💎💎💎"
e.prepend(e2)
e2.styles({"transition":"all 2s", "opacity":"0"})
await sleep(1000)
e2.styles({"opacity":"1"})
await sleep(2000)
// New element!
var e2 = me(createElement("div"))
e2.styles({"transition":"all 2s", "opacity":"0"})
e2.innerText = "💎💎💎"
e.appendChild(e2)
await sleep(1000)
e2.styles({"opacity":"1"})
})()
</script>
</div>
<!-- Event examples -->
<div thick>📬 I close from a child button event.
<script>
me().on("close", async event => { me(event).fadeOut() }) // Recieve "close" event.
</script>
<button class="close">✉️ Send "close"
<script>
me().on("click", event => { me(event).disable(); me(event).send("close") })
</script>
</button>
</div>
<div thick>📭 I stay open because of <strong>halt()</strong>
<script>
me().on("close", event => { me(event).fadeOut() }) // I will never recieve "close" event because of halt()
</script>
<div thick>📬 I close dramatically from a child button <strong>async</strong> event
<script>
me().on("close", async event => {
let e = me(event) // Save element because event.currentTarget will be lost after await.
e.halt(event) // Event stops here.
e.disable() // Prevent user from clicking button many times.
e.styles({"transition":"all 0.5s", "background":"red"})
await sleep(500)
e.styles({"background":"white"})
await sleep(500)
e.styles({"background":"red"})
await sleep(500)
e.styles({"background":"white"})
e.fadeOut()
})
</script>
<button class="close">✉️ Send "close"
<script>
me().on("click", event => { me(event).disable(); me(event).send("close") }) // Use disable() to stop clicking more than once.
</script>
</button>
</div>
</div>
<!-- Scoping and 3D -->
<div class="card">
3D Card
<div></div>
<script>
me().on('mouseenter', (ev) => {
let e = me(ev)
e.bounds = e.getBoundingClientRect()
e.on('mousemove', e.rotateToMouse)
})
me().on('mouseleave', (ev) => {
let e = me(ev)
e.off('mousemove', e.rotateToMouse)
e.style.transform = ''
e.style.background = ''
})
me().rotateToMouse = (ev) => {
let e = me(ev)
let mouseX = ev.clientX
let mouseY = ev.clientY
let leftX = mouseX - e.bounds.x
let topY = mouseY - e.bounds.y
let center = { x: leftX - e.bounds.width / 2, y: topY - e.bounds.height / 2 }
let distance = Math.sqrt(center.x**2 + center.y**2)
e.style.transform = `scale3d(1.07, 1.07, 1.0) rotate3d(${center.y / 100}, ${-center.x / 100}, 0, ${Math.log(distance)* 1}0deg)`
me('div', e).style.backgroundImage = `radial-gradient(circle at ${center.x * 2 + e.bounds.width/2}px ${center.y * 2 + e.bounds.height/2}px, #ffffff55, #0000000f)`
}
</script>
</div>
<!-- Try out window.onload predictable call chain -->
<script>onloadAdd(()=>{ console.log("Hello from Surreal onloadAdd()") })</script>
<script>onloadAdd(()=>{ console.log("I added to onload without clobbering the previous function") })</script>
<!-- Check the code! -->
<button class="blue">😺 Visit the source code for this page.
<script>
me().on("click", ev => { window.location.href ="https://github.com/gnat/surreal/blob/main/example.html" })
</script>
</button>
</body>
<style>
/* stylesheet.css */
html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6,label {
margin: 0;
padding: 0;
font-family: sans-serif;
}
button,input,select,textarea {
margin: 0;
font: inherit;
}
html {
font-size: 10px; /* 1.8 rem = 18px */
text-size-adjust: none; /* Fixes chrome on mobile. */
-webkit-text-size-adjust: none; /* Fixes safari on mobile. */
-moz-text-size-adjust: none; /* Firefox works fine, but for consistency. */
background: #adadad;
}
/* Custom for showcase. */
body {
font-family: system-ui, sans-serif;
font-size: 2rem;
padding: 1rem;
background: #adadad;
color: #ccc;
perspective: 1500px;
}
.active {
background: hsl(345deg 100% 47%);
transition: background 3s;
}
.inactive {
background: grey;
transition: background 3s;
}
body > div {
color: #222;
margin: 1rem;
padding: 1rem;
border-radius: 1rem;
}
body div[thick] {
color: #222;
margin: 2rem;
padding: 3rem;
border-radius: 1rem;
background: #eee;
}
body div[thick] div[thick] {
background: #ccc;
}
button {
cursor: pointer;
color: #fff;
padding: 2rem 3rem;
margin: 2rem;
border: none;
background: hsl(262deg 86% 47%);
border-bottom: 0.5rem solid hsl(262deg 86% 28%);
border-radius: 12px;
text-shadow: 0 2px #222222AA;
}
button:active {
transform: translateY(0.2rem);
}
button.blue {
background: hsl(200deg 100% 47%);
border: none;
border-bottom: 0.5rem solid hsl(200deg 100% 28%);
}
button.invisible {
opacity: 0.2;
background: hsl(147, 60%, 50%);
border-bottom: 0.5rem solid hsl(147 80% 28%);
}
button.close {
background: hsl(345deg 90% 40%);
border-bottom: 0.5rem solid hsl(345deg 100% 28%);
border-radius: 12px;
}
button.close:disabled {
color: #aaa;
background: hsl(345deg 0% 30%);
border-bottom: 0.5rem solid hsl(345deg 0% 18%);
transform: translateY(0.2rem);
}
.card {
position: relative;
width: 300px;
height: 400px;
padding: 1em;
margin: 2em auto;
font-weight: bold;
text-align: right;
text-shadow: 0 0 4px #000;
color: #ddd;
box-shadow: 0 1px 5px #00000099;
border-radius: 10px;
background: #999 center;
background-size: cover;
cursor: pointer;
transition-duration: 300ms;
transition-property: transform, box-shadow;
transition-timing-function: ease-out;
transform: rotate3d(0);
}
.card :hover {
transition-duration: 150ms;
box-shadow: 0 5px 20px 5px #00000044;
}
.card > div {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
border-radius: 10px;
background-image: radial-gradient(circle at 90% -20%, #ffffff33, #0000000f);
}
</style>
</html>