HTML5 Canvas vs SVG vs div


каков наилучший подход для создания элементов на лету и возможности их перемещения? Например, предположим, что я хочу создать прямоугольник, круг и полигон, а затем выбрать эти объекты и переместить их.

Я понимаю, что HTML5 предоставляет три элемента, которые могут сделать это возможным: svg,холст и div. Для того, что я хочу сделать, какой из этих элементов обеспечит лучшее спектакль?

чтобы сравнить эти подходы, я думал о создании трех визуально идентичных веб-страниц, каждая из которых имеет верхний и Нижний колонтитулы, виджет и текстовый контент в них. Виджет на первой странице будет создан полностью с помощью canvas элемент, второй полностью с svg элемент, а третий с равнины div элемент HTML и CSS.

8 396

8 ответов:

короткий ответ:

SVG будет легче для вас, так как выбор и перемещение его уже встроены. Объекты SVG являются объектами DOM, поэтому у них есть обработчики" щелчка " и т. д.

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

Canvas имеет наилучшую производительность, но вы должны реализовать все концепции управляемого состояния (выбор объекта и т. д.) самостоятельно или использовать библиотека.


длинный ответ:

HTML5 Canvas-это просто поверхность рисования для битовой карты. Вы настраиваете рисование (скажем, с цветом и толщиной линии), рисуете эту вещь, а затем холст не знает об этой вещи: он не знает, где он находится или что это такое, что вы только что нарисовали, это просто пиксели. Если вы хотите рисовать прямоугольники и перемещать их или выбирать, то вам нужно закодировать все это с нуля,в том числе код помните, что вы их нарисовали.

SVG, с другой стороны, должен поддерживать ссылки на каждый объект, который он отображает. Каждый элемент SVG / VML, который вы создаете, является реальным элементом в DOM. По умолчанию это позволяет вам гораздо лучше отслеживать создаваемые элементы и по умолчанию упрощает работу с такими вещами, как события мыши, но значительно замедляется, когда есть большое количество объектов

эти ссылки SVG DOM означают, что некоторые из ног имеют дело с то, что вы рисуете, делается для вас. И SVG быстрее при рендеринге очень большие объекты, но медленнее при отображении много объекты.

игра, вероятно, будет быстрее в холст. Огромная картографическая программа, вероятно, будет быстрее в SVG. Если вы хотите использовать Canvas, у меня есть несколько учебных пособий по запуску и запуску подвижных объектов здесь.

холст будет лучше для более быстрых вещей и тяжелых растровых манипуляций (например анимация), но будет принимать больше кода, если вы хотите много интерактивности.

я проводил кучу цифр на HTML див-сделал чертеж, по сравнению холсте-сделан рисунок. Я мог бы сделать огромный пост о преимуществах каждого, но я дам некоторые из соответствующих результатов моих тестов для рассмотрения для вашего конкретного приложения:

Я сделал тестовые страницы Canvas и HTML DIV, у обоих были подвижные "узлы"."Узлы Canvas были объектами, которые я создал и отслеживал в Javascript. HTML узлы были подвижными Элементы div.

я добавил 100 000 узлов к каждому из моих двух тестов. Они выступали совсем по-другому:

вкладка HTML test заняла целую вечность для загрузки (при времени чуть менее 5 минут, chrome попросил убить страницу в первый раз). Диспетчер задач Chrome говорит, что вкладка занимает 168 МБ. Он занимает 12-13% процессорного времени, когда я смотрю на него, 0%, когда я не смотрю.

вкладка холст загружается в одну секунду и занимает 30 МБ. Он также занимает до 13% процессорного времени все время, независимо от того, смотрит на него человек или нет. (2013 edit: они в основном исправили это)

перетаскивание на HTML-странице более плавное, что ожидается дизайном, поскольку текущая настройка должна перерисовывать все каждые 30 миллисекунд в тесте холста. Для этого существует множество оптимизаций для Canvas. (недействительность холста является самой простой, также обрезка областей, выборочная перерисовка и т. д.. просто зависит от того, как сильно вы себя чувствуете реализация)

нет никаких сомнений, что вы могли бы получить холст, чтобы быть быстрее при манипуляции с объектами, как divs в этом простом тесте, и, конечно, гораздо быстрее во время загрузки. Рисование / загрузка быстрее на холсте и имеет гораздо больше возможностей для оптимизации (т. е. за исключением вещей, которые находятся вне экрана, очень легко).

вывод:

  • SVG, вероятно, лучше подходит для приложений и приложений с несколькими элементами (менее 1000? Зависит действительно)
  • холст лучше для тысяч объектов и тщательных манипуляций, но гораздо больше кода (или библиотеки) необходимо, чтобы получить его от Земли.
  • HTML-дивы неуклюжи и не масштабируются, создание круга возможно только с закругленными углами, создание сложных форм возможно, но включает в себя сотни крошечных крошечных пиксельных дивов. Наступает безумие.

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

Я обнаружил, что на моем Mac для очень больших изображений SVG превосходит. У меня есть MacBook Pro 2013 13" Retina, и он довольно хорошо работает на скрипке ниже. Изображение 6000x6000 пикселей, и имеет 1000 объектов. Подобная конструкция в холсте была невозможна анимация для меня, когда пользователь перетаскивал объекты на диаграмме.

на современных дисплеях вы также должны учитывать различные разрешения, и здесь SVG дает вам все это бесплатно.

Скрипка:http://jsfiddle.net/knutsi/PUcr8/16/

полноэкранный режим:http://jsfiddle.net/knutsi/PUcr8/16/embedded/result/

var wiggle_factor = 0.0;
nodes = [];

// create svg:
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('style', 'border: 1px solid black');
svg.setAttribute('width', '6000');
svg.setAttribute('height', '6000');

svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink",
    "http://www.w3.org/1999/xlink");

document.body.appendChild(svg);


function makeNode(wiggle) {
    var node = document.createElementNS("http://www.w3.org/2000/svg", "g");
    var node_x = (Math.random() * 6000);
    var node_y = (Math.random() * 6000);
    node.setAttribute("transform", "translate(" + node_x + ", " + node_y +")");

    // circle:
    var circ = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    circ.setAttribute( "id","cir")
    circ.setAttribute( "cx", 0 + "px")
    circ.setAttribute( "cy", 0 + "px")
    circ.setAttribute( "r","100px");
    circ.setAttribute('fill', 'red');
    circ.setAttribute('pointer-events', 'inherit')

    // text:
    var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
    text.textContent = "This is a test! ÅÆØ";

    node.appendChild(circ);
    node.appendChild(text);

    node.x = node_x;
    node.y = node_y;

    if(wiggle)
        nodes.push(node)
    return node;
}

// populate with 100 nodes:
for(var i = 0; i < 1000; i++) {
    var node = makeNode(true);
    svg.appendChild(node);
}

// make  one mapped to mouse:
var bnode = makeNode(false);
svg.appendChild(bnode);

document.body.onmousemove=function(event){
    bnode.setAttribute("transform","translate(" +
        (event.clientX + window.pageXOffset) + ", " +
        (event.clientY + window.pageYOffset) +")");
};

setInterval(function() {
    wiggle_factor += 1/60;
    nodes.forEach(function(node) {

        node.setAttribute("transform", "translate(" 
                          + (Math.sin(wiggle_factor) * 200 + node.x) 
                          + ", " 
                          + (Math.sin(wiggle_factor) * 200 + node.y) 
                          + ")");        
    })
},1000/60);

зная различия между SVG и Canvas было бы полезно в выборе правильного.

холст

  • зависит от разрешения
  • нет поддержки для обработчиков событий
  • плохие возможности рендеринга текста
  • вы можете сохранить полученное изображение как .png или .jpg
  • хорошо подходит для графических интенсивных игр

SVG

  • независимое разрешение
  • поддержка обработчики событий
  • лучше всего подходит для приложений с большими областями рендеринга (Google Maps)
  • медленный рендеринг, если сложный (все, что использует DOM много будет медленно)
  • не подходит для игрового приложения

Я согласен с выводами Саймона Сарриса:

Я сравнил некоторую визуализацию в Protovis (SVG) с Processingjs (Canvas), которая отображает > 2000 точек, а processingjs намного быстрее, чем protovis.

обработка событий с помощью SVG, конечно, намного проще, потому что вы можете прикрепить их к объектам. В Canvas вы должны сделать это вручную (проверить положение мыши и т. д.), Но для простого взаимодействия это не должно быть сложно.

существует также додзе.видеокарта библиотека инструментария dojo. Он предоставляет слой абстракции, и вы можете указать рендерер (SVG, Canvas, Silverlight). Это может быть также жизнеспособным выбором, хотя я не знаю, сколько накладных расходов добавляет дополнительный уровень абстракции, но он упрощает кодирование взаимодействий и анимаций и является рендерер-агностиком.

вот некоторые интересные контрольные показатели:

только мои 2 цента относительно опции divs.

известных/Infamous и SamsaraJS (и, возможно, другие) использовать абсолютное позиционирование без вложенных дивов (с нетривиальным HTML и CSS контент), совмещенный с matrix2d/matrix3d для позиционирования и 2D/3D преобразования и добиться стабильных 60FPS на умеренных мобильных устройств, так что я спорил против ДИВС быть медленным вариантом.

есть много записей экрана на Youtube и в других местах, высокопроизводительных 2D / 3D вещей запуск в браузере со всем, что является элементом DOM, который вы можете Проинспектировать Элемент on, при 60FPS (смешивается с WebGL для определенных эффектов, но не для основной части рендеринга).

для ваших целей я рекомендую использовать SVG, так как вы получаете события DOM, такие как обработка мыши, включая перетаскивание, включенные, вам не нужно реализовывать собственную перерисовку, и вам не нужно отслеживать состояние ваших объектов. Используйте Canvas, когда вам нужно выполнять манипуляции с растровыми изображениями и использовать обычный div, когда вы хотите манипулировать материалом, созданным в HTML. Что касается производительности, вы обнаружите, что современные браузеры теперь ускоряют все три, но этот холст получил больше всего пока внимание. С другой стороны, насколько хорошо вы пишете свой javascript, имеет решающее значение для получения максимальной производительности с помощью canvas, поэтому я все равно рекомендую использовать SVG.

хотя есть еще некоторая правда в большинстве ответов выше, я думаю, что они заслуживают обновления:

за эти годы производительность SVG значительно улучшилась и теперь есть аппаратное ускорение CSS переходов и анимации для SVG это не зависит от производительности JavaScript вообще. Конечно, производительность JavaScript также улучшилась, и с ней улучшилась производительность Canvas, но не так сильно, как SVG. Также есть "новый ребенок" на блоке, который является доступно практически во всех браузерах сегодня и это WebGL. Чтобы использовать те же слова, которые Саймон использовал выше: It бьет как холст, так и SVG руки вниз. Это не означает, что это должна быть технология go-to, хотя, поскольку это зверь для работы, и он только быстрее в очень конкретных случаях использования.

IMHO для большинства случаев использования сегодня SVG дает лучшее соотношение производительности/удобства использования. Визуализации должны быть действительно сложными (по количеству элементов) и очень просто в то же время (на элемент), так что холст и тем более WebGL действительно сияют.

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

в то время как googling я нахожу хорошее объяснение об использовании и сжатии SVG и холст at http://teropa.info/blog/2016/12/12/graphics-in-angular-2.html

надеюсь, это поможет:

  • SVG, как и HTML, использует сохранил перевода: когда мы хотим нарисовать прямоугольник на экране, мы декларативно используем элемент в нашем ДОМ. Затем браузер нарисует прямоугольник, но он также будет создавать в памяти SVGRectElement "объект", представляющий прямоугольник. Этот объект-это то, что прилипает к нам, чтобы манипулировать – это удержанный. Мы можем назначить ему различные позиции и размеры с течением времени. Мы также можем прикрепить слушателей событий, чтобы сделать его интерактивным.
  • холст использует немедленное оказание: когда мы нарисуйте прямоугольник браузер сразу же отображает прямоугольник на экране, но есть никогда не будет быть любым "прямоугольным объектом", который его представляет. Есть просто куча пикселей в буфере холста. Мы не можем сдвинуть прямоугольник. Мы можем только нарисовать еще один прямоугольник. Мы не можем ответить щелчки или другие события на прямоугольнике. Мы можем только реагировать на события на весь холст.

таким образом, canvas является более низкоуровневым, ограничительным API, чем SVG. Но есть обратная сторона в том, что с холста вы можете сделать больше с такое же количество ресурсы. Потому что браузер не нужно создавать и поддерживать в памяти объектный граф всех вещей, которые у нас есть нарисованный, он требует меньше памяти и вычислительных ресурсов, чтобы сделать то же визуальная сцена. Если у вас очень большая и сложная визуализация нарисуйте, холст может быть вашим билетом.