-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathuse.html
582 lines (517 loc) · 19.1 KB
/
use.html
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
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
<!doctype html><html lang="en">
<head><title>darth-fader</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#000" />
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link id="luckiestFont" href="https://fonts.googleapis.com/css?family=Luckiest+Guy" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="demoStyles.css">
<script id="darthScript" src="darth-fader.js"></script>
</head>
<body>
<div id="holder">
<div id="face" class="qr" style="text-align: center;">
<i style="font-size:25px;font-family:'luckiest guy'">
How do you feel<br class="mobr"> about programming?
</i><br>
<svg id="svg0"
viewbox="0 0 220 340"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<g
transform="scale(2.2) translate(-50 -25)"
fill-rule="evenOdd"
>
<path
id="boxPath"
d="M50 50Q45 100 50 150Q100 155 150 150Q155 100 150 50Q100 45 50 50Z"
style="
stroke: rgb(102,102,102);
stroke-width: 10;
stroke-linejoin: miter;
stroke-miterlimit: 10;
fill: rgb(255,255,255);
"
/>
<path
id="mouthPath"
d="M72 80q30 5 63 0q-8 20 0 22q-30 3 -64 0q0 -9 -3 -18l-8 4q5 -3 14 -14Z"
style="
fill: rgb(102,102,102);
"
/>
</g>
</svg>
<div id="fadDiv" style="text-align:center;">
<input
id="svgFader"
style="width:300px;"
type="range"
data-fade="
levels : ['-100', 0, '100', 1],
colors : [
'rgb(128, 0, 128)', 0.0,
'rgb(128, 0, 128)', 0.4,
'rgb(190, 190, 190)', 0.5,
'rgb(255, 180, 0)', 0.6,
'rgb(255, 180, 0)', 1.0
],
facePaths : [
'M0 40Q72 100 0 160Q100 122 200 160Q128 100 200 40Q100 72 0 40Z', 0,
'M50 50Q45 100 50 150Q100 155 150 150Q155 100 150 50Q100 45 50 50Z', 0.5,
'M50 0Q72 100 50 180Q100 220 150 180Q128 100 150 0Q100 20 50 0Z', 1
],
mouthPaths : [
'M52 75q35 37 88 0q26 23 0 46q-28 -50 -86 0q-20 -20 -3 -43l-10 8q6 -18 18 -13Z', 0,
'M52 75q47 30 88 0q24 23 0 46q-43 -43 -86 0q-15 -20 -3 -43l-10 8q6 -18 18 -13Z', 0.05,
'M72 80q30 5 63 0q-8 20 0 22q-30 3 -64 0q0 -9 -3 -18l-8 4q5 -3 14 -14Z', 0.5,
'M75 50q20 5 57 0q-20 60 0 92q-30 30 -60 0q4 -60 0 -88l-12 2q10 -2 18 -14Z', 1
],
strokeColors : [
'rgb( 80, 0, 80)', 0.0,
'rgb( 80, 0, 80)', 0.4,
'rgb(102,102,102)', 0.5,
'rgb(208,111, 15)', 0.6,
'rgb(208,111, 15)', 1.0
]
"
data-fade-opts="snap:'facePaths',thumb:'colors'"
/>
</div>
</div>
<hr>
<div id="intro" class="qr">
<b>darth-fader.js</b> adds a customizable
<i>onfade event</i>
to any specified <input type=range>
element in a page;
listen for and handle the event like any other
<br><br>
include the script, then add a stop-point list
of fade arrays in a data-param, and listen for the
default <i>fade</i> event;
the following is a simple example
</div>
<div id="simpleExample" class="qr">
<pre>
<script src="darth-fader.js"></script>
<div id="sampleDiv"></div>
<input id="fader0" type="range" data-fade="
color : [
'rgb(255, 255, 0)', 0,
'rgb(255, 0, 0)', 0.25,
'rgb(255, 255, 255)', 0.50,
'rgb( 0, 255, 255)', 0.75,
'rgb(255, 0, 255)', 1
],
size : [
' 20px', 0,
'100px', 0.5,
'380px', 1
]
"/>
<script>
fader0.addEventListener('fade',
(e, vals=e.detail) => {
sampleDiv.style.backgroundColor = vals.color;
sampleDiv.style.width = vals.size;
}
);
</script>
</pre>
<br>
the <i>event.detail</i> of the fade event contains
a property for every listed fade in that input element
- for example, if you create a fade called 'height'
you would access the current interpolated value
from the handler's <i>event.detail.height</i> property
<br><br>
each <input> element contains a list
of arrays to fade through;
they are specified as a <i>name</i> for
that array, followed by a <i>colon</i>,
then an array in <i>hard-brackets</i>;
the array consists of string-percent pairs:
a <i>string</i> for the desired value, and a
<i>float percent</i> as the stop-point
for that value
<br><br>
<dd><i>
name : ['value', %, 'value', %, ... ]
</i></dd>
<br>
values are entered as a string
in <i>single</i> quotes - any numbers will
be extracted from the string and converted
to actual numbers - separate arrays with a comma
<br><br>
every fade added to the input's param also
creates an <input type="hidden">
element that will get submitted with the form -
the hidden input will be assigned an <i>id</i>
that is the darth-fader input's id, combined by an
<i>underscore</i> to the fade's name
<br><br>
in the above example, <i>fader0</i> created
two hidden inputs, one named
<i>fader0_color</i> and another with the id
<i>fader0_size</i>; besides being submitted
with any form, the current value of a fade
can also be accessed from the darth-fader's
hidden inputs
<br><br>
</div>
<div id="form0" class="qa">
<div id="quiz" style="text-align:center;font-style:italic;">
how do you feel about question one?<br>
<input id="ques1" type="range" style="--thumbH:20px;"
data-fade="
sentiment:['bad',0,'ok',0.33,'good',0.66,'good',1],
color : [
'hsl(0, 0%, 0%)', 0,
'hsl(0, 0%, 60%)', 1
]
"
data-fade-opts="thumb:'color',ignore:'color'"
/>
what about question two?<br>
<input id="ques2" type="range" style="--thumbH:20px;"
data-fade="
temperature: ['HOT!',0,'warm',0.33,'cold',0.66],
color : [
'hsl(40, 80%, 0%)', 0,
'hsl(40,100%,100%)', 1
]
"
data-fade-opts="thumb:'color',ignore:'color'"
/>
think about question three...<br>
<input id="ques3" type="range" style="--thumbH:20px;"
data-fade="
intensity : [
'strong negative', 0.0,
'weakly negative', 0.2,
'no preference', 0.4,
'weakly positive', 0.6,
'strong positive', 0.8,
'strong positive', 1.0
],
color : [
'hsl(300, 80%, 0%)', 0,
'hsl(300,100%,100%)', 1
]
"
data-fade-opts="thumb:'color',ignore:'color'"
/>
<p>
<input id="butt0" type="button" value="bite here"
style="height:30px;width:100%;"
/></p>
</div>
<div id="formResults" style="text-align:right;">
[[form results]]
</div>
</div>
<div id="options" class="qr">
there are many different options which may
be configured - <i>darth-fader.js</i> itself
has defaults that may be overwritten by
the script tag's <i>data-param</i>;
any options may also be specified by the
individual darth-fader's <i>data-param</i>
<br><br>
let's take a look at an example of that
<br><br>
<pre>
<!--
options in the script tag data-parameter
become defaults for all darth-fader elements
here they are being set to what the default
values would be anyway, just so that you
can see what those values are
-->
<script src="darth-fader.js" data-fade="
selector : 'fade',
eventName : 'fade',
thumb : false,
snap : false,
steps : false,
fix : false,
ignore : false
"></script>
<!--
options can be overwritten in the element
-->
<input id="faderX" type="range"
data-fade="
price : ['$200', 0, '$1800', 1],
colors : [
'rgb(200, 100, 0)', 0,
'rgb(225, 175, 0)', 0.25,
'rgb(255, 255, 255)', 0.5,
'rgb(200, 0, 200)', 0.75,
'rgb(100, 0, 100)', 1
],
"
data-fade-opts="
eventName : 'faderXevent',
thumb : 'colors',
fix : 2
"
/>
</pre>
<br>
alright, this will fade between several different
colors, aswell as between the prices of
<i>two hundred dollars</i> and
<i>eighteen hundred dollars</i> - but what do
all of these options mean?
<ul>
<li><b>selector</b> : this is what needs to follow
<i>data-</i> in the parameter in order for
<i>darth-fader.js</i> to recognize the element
as a darth fader; by default, anything with
<i><input data-fade></i> will be selected;
it can be any <i>string</i>
</li>
<br>
<li><b>eventName</b> : the name of the event that
handlers need to listen for - by default, this is
also <i>fade</i>; in the example, <i>faderX</i>
has changed only its specific event's name to
<i>faderXevent</i>
</li>
<br>
<li><b>thumb</b> : designates, by <i>string</i>,
the name of the fade that should be used to
color the <i>thumb</i> of the slider element;
in this example, the <i>colors</i> fade is
being used to color the thumb - this can also
be the boolean value <i>true</i>, in which case
<i>darth-fader.js</i> will color the thumb
using default colors
</li>
<br>
<li><b>snap</b> : this is the <i>string</i>
name of the fade whose values you would like
the slider to snap at - <i>darth-fader.js</i>
will create a <i>datalist</i> element and use
that to snap the slider to the apropos values
denoted by the percentage stop-points of the fade
</li>
<br>
<li><b>steps</b> : if, for some reason, you would
like the slider to move only in discreet steps,
set this value to the <i>string</i> name of
a fade and the slider will only move in as many
steps as there are percent-values in that fade;
alternatively, set this value to an <i>integer</i>
number of steps
</li>
<br>
<li><b>fix</b> : if you want all numerically fadded
values to be only a fixed number of decimal places
long, enter the <i>integer</i> that specifies how
many decimal places each numerical value should have;
in this example, <i>faderX</i> has indicated
<i>two</i> decimal places, likely because of the
<i>price</i> fader using monetary values
</li>
<br>
<li><b>ignore</b> : by default, all fades listed
in the data-param have a <i>hidden input</i>
element automatically created for them - these
hidden inputs are, ofcourse, form elements whose
values will get submitted if you use a darth-fader
in a form - this <i>string</i> is a comma-separated
list of the names of any fades for which you do NOT
want to have a hidden input element
</li>
<br>
</ul>
</div>
<hr>
<div id="anystring" class="qa">
<div>
<i>darth-fader.js</i> will do anything in his power
to find values and extrapolate between them
<br><br>
it should be, therefore, possible to
fade gradually through <i>sentences</i> ...
<br><br>
<input id="anystringFader" type="range" value="100"
style="--thumbH:100px;"
data-fade="
sentence: [
'In 30 days, I will lose 10 pounds, and over $50', 0.0,
'In 8 weeks, I will gain 40 pounds, and earn $250', 0.5,
'In 12 weeks, I will gain 70 pounds, and earn $1200', 1.0
]
"
data-fade-opts="fix:2"
/>
</div>
<div><i id="anystringOutput" style="
color: #fff;
font-size: 1.5em;
text-align: left;
">
[[see my weightloss goals]]
</i></div>
</div>
<br><br>
<div id="svgstring" class="qb">
<div style="text-align:center;">
<svg
viewbox="-50 -50 100 100"
height="200"
width="200"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
style="overflow: visible;"
>
<g transform="scale(1.1, 1.1) translate(0, 0)">
<path id="svgstringOutput" d=""/>
</g>
</svg>
</div>
<div>
and, ofcourse, this makes strings like the
<i>d</i> attribute of an svg <i>path</i>
element something that can be easily faded,
producing a morph
<br><br>
<input id="svgstringFader" type="range" style="--thumbH:100px;"
value=0
data-fade="
path : [
'M -30 -30 Q 0 -10 30 -30 Q 20 -11 30 40 Q 12 20 -35 45 Q -50 0 -30 -30Z', 0,
'M -45 -32 Q 0 -40 50 -28 Q 28 10 64 50 Q 12 80 -25 70 Q -25 -10 -45 -32Z', 1
]
"
data-fade-opts="thumb:true,steps:5"
/>
</div>
</div>
<br><br>
<div id="outro" class="qr">
there is a <a href="darth-fader.min.js">minified version</a>
that, for now, is just automatically minified by an
online minifier - eventually, there ought to be a more terse
version, intentionally designed to be as small as possible
<br><br>
if you are happy with the defaults, you can simply
include the <i>darth-fader.js</i> script, label any
inputs with a <i>data-fade</i> or
<i>data-fade-opts</i> parameter,
and write handlers for the <i>fade</i> event
<br><br>
<pre>
<script src="darth-fader.js"></script>
<input data-fade-opts="thumb:true,steps:5">
</pre>
<br>
<i>darth-fader.js</i> will look for any <input>
that has either <i>data-fade</i> or <i>data-fade-opts</i>;
if the only information given is the
<i>thumb:true</i> option, the script automatically
creates a thumb-coloring slider
</div>
<hr>
<div id="altview" class="qr">
<div style="height:100px"></div>
<div id="cap0"
data-ques="What do you think about my alternative view?"
style="width:100%;text-align:center;font-style:italic;color:#fff;"
>
What do you think about my alternative view?
</div>
<br>
<input id="slide0" type="range"
data-fade="
level : ['-1000',0,'1000',1],
statement : [
' that you are right', 0,
' that your opinion is evil', 0.5
],
response : [
'strongly DISagree!!!', 0.0,
'strongly DISagree', 0.01,
'kinda disagree', 0.2,
'could care less', 0.4,
'somewhat agree', 0.6,
'strongly AGREE', 0.8,
'strongly AGREE!!!', 0.999
],
thumb : [
'rgb(200,100, 0)', 0,
'rgb(225,175, 0)', 0.25,
'rgb(255,255,255)', 0.5,
'rgb(200, 0,200)', 0.75,
'rgb(100, 0,100)', 1
],
fontsize : [
'3.0', 0.00,
'2.0', 0.05,
'1.4', 0.25,
'1.0', 0.50,
'1.4', 0.75,
'2.0', 0.95,
'3.0', 1.00
]
"
data-fade-opts="
thumb : 'thumb',
ignore : 'statement, response, thumb'
"
/>
</div>
<div class="signature qr">~queviva</div>
</div>
</body>
<script id="docScript">
(() => {
const Q = Object.fromEntries(
`svgFader svg0 boxPath mouthPath form0 cap0 slide0 butt0
formResults ques1 ques2 ques3
`
.trim().split(/\s+/).map(obj=>[obj,document.getElementById(obj)])
);
Q.svgFader.addEventListener('fade', (e, vals = e.detail) => {
Q.boxPath.setAttribute('d', vals.facePaths);
Q.boxPath.style.fill = vals.colors;
Q.boxPath.style.stroke = vals.strokeColors;
Q.mouthPath.style.fill = vals.strokeColors;
Q.mouthPath.setAttribute('d', vals.mouthPaths);
});
Q.svg0.addEventListener('dblclick', () => {
Q.svgFader.value = 50;
Q.svgFader.dispatchEvent(new Event('input'));
})
Q.cap0.addEventListener('click', () => {
Q.slide0.value = 50;
Q.slide0.dispatchEvent(new Event('input'));
Q.cap0.innerHTML = Q.cap0.dataset.ques;
})
Q.slide0.addEventListener('fade', (e, vals = e.detail) => {
Q.cap0.innerHTML =
`I <b style="font-size:${vals.fontsize}em;"
>${vals.response}</b> ${vals.statement}.`;
Q.cap0.style.color = vals.thumb;
});
Q.butt0.addEventListener('click', () => {
let tmp = '[[form results]]';
Q.form0.querySelectorAll('input:not([type="button"])')
.forEach(p => tmp += ('<br>' + p.id + ' ::: ' + p.value));
Q.formResults.innerHTML = tmp;
});
anystringFader.addEventListener('fade', (e, vals=e.detail) => {
anystringOutput.innerHTML = vals.sentence;
});
svgstringFader.addEventListener('fade', (e, vals=e.detail) => {
svgstringOutput.setAttribute('d', vals.path);
svgstringOutput.setAttribute('fill', vals.thumb);
});
})();
</script>
</html>