Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
У канваса логика отрисовки построена на перерисовке всей карты.
Кроме того, довольно сложно каждый раз вычислить область наложения особенно при выводе текста несколько раз в одной области.
Во-первых, потребовалось меньшее количество кода для создания на svg.
<rect x="10" y="10" width="200" height="200" fill="red"/>
<path d="M10,10 L200,200 L400,10" fill="blue"/>
var rect = ctx.rect(10, 10, 200, 200, 'red');
// либо:
var rect = ctx.rect({ x: 10, y: 10, width: 200, height: 200, fill: 'red' });
var path = ctx.path([[10, 10], [200, 200], [400, 10]], 'blue');
Во-вторых, простота и удобство создания кода. У svg логика строится на отдельных объектах, их свойствах и методах. Например, чтобы определить объект под курсором, нужно создать обработчик события для данного объекта (circle для станций метро), в котором можно поменять его свойства — цвет, масштаб (на картинке для значка станции «Ходынское поле» применен метод scale) и др. У канваса логика отрисовки построена на перерисовке всей карты. И для выделения отдельных объектов нужно перерисовывать и масштабировать всю карту. Кроме этого, канвас не хранит отрисованные объекты в памяти, их нужно отдельно сохранять в переменных (в dbcartajs в объекте mflood) и самому следить за ними (добавлять, удалять). SVG-изображение хранит отрисованные объекты в DOM-модели и к ним можно обращаться напрямую.
var station = ctx.circle({ cx: 50, cy: 50, radius: 10, fill: 'red', stroke: 'red 2px' });
station.on('mouseover', 'animate', 'stroke', 'blue', 1000);
station.on('mouseout', 'animate', 'stroke', 'red', 1000);
station.on('mouseover', function(e){
this.animate('stroke', 'blue', 1000);
this.scale(1.3);
});
station.on('mouseout', function(e){
this.animate({
stroke: 'blue',
scale: 1 / 1.3
}, 1000);
});
В-третьих, возможностей в svg намного больше, чем в канвасе, например, анимация, фильтры для изображений.
fabric.Image.fromURL('image.jpg', function(img) {
img.filters.push(new fabric.Image.filters.Grayscale());
img.applyFilters(canvas.renderAll.bind(canvas));
canvas.add(img);
});
var image = ctx.image('image.jpg', 10, 10);
image.filter('pixel', function(r, g, b){
var mid = (r + g + b) / 3;
return [mid, mid, mid, 1];
});
Карта метро Москвы. SVG-версия