UNPKG

14.5 kBHTMLView Raw
1<!DOCTYPE html>
2<!--
3
4
5 ~~~ Демонстрация возможностей FileAPI ~~~
6
7
8-->
9<html>
10<head>
11 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
12 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
13
14 <title>FileAPI :: Demo :: example</title>
15
16 <meta name="viewport" content="user-scalable=no, width=400, initial-scale=0.8, maximum-scale=0.8" />
17 <meta name="apple-mobile-web-app-capable" content="yes" />
18 <meta name="apple-mobile-web-app-status-bar-style" content="yes" />
19 <meta name="format-detection" content="email=no" />
20 <meta name="HandheldFriendly" content="true" />
21
22 <script src="//yandex.st/jquery/1.8.2/jquery.min.js"></script>
23 <script>if( !window.jQuery )document.write('<script src="/js/jquery.dev.js"><'+'/script>');</script>
24
25 <script>
26 var FileAPI = {
27 debug: true
28 , staticPath: '../dist/'
29 };
30 </script>
31 <script src="../dist/FileAPI.min.js"></script>
32 <script src="../plugins/FileAPI.id3.js"></script>
33 <script src="../plugins/FileAPI.exif.js"></script>
34
35 <script>
36 // Simple JavaScript Templating
37 // John Resig - http://ejohn.org/ - MIT Licensed
38 (function (){
39 var cache = {};
40
41 this.tmpl = function tmpl(str, data){
42 // Figure out if we're getting a template, or if we need to
43 // load the template - and be sure to cache the result.
44 var fn = !/\W/.test(str) ?
45 cache[str] = cache[str] ||
46 tmpl(document.getElementById(str).innerHTML) :
47
48 // Generate a reusable function that will serve as a template
49 // generator (and which will be cached).
50 new Function("obj",
51 "var p=[],print=function(){p.push.apply(p,arguments);};" +
52
53 // Introduce the data as local variables using with(){}
54 "with(obj){p.push('" +
55
56 // Convert the template into pure JavaScript
57 str
58 .replace(/[\r\t\n]/g, " ")
59 .split("<%").join("\t")
60 .replace(/((^|%>)[^\t]*)'/g, "$1\r")
61 .replace(/\t=(.*?)%>/g, "',$1,'")
62 .split("\t").join("');")
63 .split("%>").join("p.push('")
64 .split("\r").join("\\'")
65 + "');}return p.join('');");
66
67 // Provide some basic currying to the user
68 return data ? fn(data) : fn;
69 };
70 })();
71 </script>
72
73 <style>
74 body {
75 font-size: 15px;
76 font-family: "Helvetica Neue";
77 }
78
79 .b-button {
80 display: inline-block;
81 *display: inline;
82 *zoom: 1;
83 position: relative;
84 overflow: hidden;
85 cursor: pointer;
86 padding: 4px 15px;
87 vertical-align: middle;
88 border: 1px solid #ccc;
89 border-radius: 3px;
90 background-color: #f5f5f5;
91 background: -moz-linear-gradient(top, #fff 0%, #f5f5f5 49%, #ececec 50%, #eee 100%);
92 background: -webkit-linear-gradient(top, #fff 0%,#f5f5f5 49%,#ececec 50%,#eee 100%);
93 background: -o-linear-gradient(top, #fff 0%,#f5f5f5 49%,#ececec 50%,#eee 100%);
94 background: linear-gradient(to bottom, #fff 0%,#f5f5f5 49%,#ececec 50%,#eee 100%);
95 -webkit-user-select: none;
96 -moz-user-select: none;
97 user-select: none;
98 }
99 .b-button_hover {
100 border-color: #fa0;
101 box-shadow: 0 0 2px #fa0;
102 }
103
104 .b-button__text {
105 }
106
107 .b-button__input {
108 cursor: pointer;
109 opacity: 0;
110 filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
111 top: -10px;
112 right: -40px;
113 font-size: 50px;
114 position: absolute;
115 }
116
117
118 #preview {
119 max-width: 600px;
120 box-shadow: 0 1px 3px rgba(0,0,0,.4);
121 border-radius: 3px;
122 }
123 .b-file {
124 height: 40px;
125 padding: 5px;
126 position: relative;
127 overflow: hidden;
128 border-radius: 3px;
129 background-color: #fcfcfc;
130 background: -webkit-linear-gradient(top, #fcfcfc 0%, #f6f6f6 100%);
131 background: -moz-linear-gradient(top, #fcfcfc 0%, #f6f6f6 100%);
132 background: -o-linear-gradient(top, #fcfcfc 0%, #f6f6f6 100%);
133 background: linear-gradient(to bottom, #fcfcfc 0%, #f6f6f6 100%);
134 clear: both;
135 }
136 .b-file__left {
137 float: left;
138 margin: 1px 0 0 2px;
139 line-height: 0;
140 }
141 .b-file__left_border {
142 border: 2px solid #fff;
143 border-radius: 4px;
144 }
145
146 .b-file__right {
147 margin-left: 45px;
148 }
149
150 .b-file__name {
151 color: #36c;
152 cursor: pointer;
153 border-bottom: 1px dotted #36c;
154 text-decoration: none;
155 }
156 .b-file__name:hover {
157 color: #f00;
158 border-bottom-color: #f00;
159 }
160
161 .b-file__info {
162 color: #666;
163 position: absolute;
164 font-size: 12px;
165 margin-top: 3px;
166 }
167
168 .b-file__bar {
169 padding-top: 4px;
170 }
171
172 .b-file__error {
173 color: #c00;
174 }
175 .b-file__done {
176 color: #458383;
177 }
178 .b-file__abort {
179 top: 10px;
180 right: 20px;
181 width: 15px;
182 height: 15px;
183 position: absolute;
184 color: #c00;
185 cursor: pointer;
186 font-size: 20px;
187 display: none;
188 }
189 .b-file_upload .b-file__abort { display: block; }
190
191 .b-progress {
192 width: 200px;
193 height: 10px;
194 border: 2px solid #E2E4E2;
195 border-radius: 10px;
196 box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
197 background-color: #d3d3d3;
198 position: relative;
199 }
200 .b-progress__bar {
201 width: 0;
202 height: 10px;
203 border-radius: 10px;
204 background-color: #2D9DD7;
205 background: -webkit-linear-gradient(top, #2D9DD7 0%, #1C81C7 100%); /* FF3.6+ */
206 background: -moz-linear-gradient(top, #2D9DD7 0%, #1C81C7 100%); /* FF3.6+ */
207 background: linear-gradient(to bottom, #2D9DD7 0%, #1C81C7 100%); /* FF3.6+ */
208 -webkit-transition: width .5s ease-out;
209 -moz-transition: width .5s ease-out;
210 -ms-transition: width .5s ease-out;
211 transition: width .5s ease-out;
212 }
213
214 .b-dropzone,
215 .b-dropzone__bg {
216 top: 0;
217 left: 0;
218 right: 0;
219 bottom: 0;
220 z-index: 30000;
221 position: absolute;
222 }
223 .b-dropzone__bg {
224 opacity: .2;
225 background-color: #2D9DD7
226 }
227 .b-dropzone__txt {
228 color: #1C81C7;
229 text-shadow: 0 2px 1px #113C53;
230 font-size: 400%;
231 font-weight: bold;
232 text-align: center;
233 width: 500px;
234 top: 50%;
235 left: 50%;
236 margin: -100px 0 0 -250px;
237 z-index: 30001;
238 position: absolute;
239 }
240
241 .b-layer {
242 border: 3px solid #fff;
243 border-radius: 5px;
244 box-shadow: 0 1px 30px #000;
245 background-color: #f3f3f3;
246 top: 50px;
247 left: 50%;
248 z-index: 30002;
249 position: absolute;
250 margin-left: -150px;
251 margin-bottom: 100px;
252 }
253 .b-layer__h1 {
254 color: #fff;
255 padding: 10px 10px;
256 width: 300px;
257 overflow: hidden;
258 background-color: #2D9DD7;
259 }
260 .b-layer__img {
261 padding: 5px 10px;
262 text-align: center;
263 border-top: 2px solid #fff;
264 }
265 .b-layer__info {
266 padding: 2px 15px;
267 border-top: 2px solid #fff;
268 }
269 .b-layer__info div {
270 width: 280px;
271 overflow: hidden;
272 white-space: nowrap;
273 }
274
275
276 </style>
277
278</head>
279<body>
280 <div style="left: 0; right: 0; bottom: 0; position: fixed; box-shadow: 0 0 5px rgba(0,0,0,.65); background-color: #f3f3f3;">
281 <div style="padding: 5px 10px 10px">
282 <a href="../">&larr; index</a> |
283 <b>demo</b> -
284 <a href="./userpic.html">userpic</a> -
285 <a href="./thumbnails.html">thumbnails</a> -
286 <a href="./watermark.html">watermark</a> -
287 <a href="./webcam.html">webcam</a> -
288 <a href="./caman.html">caman.js</a>
289 </div>
290 </div>
291
292 <div id="drop-zone" class="b-dropzone" style="display: none">
293 <div class="b-dropzone__bg"></div>
294 <div class="b-dropzone__txt">Drop files there</div>
295 </div>
296
297 <div id="oooops" style="display: none; margin: 10px; padding: 10px; border: 2px solid #f60; border-radius: 4px;">
298 Увы, ваш браузер не поддерживает html5 и flash,
299 поэтому смотреть тут нечего, а iframe не даёт всей красоты :]
300 </div>
301
302 <div id="buttons-panel">
303 <div class="b-button js-fileapi-wrapper">
304 <div class="b-button__text">Upload one file</div>
305 <input name="files" class="b-button__input" type="file" />
306 </div>
307
308 <div class="b-button js-fileapi-wrapper">
309 <div class="b-button__text">Multiple</div>
310 <input name="files" class="b-button__input" type="file" multiple />
311 </div>
312
313 <div class="b-button js-fileapi-wrapper">
314 <div class="b-button__text">jpg, jpeg & gif</div>
315 <input name="files" class="b-button__input" type="file" accept="image/*" multiple />
316 </div>
317
318 <span id="drag-n-drop" style="display: none; padding: 0 30px">
319 or &nbsp; &nbsp; drag'n'drop
320 </span>
321 </div>
322
323 <div id="preview" style="margin-top: 30px"></div>
324
325 <script id="b-file-ejs" type="text/ejs">
326 <div id="file-<%=FileAPI.uid(file)%>" class="js-file b-file b-file_<%=file.type.split('/')[0]%>">
327 <div class="js-left b-file__left">
328 <img src="<%=icon[file.type.split('/')[0]]||icon.def%>" width="32" height="32" style="margin: 2px 0 0 3px"/>
329 </div>
330 <div class="b-file__right">
331 <div><a class="js-name b-file__name"><%=file.name%></a></div>
332 <div class="js-info b-file__info">size: <%=(file.size/FileAPI.KB).toFixed(2)%> KB</div>
333 <div class="js-progress b-file__bar" style="display: none">
334 <div class="b-progress"><div class="js-bar b-progress__bar"></div></div>
335 </div>
336 </div>
337 <i class="js-abort b-file__abort" title="abort">&times;</i>
338 </div>
339 </script>
340
341 <script id="b-layer-ejs" type="text/ejs">
342 <div class="b-layer">
343 <div class="b-layer__h1"><%=file.name%></div>
344 <div class="js-img b-layer__img"></div>
345 <div class="b-layer__info">
346 <%
347 FileAPI.each(info, function(val, key){
348 if( Object.prototype.toString.call(val) == '[object Object]' ){
349 var sub = '';
350 FileAPI.each(val, function (val, key){ sub += '<div>'+key+': '+val+'</div>'; });
351 if( sub ){
352 %><%=key%><div style="margin: 0 0 5px 20px;"><%=sub%></div><%
353 }
354 } else {
355 %>
356 <div><%=key%>: <%=val%></div>
357 <%
358 }
359 });
360 %>
361 </div>
362 </div>
363 </script>
364
365
366 <script type="text/javascript">
367 jQuery(function ($){
368 if( !(FileAPI.support.cors || FileAPI.support.flash) ){
369 $('#oooops').show();
370 $('#buttons-panel').hide();
371 }
372
373 $(document).on('mouseenter mouseleave', '.b-button', function (evt){
374 $(evt.currentTarget).toggleClass('b-button_hover', evt.type == 'mouseenter');
375 });
376
377
378 if( FileAPI.support.dnd ){
379 $('#drag-n-drop').show();
380 $(document).dnd(function (over){
381 $('#drop-zone').toggle(over);
382 }, function (files){
383 onFiles(files);
384 });
385 }
386
387
388 $('input[type="file"]').on('change', function (evt){
389 var files = FileAPI.getFiles(evt);
390 onFiles(files);
391 FileAPI.reset(evt.currentTarget);
392 });
393
394
395 var FU = {
396 icon: {
397 def: '//cdn1.iconfinder.com/data/icons/CrystalClear/32x32/mimetypes/unknown.png'
398 , image: '//cdn1.iconfinder.com/data/icons/humano2/32x32/apps/synfig_icon.png'
399 , audio: '//cdn1.iconfinder.com/data/icons/august/PNG/Music.png'
400 , video: '//cdn1.iconfinder.com/data/icons/df_On_Stage_Icon_Set/128/Video.png'
401 },
402
403 files: [],
404 index: 0,
405 active: false,
406
407 add: function (file){
408 FU.files.push(file);
409
410 if( /^image/.test(file.type) ){
411 FileAPI.Image(file).preview(35).rotate('auto').get(function (err, img){
412 if( !err ){
413 FU._getEl(file, '.js-left')
414 .addClass('b-file__left_border')
415 .html(img)
416 ;
417 }
418 });
419 }
420 },
421
422 getFileById: function (id){
423 var i = FU.files.length;
424 while( i-- ){
425 if( FileAPI.uid(FU.files[i]) == id ){
426 return FU.files[i];
427 }
428 }
429 },
430
431 showLayer: function (id){
432 var $Layer = $('#layer-'+id), file = this.getFileById(id);
433
434 if( !$Layer[0] ){
435 $Layer = $('<div/>').appendTo('body').attr('id', 'layer-'+id);
436 }
437
438 $Layer.css('top', $(window).scrollTop() + 30);
439
440 FileAPI.getInfo(file, function (err, info){
441 $Layer
442 .click(function (){ $(document).click(); })
443 .html(tmpl($('#b-layer-ejs').html(), {
444 file: file
445 , info: $.extend(err ? {} : info, { size: (file.size/1024).toFixed(3) + ' KB' })
446 }))
447 ;
448
449 if( /image/i.test(file.type) ){
450 if( err ){
451 $Layer.find('.js-img').html('Ooops.');
452 }
453 else {
454 FileAPI.Image(file).preview(300).get(function (err, img){
455 $Layer.find('.js-img').append(img);
456 });
457 }
458 } else {
459 $Layer.find('.js-img').remove();
460 }
461
462 $(document).off('click.layer keyup.layer').one('click.layer keyup.layer', function (evt){
463 $Layer.remove();
464 });
465 });
466 },
467
468 start: function (){
469 if( !FU.active && (FU.active = FU.files.length > FU.index) ){
470 FU._upload(FU.files[FU.index]);
471 }
472 },
473
474 abort: function (id){
475 var file = this.getFileById(id);
476 if( file.xhr ){
477 file.xhr.abort();
478 }
479 },
480
481 _getEl: function (file, sel){
482 var $el = $('#file-'+FileAPI.uid(file));
483 return sel ? $el.find(sel) : $el;
484 },
485
486 _upload: function (file){
487 if( file ){
488 file.xhr = FileAPI.upload({
489 url: '/upload',
490 files: { file: file },
491 upload: function (){
492 FU._getEl(file).addClass('b-file_upload');
493 FU._getEl(file, '.js-progress')
494 .css({ opacity: 0 }).show()
495 .animate({ opacity: 1 }, 100)
496 ;
497 },
498 progress: function (evt){
499 FU._getEl(file, '.js-bar').css('width', evt.loaded/evt.total*100+'%');
500 },
501 complete: function (err, xhr){
502 var state = err ? 'error' : 'done';
503
504 FU._getEl(file).removeClass('b-file_upload');
505 FU._getEl(file, '.js-progress').animate({ opacity: 0 }, 200, function (){ $(this).hide() });
506 FU._getEl(file, '.js-info').append(', <b class="b-file__'+state+'">'+(err ? (xhr.statusText || err) : state)+'</b>');
507
508 FU.index++;
509 FU.active = false;
510
511 FU.start();
512 }
513 });
514 }
515 }
516 };
517
518 function onFiles(files){
519 var $Queue = $('<div/>').prependTo('#preview');
520
521 FileAPI.each(files, function (file){
522 if( file.size >= 25*FileAPI.MB ){
523 alert('Sorrow.\nMax size 25MB')
524 }
525 else if( file.size === void 0 ){
526 $('#oooops').show();
527 $('#buttons-panel').hide();
528 }
529 else {
530 $Queue.append(tmpl($('#b-file-ejs').html(), { file: file, icon: FU.icon }));
531
532 FU.add(file);
533 FU.start();
534 }
535 });
536 }
537
538
539 $(document)
540 .on('click', '.js-file', function (evt){
541 if( !evt.isDefaultPrevented() ){
542 FU.showLayer(evt.currentTarget.id.split('-')[1]);
543 evt.preventDefault();
544 }
545 })
546 .on('click', '.js-abort', function (evt){
547 FU.abort($(evt.target).closest('.js-file').attr('id').split('-')[1]);
548 evt.preventDefault();
549 })
550 ;
551 }); // ready
552 </script>
553
554</body>
555</html>