Масштабирование холста в Firefox не влияет на изображения SVG - PullRequest
0 голосов
/ 03 мая 2018

Firefox не учитывает 2D-преобразование холста для изображений SVG, однако это относится к изображениям PNG.

Следующий фрагмент кода создает два HTML-холста с контекстами 2D-рисования. В обоих случаях применяется простое преобразование масштаба, затем на верхнем изображении отображается квадратное изображение PNG размером 20 пикселей, а в нижнем - SVG с такими же размерами.

На моем Chromium (v65.0.3325.162) изображения масштабируются, как и ожидалось. Однако в Firefox (v58.0.2) холст внизу (тот, у которого SVG) не масштабируется, в отличие от холста с исходным изображением PNG.

function createPng(xSize, ySize) {
  var canvas = document.createElement("canvas");
  canvas.width = 20;
  canvas.height = 20;
  var ctx = canvas.getContext("2d")
  ctx.fillStyle = "000000";
  ctx.fillRect(0, 0, xSize, ySize);
  
  var img = new Image()
  prom = new Promise(function(resolve, reject) {
    img.onload = function() {resolve(img)}
    img.onerror = function(err) {reject(err)}
  })
  img.src = canvas.toDataURL("image/png");
  return prom
}

function createSvg() {
  var img = new Image()
  var prom = new Promise(function(resolve, reject) {
    img.onload = function() {resolve(img)}
    img.onerror = function(err) {reject(err)}
  })
  img.src =  "https://cdn.rawgit.com/AttilaVM/4e0987aae8bc37b2067fbde591088758/raw/95dcffd67b37540d739f4bd5f33f6bead625a90f/test.svg"
  return prom
}

var containerPng = document.getElementById("container-png")
var canvasPng = document.createElement("canvas")

canvasPng.width = containerPng.clientWidth;
canvasPng.height = containerPng.clientHeight;

containerPng.appendChild(canvasPng);

var ctxPng = canvasPng.getContext("2d");

createPng(20, 20)
.then(function(img) {
  ctxPng.scale(5, 1); 
  ctxPng.drawImage(img, 0, 0)
})
.catch(function(err) {console.error(err)});

var containerSvg = document.getElementById("container-svg")
var canvasSvg = document.createElement("canvas")

canvasSvg.width = containerSvg.clientWidth;
canvasSvg.height = containerSvg.clientHeight;

containerSvg.appendChild(canvasSvg);
var ctxSvg = canvasSvg.getContext("2d");

createSvg()
.then(function(img) {
  ctxSvg.scale(5, 1); 
  ctxSvg.drawImage(img, 0, 0)
})
.catch(function(err) {console.error(err)});
.container {
  position: relative;
  margin: 15px 0 0 0;
  width: 100%;
  height: 20px;
  background-color: #aaaaaa
}

.container > canvas {
  position: absolute;
  top: 0;
  left: 0;
}
<div id="container-png" class="container"></div>
<div id="container-svg" class="container"></div>

Скриншоты

Хром:

enter image description here

Fire Fox:

enter image description here

Вопрос:

Каков наилучший способ написания кода для рисования масштабированных изображений SVG на холсте HTML, который дает одинаковый результат как в Firefox, так и в Chromium?

1 Ответ

0 голосов
/ 03 мая 2018

На самом деле это не ошибка. В исходном svg атрибут preserveAspectRatio отсутствует. Это означает, что используется значение по умолчанию, равное XMidYMid. Это создаст проблему, если viewBox форматное соотношение svg не соответствует форматному соотношению цели viewPort (изображение). Чтобы отключить это, вам нужно добавить preserveAspectRatio="none" в svg. Я пошел к источнику svg, добавил атрибут preserveAspectRatio="none", а затем сделал это:

var x = "data:image/svg+xml;base64,"+ btoa(ser.serializeToString(document.querySelector("svg")))

ser выше - это экземпляр XMLSerializer. Это даст мне URL-адрес данных, который я могу использовать:

"data:image/svg+xml;base64,PHN2ZyB4bWxuczpvc2I9Imh0dHA6Ly93d3cub3BlbnN3YXRjaGJvb2sub3JnL3VyaS8yMDA5L29zYiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDI2LjQ1OCAyNi40NTgiIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGRlZnM+PGxpbmVhckdyYWRpZW50IG9zYjpwYWludD0iZ3JhZGllbnQiIGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlMjVlNWUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMxMjkwMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB5Mj0iMjk1LjQ4MiIgeDI9IjEyLjYxNCIgeTE9IjI3Mi4xNjQiIHgxPSIxMi4xOSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjExMzQ3IDAgMCAxLjExMzQ3IC0xLjUwMSAtMzIuMTk4KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPSJiIiB4bGluazpocmVmPSIjYSIvPjwvZGVmcz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMCAyNzAuNTQyaDI2LjQ1OFYyOTdIMHoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTI3MC41NDIpIi8+PC9zdmc+"

Затем я создал скрипку и изменил это:

function createSvg() {
  var img = new Image()
  var prom = new Promise(function(resolve, reject) {
    img.onload = function() {resolve(img)}
    img.onerror = function(err) {reject(err)}
  })
  img.src =  "data:image/svg+xml;base64,PHN2ZyB4bWxuczpvc2I9Imh0dHA6Ly93d3cub3BlbnN3YXRjaGJvb2sub3JnL3VyaS8yMDA5L29zYiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDI2LjQ1OCAyNi40NTgiIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PGRlZnM+PGxpbmVhckdyYWRpZW50IG9zYjpwYWludD0iZ3JhZGllbnQiIGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlMjVlNWUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMxMjkwMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB5Mj0iMjk1LjQ4MiIgeDI9IjEyLjYxNCIgeTE9IjI3Mi4xNjQiIHgxPSIxMi4xOSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjExMzQ3IDAgMCAxLjExMzQ3IC0xLjUwMSAtMzIuMTk4KSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGlkPSJiIiB4bGluazpocmVmPSIjYSIvPjwvZGVmcz48cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMCAyNzAuNTQyaDI2LjQ1OFYyOTdIMHoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTI3MC41NDIpIi8+PC9zdmc+";
  return prom
}

Смотрите скрипку здесь:

https://fiddle.jshell.net/ibowankenobi/4ntq2qLz/1/

Похоже, это решило проблему в браузере Firefox, который я тестировал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...