-
Notifications
You must be signed in to change notification settings - Fork 149
/
index.html
535 lines (500 loc) · 24.5 KB
/
index.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
<html>
<head>
<title>Dragdealer.js – drag provider, the good stuff</title>
<meta charset="utf-8">
<meta name="description" content="Drag-based JavaScript component, embracing endless UI solutions.">
<link href="lib/jasmine.css" type="text/css" rel="stylesheet">
<link href="lib/font-awesome/css/font-awesome.min.css" type="text/css" rel="stylesheet">
<script src="lib/jquery-1.10.2.js"></script>
<script src="lib/jquery.simulate.js"></script>
<script src="lib/jasmine.js"></script>
<script src="lib/jasmine-jsreporter.js"></script>
<script src="lib/jasmine-html.js"></script>
<script src="lib/jasmine-jquery.js"></script>
<link href="src/dragdealer.css" type="text/css" rel="stylesheet">
<script src="src/dragdealer.js"></script>
<script src="spec/helpers.js"></script>
<script src="spec/matchers.js"></script>
<script src="spec/optionsSpec.js"></script>
<script src="spec/draggingSpec.js"></script>
<!--[if gt IE 9]><!-->
<script src="spec/touchDraggingSpec.js"></script>
<!--<![endif]-->
<script src="spec/callbacksSpec.js"></script>
<script src="spec/apiSpec.js"></script>
<script src="spec/resizingSpec.js"></script>
<script src="spec/eventsSpec.js"></script>
<script src="spec/setup.js"></script>
<script src="spec/browser-runner.js"></script>
<link href="demo/style/index.css" type="text/css" rel="stylesheet">
<link href="demo/style/jasmine-reporter.css" type="text/css" rel="stylesheet">
<link href="demo/style/demos.css" type="text/css" rel="stylesheet">
<script src="demo/script/index.js"></script>
<script src="demo/script/demos.js"></script>
</head>
<body>
<div id="main-slider" class="dragdealer">
<div class="specs-tab">
<ul class="specs-bullets"></ul>
<p class="specs-summary"></p>
</div>
<div class="handle red-bar">
<h1><strong>Dragdealer</strong>.js</h1>
</div>
</div>
<div id="content">
<div class="content-slides">
<div class="slide demo">
<div class="inner-wrapper">
<div class="important">
<p><strong>Jan 2014:</strong> Almost 4 years from the initial Dragdealer launch, a new version is released. For more details read the <a href="https://medium.com/p/370ff43bcb31">blog post</a> or check out the freshly baked <a href="https://github.com/skidding/dragdealer">GitHub repo.</a></p>
</div>
<h2>Drag-based JavaScript component, embracing endless UI solutions</h2>
<p>2d dragging and tapping, mouse and touch, ~12KB. No dependency. <a href="https://github.com/skidding/dragdealer/blob/master/Gruntfile.js#L2-L44">Any browser.</a></p>
<ul class="project-buttons">
<li>
<a href="https://github.com/skidding/dragdealer">
<i class="fa fa-github"></i> source code
</a>
</li>
<li>
<a href="https://github.com/skidding/dragdealer/archive/master.zip">
<i class="fa fa-cloud-download"></i> download
</a>
</li>
<li>
<a href="#demos" class="internal-link">
<i class="fa fa-magic"></i> jump to demos
</a>
</li>
</ul>
<pre class="code">
<div id="demo-simple-slider" class="<strong>dragdealer</strong>">
<div class="<strong>handle</strong> red-bar">drag me</div>
</div>
</pre>
<pre class="code">
<strong>new Dragdealer</strong>('demo-simple-slider');
</pre>
<div id="demo-simple-slider" class="dragdealer">
<div class="handle red-bar">drag me</div>
</div>
<h3>JS API</h3>
<p>Here are the options, callbacks and methods Dragdealer supports, but you can read the <a href="https://github.com/skidding/dragdealer/blob/master/src/dragdealer.js">source code</a> for more information.</p>
<h4>Constructor</h4>
<ul class="property-list">
<li>
<strong>Dragdealer(wrapper, options={})</strong>
<span class="description">Accepts an id or a DOM reference for the wrapper element. See possible options below.</span>
</li>
</ul>
<h4>Options</h4>
<ul class="property-list">
<li>
<span class="type">bool</span>
<strong>disabled</strong><span class="default">=false</span>
<span class="description">Init Dragdealer in a disabled state. The handle will have a .disabled class.</span>
</li>
<li>
<span class="type">bool</span>
<strong>horizontal</strong><span class="default">=true</span>
<span class="description">Enable horizontal dragging.</span>
</li>
<li>
<span class="type">bool</span>
<strong>vertical</strong><span class="default">=false</span>
<span class="description">Enable vertical dragging.</span>
</li>
<li>
<span class="type">number</span>
<strong>x</strong><span class="default">=0</span>
<span class="description">Initial horizontal (left) position. Accepts a float number value between 0 and 1.</span>
</li>
<li>
<span class="type">number</span>
<strong>y</strong><span class="default">=0</span>
<span class="description">Initial vertical (top) position. Accepts a float number value between 0 and 1.</span>
</li>
<li>
<span class="type">number</span>
<strong>steps</strong><span class="default">=0</span>
<span class="description">Limit the positioning of the handle within the bounds of the wrapper, by defining a virtual grid made out of a number of equally-spaced steps. This restricts placing the handle anywhere in-between these steps. E.g. setting 3 steps to a regular slider will only allow you to move it to the left, to the right or exactly in the middle.</span>
</li>
<li>
<span class="type">bool</span>
<strong>snap</strong><span class="default">=false</span>
<span class="description">When a number of steps is set, snap the position of the handle to its closest step instantly, even when dragging.</span>
</li>
<li>
<span class="type">bool</span>
<strong>slide</strong><span class="default">=true</span>
<span class="description">Slide handle after releasing it, depending on the movement speed before the mouse/touch release.</span>
</li>
<li>
<span class="type">bool</span>
<strong>loose</strong><span class="default">=false</span>
<span class="description">Loosen-up wrapper boundaries when dragging. This allows the handle to be *slightly* dragged outside the bounds of the wrapper, but slides it back to the margins of the wrapper upon release.</span>
</li>
<li>
<span class="type">number</span>
<strong>top</strong><span class="default">=0</span>
<span class="description">Top padding between the wrapper and the handle.</span>
</li>
<li>
<span class="type">number</span>
<strong>bottom</strong><span class="default">=0</span>
<span class="description">Bottom padding between the wrapper and the handle.</span>
</li>
<li>
<span class="type">number</span>
<strong>left</strong><span class="default">=0</span>
<span class="description">Left padding between the wrapper and the handle.</span>
</li>
<li>
<span class="type">number</span>
<strong>right</strong><span class="default">=0</span>
<span class="description">Right padding between the wrapper and the handle.</span>
</li>
<li>
<span class="type">fn</span>
<strong>callback(x, y)</strong>
<span class="description">Called when releasing handle, with the projected x, y position of the handle. Projected value means the value the slider will have after finishing a sliding animation, caused by either a step restriction or drag motion (see <em>steps</em> and <em>slide</em> options.)</span>
</li>
<li>
<span class="type">fn</span>
<strong>dragStopCallback(x, y)</strong>
<span class="description">Same as callback(x,y) but only called after a drag motion, not after setting the step manually.</span>
</li>
<li>
<span class="type">fn</span>
<strong>dragStartCallback(x, y)</strong>
<span class="description">Same as dragStopCallback(x,y) but called at the beginning of a drag motion and with the sliders initial x, y values.</span>
</li>
<li>
<span class="type">fn</span>
<strong>animationCallback(x, y)</strong>
<span class="description">Called every animation loop, as long as the handle is being dragged or in the process of a sliding animation. The x, y positional values received by this callback reflect the exact position of the handle DOM element, which includes exceeding values (even negative values) when the <em>loose</em> option is set true.</span>
</li>
<li>
<span class="type">string</span>
<strong>handleClass</strong><span class="default">=handle</span>
<span class="description">Custom class of handle element.</span>
</li>
<li>
<span class="type">bool</span>
<strong>css3</strong><span class="default">=true</span>
<span class="description">Use css3 transform in modern browsers instead of absolute positioning.</span>
</li>
<li>
<span class="type">fn</span>
<strong>customRequestAnimationFrame</strong>
<span class="description">Provide custom requestAnimationFrame function (used in tests).</span>
</li>
<li>
<span class="type">fn</span>
<strong>customCancelAnimationFrame</strong>
<span class="description">Provide custom cancelAnimationFrame function (used in tests).</span>
</li>
</ul>
<h4>Methods</h4>
<ul class="property-list">
<li>
<strong>disable</strong>
<span class="description">Disable dragging of a Dragdealer instance. Just as with the <em>disabled</em> option, the handle will receive a .disabled class</span>
</li>
<li>
<strong>enable</strong>
<span class="description">Enable dragging of a Dragdealer instance. The .disabled class of the handle will be removed.</span>
</li>
<li>
<strong>reflow</strong>
<span class="description">Recalculate the wrapper bounds of a Dragdealer instance, used when the wrapper is responsive and its parent container changed its size, or after changing the size of the wrapper directly.</span>
</li>
<li>
<strong>getValue</strong>
<span class="description">Get the value of a Dragdealer instance programatically. The value is returned as an [x, y] tuple and is the equivalent of the <em>projected</em> value returned by the regular callback, not animationCallback.</span>
</li>
<li>
<strong>getStep</strong>
<span class="description">Same as getValue, but the value returned is in step increments (see <em>steps</em> option)</span>
</li>
<li>
<strong>setValue(x, y, snap=false)</strong>
<span class="description">Set the value of a Dragdealer instance programatically. The 3rd parameter allows to snap the handle directly to the desired value, without any sliding transition.</span>
</li>
<li>
<strong>setStep(x, y, snap=false)</strong>
<span class="description">Same as setValue, but the value is received in step increments (see <em>steps</em> option)</span>
</li>
</ul>
<h3 id="demos">Demos</h3>
<p class="secondary">Some demos will use jQuery to manipulate surrounding elements. This is for keeping the examples as small as possible, Dragdealer doesn't have a jQuery or any other dependency.</p>
<h4>Just a slider</h4>
<p>A slider is just a user control, the power lies in the value it represents. For this reason the <strong>animationCallback</strong> is your biggest ally, with it you tie the user input to any visualization you can think of. This is the most boring example.</p>
<pre class="code">
new Dragdealer('just-a-slider', {
<strong>animationCallback</strong>: function(x, y) {
$('#just-a-slider .value').text(Math.round(<strong>x</strong> * 100));
}
});
</pre>
<div id="just-a-slider" class="dragdealer">
<div class="handle red-bar">
<span class="value"></span>%
</div>
</div>
<h4>Content scroller</h4>
<p>Controlling a different element is a straightforward use-case for Dragdealer. It's basic math. Let's spice it up with some vertical movement.</p>
<pre class="code">
var availHeight = $('.content-body').outerHeight() -
$('.content-mask').outerHeight();
new Dragdealer('content-scroller', {
horizontal: false,
<strong>vertical: true,</strong>
<strong>yPrecision: availHeight,</strong>
animationCallback: function(x, y) {
$('.content-body').css('margin-top', -<strong>y</strong> * availHeight);
}
});
</pre>
<div class="content-scroller">
<div id="content-scroller" class="dragdealer">
<div class="handle red-bar">
<span class="value"><i class="fa fa-bars"></i></span>
</div>
</div>
<div class="content-mask">
<div class="content-body">
<p>It was all a dream<br>
I used to read Word Up magazine<br>
Salt 'n' Pepa and Heavy D up in the limousine<br>
Hangin pictures on my wall<br>
Every Saturday Rap Attack, Mr. Magic, Marley Marl<br>
I let my tape rock 'til my tape popped<br>
Smoking weed and Bambu, sipping on Private Stock<br>
Way back, when I had the red and black lumberjack<br>
With the hat to match<br>
Remember Rappin Duke? duh-ha, duh-ha<br>
You never thought that hip hop would take it this far<br>
Now I'm in the limelight cause I rhyme tight<br>
Time to get paid, blow up like the World Trade<br>
Born sinner, the opposite of a winner<br>
Remember when I used to eat sardines for dinner<br>
Peace to Ron G, Brucey B, Kid Capri<br>
Funkmaster Flex, Lovebug Starski (wassup)<br>
I'm blowing up like you thought I would<br>
Call the crib, same number same hood (that's right)<br>
It's all good (it's all good)<br>
And if you don't know, now you know, nigga</p>
<p>I made the change from a common thief<br>
To up close and personal with Robin Leach<br>
And I'm far from cheap, I smoke skunk with my peeps all day<br>
Spread love, it's the Brooklyn way<br>
The Moet and Alizé keep me pissy<br>
Girls used to diss me<br>
Now they write letters cause they miss me<br>
I never thought it could happen, this rapping stuff<br>
I was too used to packing gats and stuff<br>
Now honeys play me close like butter play toast<br>
From the Mississippi down to the east coast<br>
Condos in Queens, indo for weeks<br>
Sold out seats to hear Biggie Smalls speak<br>
Living life without fear<br>
Putting 5 karats in my baby girl's ears<br>
Lunches, brunches, interviews by the pool<br>
Considered a fool cause I dropped out of high school<br>
Stereotypes of a black male misunderstood<br>
And it's still all good<br>
Uh...and if you don't know, now you know, nigga</p>
<p>Super Nintendo, Sega Genesis<br>
When I was dead broke, man I couldn't picture this<br>
50-inch screen, money green leather sofa<br>
Got two rides, a limousine with a chauffeur<br>
Phone bill about two G's flat<br>
No need to worry, my accountant handles that<br>
And my whole crew is lounging<br>
Celebrating every day, no more public housing<br>
Thinking back on my one-room shack<br>
Now my mom pimps a Ac with minks on her back<br>
And she loves to show me off, of course<br>
Smiles every time my face is up in The Source<br>
We used to fuss when the landlord dissed us<br>
No heat, wonder why Christmas missed us<br>
Birthdays was the worst days<br>
Now we sip champagne when we thirst-ay<br>
Uh, damn right I like the life I live<br>
Cause I went from negative to positive<br>
And it's all</p>
<p>...and if you don't know, now you know, niggaaa</p>
</div>
</div>
</div>
<p>The <em>yPrecision</em> option adjusts the (vertical) granularity of the callback values. It is useful when controlling an element larger than the Dragdealer wrapper, in offering a smooth transition at the end.</p>
<p class="secondary">Please note that this is not a complete solution for a custom scrollbar, nor does it try to be. You could make the content scrollable with a few lines of code but I for one think generic <em>custom scrollbars</em> are sent from hell.</p>
<h4><em>"slide to unlock"</em></h4>
<p>This is how this project started, somebody wanted an iPhone-like slider. Classic.</p>
<pre class="code">
new Dragdealer('slide-to-unlock-old', {
<strong>steps: 2,</strong>
callback: function(x, y) {
// Only 0 and 1 are the possible values because of "steps: 2"
<strong>if (x) {</strong>
this.disable();
$('#slide-to-unlock-old').fadeOut();
}
}
});
</pre>
<div class="slide-to-unlock old-slider">
<div id="slide-to-unlock-old" class="dragdealer">
<div class="slide-text">slide to unlock</div>
<div class="handle"></div>
</div>
</div>
<p>But the iPhone changed since then, iOS has a different start screen. Let's see how hard would it be to reproduce it.</p>
<pre class="code">
new Dragdealer('slide-to-unlock-new', {
<strong>x: 1,</strong>
<strong>steps: 2,</strong>
<strong>loose: true,</strong>
callback: function(x, y) {
// Only 0 and 1 are the possible values because of "steps: 2"
<strong>if (!x) {</strong>
this.disable();
$('#slide-to-unlock-new').fadeOut();
}
}
});
</pre>
<div class="slide-to-unlock new-slider">
<div id="slide-to-unlock-new" class="dragdealer">
<div class="handle">
<div class="slide-text"><i class="fa fa-angle-right"></i> slide to unlock</div>
</div>
</div>
</div>
<p>By no means do these demos try to be exact replicas, but merely to show the flexibility of Dragdealer.</p>
<p class="secondary">The latter example has the handle (the dragging object) bigger than the wrapper, which in turn has <em>overflow: hidden;</em> to mask the bigger handle surface. You should check out the HTML and CSS to understand these examples better.</p>
<h4>Image carousel</h4>
<p>Let's kick it up a notch. How about a <strong>touch-ready image carousel</strong>... piece of cake. The entire string of images will be the draggable handle, masked by a wrapper the size of a single image (a slide.)</p>
<pre class="code">
new Dragdealer('image-carousel', {
<strong>steps: 4,
speed: 0.3,
loose: true,
requestAnimationFrame: true</strong>
});
</pre>
<div id="image-carousel" class="dragdealer">
<div class="handle">
<div class="slide img1">
<div class="info">
<p class="title">Aston Martin DB4</p>
<p class="description"><strong>1959</strong> — 3.7L, 240hp</p>
</div>
</div>
<div class="slide img2">
<div class="info">
<p class="title">Mercedes-Benz 300SL</p>
<p class="description"><strong>1956</strong> — 2996cc, 212-222hp</p>
</div>
</div>
<div class="slide img3">
<div class="info">
<p class="title">Jaguar E-Type</p>
<p class="description"><strong>1966</strong> — 3.8L, 265bhp</p>
</div>
</div>
<div class="slide img4">
<div class="info">
<p class="title">Maserati A6</p>
<p class="description"><strong>1950</strong> — 2L, 120bhp</p>
</div>
</div>
</div>
</div>
<p>The <em>speed</em> option makes Dragdealer snappier, by speeding up the sliding animations. It takes up values between 0 and 1 and it defaults to 0.1.</p>
<h4>Interactive canvas mask</h4>
<p>With Dragdealer you can go from creating a simple slider to an entire website. I'm only saying this because I've seen more than a few examples of full-window implementations.</p>
<pre class="code">
var canvasMask = new Dragdealer('canvas-mask', {
x: 0,
// Start in the bottom-left corner
y: 1,
<strong>vertical: true,
speed: 0.2,
loose: true,
requestAnimationFrame: true</strong>
});
// Bind event on the wrapper element to prevent it when a drag has been made
// between mousedown and mouseup (by stopping propagation from handle)
$('#canvas-mask').on('click', '.menu a', function(e) {
e.preventDefault();
var anchor = $(e.currentTarget);
<strong>canvasMask.setValue(anchor.data('x'), anchor.data('y'));</strong>
});
</pre>
<div id="canvas-mask" class="dragdealer">
<div class="handle">
<div class="page">
<p class="menu">
<a href="#" data-x="0" data-y="1">Two-dimensional</a> |
<a href="#" data-x="1" data-y="1">Elastic</a> |
<a href="#" data-x="1" data-y="0">Interactive</a> |
<strong>Open</strong>
</p>
<p class="body">
Dragdealer is <strong>open source</strong>, <br >
see you on <a href="https://github.com/skidding/dragdealer">GitHub</a>
</p>
</div>
<div class="page">
<p class="menu">
<a href="#" data-x="0" data-y="1">Two-dimensional</a> |
<a href="#" data-x="1" data-y="1">Elastic</a> |
<strong>Interactive</strong> |
<a href="#" data-x="0" data-y="0">Open</a>
</p>
<p class="body">
The dragged surface can host <strong>rich content</strong>, <br>
including links for scrolling inside itself
</p>
</div>
<div class="page">
<p class="menu">
<strong>Two-dimensional</strong> |
<a href="#" data-x="1" data-y="1">Elastic</a> |
<a href="#" data-x="1" data-y="0">Interactive</a> |
<a href="#" data-x="0" data-y="0">Open</a>
</p>
<p class="body">
The masked content can be discovered through <br>
both <strong>horizontal and vertical dragging</strong>
</p>
</div>
<div class="page">
<p class="menu">
<a href="#" data-x="0" data-y="1">Two-dimensional</a> |
<strong>Elastic</strong> |
<a href="#" data-x="1" data-y="0">Interactive</a> |
<a href="#" data-x="0" data-y="0">Open</a>
</p>
<p class="body">
The surface boundaries have an <strong>elastic ease</strong> and <br>
the corners can be slightly pulled inwards
</p>
</div>
</div>
</div>
<p class="secondary">The previous version of Dragdealer had a major drawback for this use-case: buttons and links from inside the handle (which is the entire content) would not clickable on touch devices anymore, once Dragdealer was initialized. That is <a href="https://github.com/skidding/dragdealer/pull/7">fixed</a> now.</p>
<p class="disclaimer">Dragdealer is just a drag component, the rest is up to you.</p>
<p>© 2010+ <a href="https://twitter.com/skidding">@skidding</a> — Best regards</p>
</div>
</div>
<div class="slide specs">
<!-- Jasmine reporter goes here -->
</div>
</div>
</div>
</body>
</html>