Pull to refresh

Comments 85

Получил изображение, оно у вас меньше 200х200 (imageSize: { minWidth: 200, minHeight: 200 }), просто не делал нотификацию.
Возможно я пропустил, но в глаза бросилось только
>«Но, увы, существуют IE ниже 10»
Можно где-нибудь добавить список поддерживаемых браузеров?
Поддержка браузерами (IE6+, Chrome 10+, FF 3.8+, Opera 10+, Safari 5+):
  • Загрузка по олному файлу — все браузеры;
  • Множественная загрузка — все браузеры с поддержкой Flash или HTML5;
  • Работа с изображениями — все браузеры с поддержкой Flash или HTML5;
  • WebCam — все браузеры с поддержкой Flash или HTML5;
  • Drag'n'Drop — только HTML5.
Добавьте детектирование возможностей. Если Drag'n'Drop не поддерживает браузер, то выдайте сообщение об этом (поведение по умолчанию с возможностью отключения).
Кстати вы заявили что «Для поддержки старых браузеров используется Flash» я расчитывал что если браузер не поддерживает Drag'n'Drop то будет использована соответствующая Flash заглушка. А это не так, не вводите людей в заблуждение.
Никто и не вводит, написано же «только HTML5» (FileAPI.support.dnd). Если вы говорите про пример на странице плагина, то это просто недоработка самого примера, обязательно поправлю.
Android 2.3.6. 1-ый раз выскочило — «отсутствуют файлы изображений». Возможно это флеш (Adobe Flash Player 11.1) тупит. Или Android как всегда
Андроид это отдельная песня, если нашли проблему, напишите таск, будет разбираться. Увы, очень многое зависит от версии и устройства.
И ведь не придерешься:
var shot = cam.shot();
Я знал что вам понравится :]
собирать бы это дело по зависимостям и разделить на amd или commonJs модули! будет время сделаю пулл реквест!
image

что ж вы так неаккуратно списки файлов подбираете :)

а за библиотеку огромное спасибо, обязательно попробую использовать в своих проектах, как раз не хватало подобного функционала.
Все файлы были загружены в ознакомительных целях и для тестирования библиотеки.
UFO just landed and posted this here
Fallout II — вполне неплохая игра, мне понравилась;
Police Squad! — для любителей Лесли Нильсена;
Adventure Time — норм;
«Стальные пещеры» — очень советую, вся трилогия великолепна, но лучше книгу, озвучка слабовата.
Не хватает выхода из режима кропа, если передумал.
Он просто выключен: closeOnEsc: false, closeOnOverlayClick: false.
Библиотека поддерживает загрузку больших файлов по частям? Дробление на клиенте на мелки фрагменты и их сборку на сервере в готовый файл?
Да, единственное чего нет, это примеров сервереной части. Но думаю в ближайшее время появится инструкция на эту тему.
Как это не удивительно, но многим пользователям не нужно низкоуровневое API

Ключевая мысль. Когда она придет в голову еще раз, глядишь, 3-й версией плагина можно будет пользоваться) Не так уж много вариантов использования загрузчика в реальных проектах (остальные либо от незнания, либо баловство). Самые распространенные представлены на демо-страничке, что обнадеживает. Очевидно, что описываются они слишком многословно, можно было бы сократить код раз в пять, или пресеты сделать. Хотелось бы видеть плагины для популярный фреймворков (ангуляр, бекбон) и, конечно, кастомизатор, чтобы пользователь, которому не нужна поддержка старых браузеров или веб-камеры мог бы сделать сборку без них. И еще, хороший тон — насильно объединять кнопку загрузки и область перетаскивания, чтобы файлы загружались при перетаскивании на кнопку.

А, вообще, спасибо за плагин!
Я не зря написал «для большинства», например мне и моим коллегам плагин не нужен (сейчас он используется только в одном месте), для большинства задач нужно именно API. Это отдельная часть библиотеки, я очень надеюсь, что найдутся люди, готовые участвовать в его развитии.

Очевидно, что описываются они слишком многословно, можно было бы сократить код раз в пять, или пресеты сделать
Мне вот неочевидно, я очень старался сделать его локаничным, если есть способ ещё сократить код, буду рад услышать как.

Хотелось бы видеть плагины для популярный фреймворков (ангуляр, бекбон) и, конечно, кастомизатор, чтобы пользователь, которому не нужна поддержка старых браузеров или веб-камеры мог бы сделать сборку без них.
Под ангуляр если и делать, то jquery.fileapi не нужен, там хватит чистого FileAPI. Сборки есть, работа с камерой — 244 строчки вместе с комментариями, так что не вижу смысла делать её опциональной.

Что нужно так это кросбраузерность, даже если какой то из браузеров не поддерживает мультизагрузки или Drag'n'Drop, то это бы детектилось подгружался нужный плагин. Чтобы всместе с файлом на сервер уходили дополнительно данные: CSRF-токен, данные авторизации и т.п. Всё это корректно работало бы и через https (у флеша там есть особенность передачи кукисов). Вот это было бы круто. А низкоуровневое апи — если идти на низкий уровень, то зачем какой-то плагин, всё сам пишешь.
Не очень понял о чем, работу с Flash и проблемы связанные с этим, я разбирал в первой статье .

А низкоуровневое апи — если идти на низкий уровень, то зачем какой-то плагин, всё сам пишешь.
Это заблуждение, практически всё, что сейчас есть в HTML5 невозможно использовать без оберток, начиная от localStorage, кончая IndexedDB.
Потихоньку пилю загрузчик для Ангуляра. Тут описал какие-то свои мысли: habrahabr.ru/post/191464/
Думаю, нужно подходить с другой стороны. Сначала собрать статистику наиболее распространенных вариантов загрузки, потом хорошенько продумать эти варианты (со стороны правильности разработки и со стороны удобства для пользователей) и заточить АПИ под них. Например, как могла бы выглядеть настройка превьюшки:

preview: {
  cropper: '200px', //область всегда квадратная, меняется только масштаб
  copyright: 'watermark.jpg' //правый нижний угол
}

Остальные 100500 настроек можно закопать в АПИ, чтобы не мозолили глаза
Не очень понял, что это за часть кода. Попробуй взять любой пример и написать его как бы вы хотели его видеть.
Мне тоже кажется, что такой многословный код со стороны пользователя библиотеки не нужен. Если подумать, все действия можно было описать в декларативном стиле с параметрами. При необходимости некоторой кастомизации передавать в параметрах колбеки.

Вот мне, например, требуется такой алгоритм (пока не понял, возможен ли он с вашей либой):
1) 2 кнопки: выбрать файл | сделать фото;
2) если делаем фото, открывается снималка;
3) если выбираем файл или после сделанного фото, открывается кропалка;
4) файл заливается на сервер.

Не понял пока, можно ли совместить камеру и кроп. Хотя даже если нельзя, это не жизненно критично.

Так вот как бы я хотел это описать на JS:

var a = FileApi({
    url: 'url.php',
    max_...: ...,
    ...
});
$('#select-photo').on('click', a.delegate(['select', 'crop', 'upload']);
$('#cam').on('click', a.delegate(['cam', 'crop', 'upload']);


Я понимаю всю наивность такого подхода, но считаю, что если все круто продумать, то новых проблем это не создаст. Вот вы пользуетесь МакОсью. Наверное, знаете про ее 100500 ограничений в стиле Эппл решил что для вас лучше так, и вариантов больше нет. Но все равно все довольны (кроме мня). Так же и тут. Некоторые возможности можно закрыть, но вместо это дать на порядок более простой API, который устроит 98 % пользователей.

Конечно, в моем примере можно было вместо строк в массиве порядка действий дать хэши с параметрами (если нужно), с колбеками, которые будут делать кастомизацию. Т.е. тот АПИ, что есть сейчас, он никуда не денется, просто над ним будет офигенная обертка. Именно об этом и пишут люди в комментах. В этой ветке, и веткой выше.
Simple button
$('#simple-btn').fileapi({
   url: 'http://rubaxa.org/FileAPI/server/ctrl.php',  
   maxSize: 20 * FileAPI.MB,
   elements: {...}
});

maxQuantity: false // 1, 2, 3… максимальное количество загружаемых файлов. По-умолчанию без ограничений
onSelect: false //по умолчанию автозагрузка

Userpic + crop
$('#userpic').fileapi({
   url: 'http://rubaxa.org/FileAPI/server/ctrl.php',
   accept: ['jpg', 'png', 'gif'], //так намного понятнее, да и серверные функции чаще с конкретным типом работают
   elements: {...},
   onSelect: function (evt, file){
      if( file ){
         $('#popup').modal({
            onOpen: function (overlay){
               $(overlay).on('click', '.js-upload', function (){
                  $.modal().close();
                  $('#userpic').fileapi('upload');
               });
               $('.js-img', overlay).cropper({
                  file: file,
                  size: '200px', //по умолчанию квадрат. Остальные настройки, вообще, не нужны
                  onSelect: function (coords){
                     $('#userpic').fileapi('crop', file, coords);
                  }
               });
            }
         }).open();
      }
   }
});

imageSize: { minWidth: 200, minHeight: 200 } Изображение должно автоматом растягиваться до нужного размера

File upload
$('#file-upload').fileapi({
   onSelect: function (evt, file){
      $( '.js-send').click(function () {
         $('#file-upload').fileapi('upload'); //Загрузка по клику редкая операция, не стоит для нее создавать отдельные абстракции типа ctrl
       })
      $('.js-reset' ).click(function () {
         $('#file-upload').fileapi('abort');
      })
   }
   elements: {...}
});


Как-то так хотя бы
В статье и на сайте, я специально развернул примеры, чтобы показать возможности для кастомизации (тут их меньше половины). Даже сейчас работа с плагином может выглядеть просто `$('..').fileapi({ })` (http://jsfiddle.net/RubaXa/VEBvN/ — Simple button, File upload). Так же, ваша запись про «File upload» будет работать, только вместо «abort» -> «reset».

imageSize: { minWidth: 200, minHeight: 200 } Изображение должно автоматом растягиваться до нужного размера
На своей практике не знаю ни одного такого примера.

feedbee, чем сильней сокращаешь запись, вкладывая в параметры «глубокий смысл», тем меньше понимания у человека, который будет этим пользоваться, в конечном итоге это превратится в магию и лишении вопросы.

P.S. Это не значит, что я с вами не согласен, отнюдь, очень хочется сделать галерею примеров, где были бы уже готовые варианты использования (html + js), будет время обязательно займусь.
imageSize: { minWidth: 200, minHeight: 200 } Тут скорее хотел сказать, что не стоит отсеивать картинки по размеру (по весу — да). Тем более запрещать загрузку маленьких изображений. Если, вообще, правильно понял эту настройку.
тем меньше понимания у человека, который будет этим пользоваться
На то и расчет, что программист должен меньше напрягаться + нужно усложнить ему создание плохих дизайнерских решений + не давать настраивать то, что обычно настраивается более привычным способом (в ваших примерах это ctr вместо стандартного способа задания обработчика; bgColor, который всегда настраивается CSS и т.п.)
imageSize — это необязательный параметр, который позволяет на этапе выбора предупредить человека что выбранная им фотография (например для аватары) меньше минимальный размеров.

+ не давать настраивать то, что обычно настраивается более привычным способом (в ваших примерах это ctr вместо стандартного способа задания обработчика;
Не понял, «обычным» это каким?
Для Жиквери обычный способ это:
$('selector').click(function () {...}) или .on('type', function () {...})

Это и понятнее и гибче. Может быть разработчик по свайпу вправо захочет грузить, а по свайпу влево отменять. Вы же вводите новое понятие:
ctrl: { upload: '.js-send', reset: '.js-reset' }

Тем более для операций, которые, вообще, не стоит давать пользователям.
Мне кажется вы не понимате. Это возможность задать selector элемента управления, чтобы как раз не писать дополнительный код, который вы привели, плагин сам повесит нужные события. Это общепринятая практика, посмотрите любой iquery plugin, а лучше jQuery UI (например draggable: $( "#draggable2" ).draggable({ cancel: "p.ui-widget-header" });)
Это как раз понятно) Но встречается такое очень редко, а если и встречается, то для пары-тройки методов, так же как и у вас. Нужно ли такое упрощение? Тут, видимо, вопрос предпочтений.

В любом случае, если вынести их из объекта ctrl, хуже не будет
только вместо «abort» -> «reset».
Почему, кстати reset? В xhr называется abort, а reset будет лишний раз сбивать с толку
// Controls
ctrl: {
	upload: '[data-fileapi="ctrl.upload"]',
	reset: '[data-fileapi="ctrl.reset"]',
	abort: '[data-fileapi="ctrl.abort"]'
}
мы же говорили про пример «File upload», а там небыло abort, вот я и поправил. abort как видите тоже есть.
Интересует возможность генерации превьюшек с кропом на клиенте.

Например пользователь выбирает файл, ему предлагается кроп для превью, и на сервер отправляется 2 файла — оригинал для полноценного просмотра и кропнутая версия для превью картинки. Бывает нужно, например, когда загружаются фотографии в фотогалерею и просматривать можно фото полного размера, а превью у всех фоток фиксированного, и часто при автоматическом кропе в таких ситуациях возникает проблема «отрезанных голов» и тд
Не нашел примера с сортировкой загруженных картинок, есть ли возможность их сортировать перетаскиванием?
Есть опция sortFn для сортировки выбранных файлов перед загрузкой. То что вы хотите, не относится к тематике моего плагина, для это можно взять например jQuery UI / Sortable.
как раз хочется отсортировать перед загрузкой на сервер… эта функция отрабатывает один раз или можно сделать несколько вызовов?
Вы уж определитесь, вам до или после нужно сортировать. sortFn — сортирует выбранные файлы.
да простите, неверно выразился, все таки есть ли какое-то событие которое запускает sortFn? возможно onDrop?
Фунция выполняется в момент выбора файлов пользователем, пример при помощи диалога или drag'n'drop.
понял спасибо ) может быть добавите событие для сортировки без выбора нового файла, мне кажется это будет удобно
>FileAPI.event.on(input, «change», function (){… });
Мне кажется, здесь лучше поменять местами первые два параметра, по аналогии как метод .on() сделан у jQuery.on(). Слово «on» как бы говорит — «на событие инпута реакция такая-то» — .on('change', input, fn)
Библитека Bean с вами не согласна + в jQuery такая запись означает делегирование, могла возникнуть путаница. Да и менять уже поздно, библиотеке год.
Пробую прикрутить jquery плагин к своему проекту и возник вопрос:
— А каким образом получить сообщение об ошибке, когда пользователь пытается выбрать файл большего размера чем разрешено?
$('...').fileapi({
    onSelect: function (evt, ui){
        ui.all; // Все выбранные файлы
        ui.files; // Прошли 
        ui.other; // Не прошли условия фильтрации

        if( ui.other.length ){
             alert("Ошибка: ...");
        }
    }
});
Спасибо, а как отделить ошибку по максимальному размеру файла, от ошибки по ширине изображения?
Размер файла я могу взять из ui.other[0].size, а ширину, высоту изображения не нашел.
Высоту изображения можно получить только через FileAPI.getInfo(file, callback), давайте лучше сделаю дополнительный объект ui.errors: [{ error: "maxSize", file: {...} }, { error: "maxSize", file: {...} }]. Так буде удобнее работать.
Подскажите, пожалуйста.
Я могу каким-то образом после успешной загрузки изображений на сервер обрабатывать ответ, который получаю по url? Прикручиваю через jquery и логично что это должно быть в onComplete но что-то не могу сообразить…

В данном случае, хочется сделать дополнительную проверку на сервере, обработку и возврат html кода в нужном виде, а также переинициализацию формы для дальнейшей работы.
Спасибо. Слона то я и не заметил :).
Сразу хоче заметить, прямо сейчас нашли проблему в методах onFile*, они не работают, ошибка закралась, исправлено в dev ветке. Ближе к вечеру волью в мастер.
Да, я как раз начал тестировать на этом методе, считая что он идентичен onComplete и было не ясно. Очень приятная библиотека, спасибо вам.
Всегда пожалуйста. Если что пишите в личку или на github.
Пробую внедрить вместе с caman.js, ничего не выходит(

Я загрузил превью. Применил фильтр. Теперь в канвасе у меня готовое изображение, для загрузки на сервер.

Получаю его данные:
<code>
 FileAPI.event.on(upload, 'click', function (){
                var element = document.getElementById('result').children[0];
                if (element) {
                    var base = element.toDataURL();
                    FileAPI.upload({
                        url: 'http://localhost/FileAPI/server/ctrl.php',
                        files: { file: file },
                        upload: function (){

                        },
                        progress: function (evt){

                        },
                        complete: function (err, xhr){

                        }
                    });

                }

            });
</code>


Но АПИ не позволяет послать данные, только файл. А файл исходный, без фильтра. Надо теперь снова здорово применять фильтр? Не совсем понял как, так как файлапи.имадж — возвращает канвас, и о5 снова здорово. Что посоветуете?
Спасибо за ответ! Там же, в тестах, нашел более подходящий для меня параметр — блоб, это именно то что мне было нужно. Странно что в доке его не заметил
Потому что это не документированая возможность. Для работы с изображениями есть FileAPI.Image, его и нужно загружать как файл.
Т е вы эффект 2 раза применять советуете? 1 раз показал — потом в файл аплоад 2 раз его применил при загрузке? Я к загруженному в канвас изображению применяю всеразличные эффекты при помощи сторонних js библиотек (пока это каман, поддержка которой у вас есть, но я потом другие захочу либы, поддержки котрых у вас нет. В этом случае как я применю эффекты сторонних либ через вашу либу?). Сейчас можно так — выдрал из канваса результат и тупо сохранил его. Это же здорово. Не убирайте ее.

Еще пожелание — примеров с серверсайд побольше. Сейчас в примере с каманжс — например — сервер сайд нет. Не очень понятно как и откуда взять файл после примененного эффекта. Вернее мне совсем непонятно. Сейчас для меня выглядит как магия то как вы извлекаете из инпута файл кручу верчу загрузить хочу. Нифига непонятно. Простите за сумбур.
А как удалить (очистить) все выбранные для загрузки файлы используя jquery.fileapi?
$('.b-thumb__del').click();
пока сделал так, но это костыль
Похоже нет, нет реакции.
Версия плагина? (на данный момент 0.3.1)
Великолепная библиотека. Мне нужно было сделать resize изображения перед отсылкой на сервер и FileAPI отлично с этим справляется, без лишних телодвижений. Подскажите по поводу лицензии на библиотеку, могу ли я её использовать свободно для своих проектов? Не очень разбираюсь в лицензировании, знаю что MIT можно.
BSD, иначе говоря «Да», можно использовать, даже в коммерческих целях.
На iphone/ipad файлы автоматом поворачивается на 90 градусов. Как пофиксить?
тут скорее наоборот: автоматом не поворачиваются
При загрузке файл возрастает в несколько раз. Загружаю JPG 1.3MB, а получается на сервере 3.4MB. Можете рассказать почему так происходит?

И второй вопрос можно ли передавать исходник чтобы 1 в 1 файл получался на сервере?
Видно у вас стоят какие-то параметры обработки изображения на клиенте. Чтобы ответить тончее, нужен пример параметров загрузки и версия браузера.
Именно в jquery версии наблюдается данный момент — rubaxa.github.io/jquery.fileapi/
В НЕ jquery версии все работает отлично, файл 1 в 1 отправляется.
Первый пример «Simple button» (rubaxa.github.io/jquery.fileapi/), только в «url» пропишите не полный путь а относительный, например, "/FileAPI/server/ctrl.php", то есть все скрипты на одном сервере.
Аналогично и в Firefox 35.0.1 и в Chrome 40.0.2214.111 m (64-bit) на Windows 8 (64-bit)
Проверил и на Windows 7 (32-bit) — такое же поведение.
В плагине по умолчанию включен автоповорот, возмодно вы грузите именно такое изображние. Пришлите пример на trash@rubaxa.org

P.S. Ну и для подобных вопросов лучше использовать github/issue
Собственно всё верно, если включен автоповорот, то в независимости от реального поворота, изображение отправляется в канвас и уже он загружается на сервер. Размер увеличивается именно по этой причине. Тут нужно дорабатывать FileAPI, чтобы если изображение не изменилось, но не преобразовывать его в canvas.

Подписывайтесь на задачу: github.com/mailru/FileAPI/issues/303
Спасибо что уделили время!
С гитом ещё знакомлюсь, в следующий раз туда буду писать.
Реально ли прикрутить pako, чтобы зиповать фотки до их отправки на сервер?
Sign up to leave a comment.