Использование CSS-спрайтов: много раз репликация одного большого изображения обременяет клиента?

1

У меня есть забавный маленький виджет, который предлагает пользователям выбирать из списка из 114 животных. Пользовательский интерфейс включает в себя маленькие эскизы каждого вида, все одинакового размера (100x70). Общая сумма миниатюр составляет 2,1 млн.

Я не собираюсь делать 114 запросов к серверу, поэтому я использовал ImageMagick, чтобы сделать одно ОЧЕНЬ длинное изображение (11400x70), которое уменьшается до 960K. Поэтому задача состоит в том, чтобы разделить это длинное изображение на 114 маленьких изображений на клиенте. (РЕДАКТИРОВАТЬ: мне нужно, чтобы каждое животное представляло собой свое собственное изображение, потому что пользовательский интерфейс фильтрует список, например, "показывать мне только травоядных").

Первоначально у меня был сложный подход, когда я рисовал это большое изображение на холсте после загрузки строки base64 объединенного изображения, вытягивал ImageData для каждого животного, рисовал ТО на второй холст, а затем вытягивал dataURL:

var combined_canvas = document.createElement('canvas');
var combined_ctx = combined_canvas.getContext('2d');

var indv_canvas = document.createElement('canvas');
var indv_ctx = indv_canvas.getContext('2d');    

combined_canvas.width = 11400; combined_canvas.height = 70;
indv_canvas.width = 100; indv_canvas.height = 70;

var image = new Image();
image.onload = function() {
    combined_ctx.drawImage(image, 0, 0); // paint combined image

    // loop through the list of 114 animals
    Object.keys(master_list).forEach((d, i) => {
        // get the image data just for this animal in sequence
        var imageData = combined_ctx.getImageData(i * 100, 0, 100, 70);
        // paint that image data to the second canvas
        indv_ctx.putImageData(imageData, 0, 0); 
        var img = document.createElement('img'); 
        img.src = indv_canvas.toDataURL();
        document.getElementById("animal_thumbnails").appendChild(img);
    });
};
image.src = combined_images; // the base64 of the combined image

Естественно, было бы НАМНОГО проще сделать 114 CSS-спрайтов, что также предотвратило бы небольшую потерю качества из-за того, как Canvas рисует изображения. Но я не очень хорошо понимаю, как браузеры хранят одно и то же изображение, размещенное много раз с разными смещениями.

В случае, если клиент дублирует объединенное изображение в памяти, я просматриваю около 100 МБ для всех этих миниатюр. Я надеюсь, что даже самый худший браузер умнее этого, но это слишком далеко, чтобы я не знал.

Причина, по которой я загружаю изображение как base64, заключается в том, что у меня была еще одна идея - декодировать base64 с помощью atob() и разрезать его с помощью jpg-js, в соответствии с qaru.site/questions/127771/.... Но jpg-js добавляет около 300 КБ при минимизации, и я не уверен, что он когда-либо действительно предназначался для клиента.

  • 1
    Вы бы не сделали 114 спрайтов CSS. CSS-спрайт - это именно то, что вы сделали, многие изображения объединены в одно. Теперь все, что вам нужно сделать, это установить это одно изображение в качестве фона div, где div составляет 70x70px, и переместить фон, чтобы отобразить нужное изображение. Div действует как окно.
  • 0
    Правильно, но мне нужно каждое животное в качестве своего собственного узла для фильтрации (например, показывать мне только плотоядных), поэтому мне нужно 114 делений, верно?
Показать ещё 2 комментария
Теги:
image
canvas
css-sprites

1 ответ

0
Лучший ответ

Что касается использования памяти, пожалуйста, смотрите этот пост и этот пост

Поэтому задача состоит в том, чтобы разделить это длинное изображение на 114 маленьких изображений на клиенте.

Для чего нужно нарезать длинное изображение. Я хотел бы сохранить его как одно изображение и использовать как спрайт CSS и показывать все изображения.

Если ваши изображения имеют фиксированное измерение, цикл JavaScript может отображать все изображения на странице. Или вы могли бы использовать инструмент, как это, чтобы получить положение животных и иметь его в файле CSS. Но я бы предпочел метод цикла JS.

Код будет что-то вроде этого

var imageItem = "";
var x = 0;
for (var i = 0; i < 144, i++) {

  imageItem += "<li style='background-position: "+ x + " 0'></li>";
  x = x + 100; // this is the width of the each image
}

someElement.innerHtml = "<ul class='img-container'>" + imageItem + "</ul>";

В CSS

.img-container li {
  width: 100px;
  height: 70px;
  background-image : url('../your-long-image.jpg');
  background-repeat: no-repeat;
}

Посмотрите этот пример, я использую только одно изображение, я изменяю положение смещения, чтобы показать разные места на одном и том же изображении.

var imageItem = "";
var x = 0;
for (var i = 0; i < 3; i++) {
      
      imageItem += "<li style='background-position: "+ x + "px  0'>ss</li>";
      x = x - 125; // this is the width of the each image
}

    document.getElementById("container").innerHTML = "<ul class='img-container'>" + imageItem + "</ul>";
.img-container li {
      width: 125px;
      height: 200px;
      border: 1px solid green;
      background-image : url('https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/intermediary/f/c9702304-c06d-4500-90b7-b6b6168093f8/db9n9km-ee485eb1-1ecc-4cd8-b845-f16900bde9e0.png');
      background-repeat: no-repeat;
      float:left;
      list-style: none;
    }
<div id="container"></div>
  • 0
    Просто чтобы быть понятным, цикл будет создавать новый элемент Image на каждой итерации, устанавливать его на объединенное изображение и устанавливать стиль для корректного смещения?
  • 0
    Там нет элемента изображения, мы используем background-image, чтобы показать изображение, мы меняем background-position, чтобы показать разложенное изображение.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню