Задача состоит вот в чем.
Есть сайт с элементами меню, каждый элемент подгружает что-то одно:
Секвенции (Например моделька 360 состоящая из набора фотографий)
Видео
Просто картинка
Не напрягая лишним функционалом, просто сведу к минимуму:
Есть кнопка при какой необходимо, чтобы все секвенции, картинки или даже видео подгружались в памяти и при воспроизведении не глючили.
Какие самые благоприятные варианты реализовать это без лагов?
Буду рад любой помощи.
Реализовал загрузку всех изображений в кэш, лаги всё равно есть. Поэтому уже обратился сюда.
Код загрузки изображений в кэш:
!function ($) {
/**
* В поданный на вход элемент создается div, куда будут помещены изображения.
* Данную функцию вызывает массив, в каком содержаться пути к изображениям.
* @param el Элемент, куда будет помещен блок с кэшем
* @param id Уникальное имя для блока с кэшем
*/
$.fn.preload = function (el, id) {
// Если элемента с указанным идентификатором не существует, то загружаем в кэш
if (!el.find('#' + id).exists()) {
// Формируем блок, где будут лежать указанные изображения
$("
/** * Загрузка переданного элемента в кэш (Осуществляет загрузку секвенций и картинок) * @param el Dom-element * @param index Индекс массива */ function preload_item(el, index) { var id = el.attr('data-id'), // Указанный идентификатор для элемента src, // Тут будет храниться путь к картинке frames, // Кол-во фреймов, какие будут записаны в кэш arr = [], // Массив, в каком будет храниться путь к каждому изображению img_name, // Будет храниться только имя изображения с удаленным постфиксом directory; // Будет храниться папка, в какой будут все изображения
// Определяем тип контента, если секвенции, то много изображений, иначе одно изображение switch (el.attr('data-content')) { case 'sequence': src = el.attr("data-path"); frames = parseInt(el.attr('data-frames'));
// Записываем каждый путь к фрейму, для записи в кэш for (var i = 1; i < frames + 1; i++) { img_name = src.split('/')[src.split('/').length - 1]; directory = src.split('/').slice(0, -1).join("/"); arr.push(directory + "/" + img_name.split('_')[0] + "_" + i + "." + img_name.split('.')[1]) } // Записываем в кэш и передаем элемент в каком будет содержаться images_cache и уникальное имя для него $(arr).preload(content, img_name.split('_')[0] + id); break; case 'image': // Костыль небольшой. // Получаем путь к изображению где лежать с мал. разрешением и заменяем на папку, где лежать с большим разрешением. src = el.find('img').attr("src").replace('colors_small', 'colors_big');
// Формируем путь к изображению img_name = src.split('/')[src.split('/').length - 1]; directory = src.split('/').slice(0, -1).join("/"); arr.push(directory + "/" + img_name);
// Записываем в кэш и передаем те же данные $(arr).preload(content, img_name.split('.')[0] + id); break; }
// Получаем список все img, какие не успели загрузиться var images_not_loaded = $(".images_cache > img").not(function () { return this.complete; });
var count = images_not_loaded.length;
// Если кол-во > 0 if (count) { // Записываем их images_not_loaded.load(function () { count--; // Если уже нечего записывать и "левая переменная" if (!count && index === ids.length - 1 && startAnimate) { // Что-то делаем } }); } else { // Если уже нечего записывать и "левая переменная" if (index === ids.length - 1 && startAnimate) { // Что-то делаем } } }
Ответ
Загружайте изображения через new Image();
.src даст вам путь.
.onload создаст событие окончания загрузки - потом устанавливайте в требуемый вам div.
Как полагаю, часть проблем у вас от того, что вы все добавляете в DOM, что также нагружает браузер.
Как пример, используйте вот такой вариант:
var images = {}; // Массив изображений
function preload(el){
var id = el.attr('data-id');
var content = el.attr('data-content');
var obj = {
loaded: 0,
images: []
};
var src = el.attr('data-path');
/// тут непонятно как вы генерируете пути
var arr = (content === 'sequence') ? getImageUrlsFromSequenceData() : getImageUrlsFromImageData();
/// но предположим в конце у нас их будет массив arr
arr.forEach(function(item){
//создаем элемент Image
var image = new Image();
//устанавливаем событие для получения того, что оно загрузилось
//количество незагруженных вы можете получить через obj.images.length-obj.loaded
image.onLoad=getActionOnLoad(obj);
//назначаем урл
image.src=item;
//добавляем в массив
obj.images.push(image);
});
//добавляем в ссылочный массив
images[id] = obj;
}
function getActionOnLoad(obj){
return (function(){
obj.loaded++;
//тут еще можно вызывать требуемый нам каллбек, если loaded
//достигло images.length. его можно добавить в параметры прелоадера
});
}
function getImageUrlsFromSequenceData(data){
//тут вы генерируете ссылки для sequence
return [];
}
function getImageUrlsFromImageData(data){
//тут вы генерируете ссылки для Image
return [];
}
Комментариев нет:
Отправить комментарий