Перспективное преобразование работает только с тегом svg, а не с g или изображением

Я работаю над проектом, который включает в себя серию перспективных преобразований фигур, где пользователь в конечном итоге сможет перемещаться по ним. Я работал над прототипом преобразований, которые разрабатывал с помощью этого кода < / а>

По сути, у меня есть 4 точки, из которых я вычисляю матрицу с помощью функции numberic.js, а затем применяю преобразование matrix3D css3 к элементу svg.

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

var margin = {top: 152.5, right: 200, bottom: 152.5, left: 200},
    width = 700 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;
var sourcePoints = [[0, 0], [width, 0], [width, height], [0, height]],
    targetPoints = [[225.201, 48.411], [1188.39, 185.159], [1869.12, 892.339], [217.525, 231.14]];

var svgTransform;

var transform = ["", "-webkit-", "-moz-", "-ms-", "-o-"].reduce(function(p, v) { 
        return v + "transform" in document.body.style ? v : p; 
    }) + "transform";

function transformed() {  
  for (var a = [], b = [], i = 0, n = sourcePoints.length; i < n; ++i) {
    var s = sourcePoints[i], t = targetPoints[i];
    a.push([s[0], s[1], 1, 0, 0, 0, -s[0] * t[0], -s[1] * t[0]]), b.push(t[0]);
    a.push([0, 0, 0, s[0], s[1], 1, -s[0] * t[1], -s[1] * t[1]]), b.push(t[1]);
  }

  var X = numeric.solve(a, b, true), matrix = [
    X[0], X[3], 0, X[6],
    X[1], X[4], 0, X[7],
       0,    0, 1,    0,
    X[2], X[5], 0,    1
  ].map(function(x) {
    return d3.round(x, 6);
  });

  svgTransform.style(transform, "matrix3d(" + matrix + ")");
}

function reset() {
    targetPoints = [[0, 0], [width, 0], [width, height], [0, height]];
    transformed();
    targetPoints = [[225.201, 48.411], [1188.39, 185.159], [1869.12, 892.339], [217.525, 231.14]];
}

function initialize() {
    svgTransform = d3.select("#vis").append("svg")
        .attr("width", $("#vis").width())
        .attr("height", $("#vis").height())
        .style(transform + "-origin", 0 + "px " + 0 + "px " + 0 + "px");

    svgTransform.append("g")
        .append("image")
        .attr("xlink:href", "http://i.imgur.com/RqtyZjC.png")
        .attr("width", width)
        .attr("height", height);

    $("button.transform").click(function(evt) {
        evt.stopPropagation();
        transformed();
    });
    $("button.reset").click(function(evt) {
        evt.stopPropagation();
        reset();
    });   
}

initialize();

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

Я также пробовал делать это только с div, и он также отлично работает (скрипт здесь) но причина, по которой я хотел использовать SVG, заключалась в том, чтобы облегчить создание пользовательского интерфейса и использование масштабирования и панорамирования.

Любой более опытный, чем я, может понять, почему преобразования не работают внутри svg?

Сильфон - это изображение результата, если преобразование применяется к тегу g или image внутри SVG.

Преобразование применено внутри тега SVG

Заранее спасибо за помощь!


person Solidus    schedule 30.11.2014    source источник


Ответы (1)


К крайним <svg> элементам безопасно применять преобразования CSS 3D, как и к любому элементу HTML. Но поддержка браузером трехмерных преобразований дочерних элементов SVG все еще находится в стадии разработки и в настоящее время ненадежна. Спецификация, описывающая это (http://www.w3.org/TR/css3-transforms/#svg-three-dimensional-functions) все еще остается только рабочим проектом. Возможно, сейчас имеет смысл избегать этого.

person Paul LeBeau    schedule 30.11.2014
comment
Хорошо, я вижу. Спасибо за информацию. Тогда я не вижу смысла использовать SVG. Думаю, я просто буду использовать обычный HTML и использовать преобразования для панорамирования и масштабирования. - person Solidus; 30.11.2014