Масштабирование SVG (Raphael.js) как SWF

Я начал использовать Raphael.js несколько дней назад, и мне это очень нравится. Единственное, что я не смог понять, это как заставить тег «paper» или svg/vml заполнять окно браузера, как swf. См. этот пример.

Обратите внимание, как в приведенном выше примере изменяется размер окна браузера

Мне удалось изменить размер «бумаги» в окне браузера, но мне не удалось настроить размер всей векторной графики. Любая обратная связь будет принята с благодарностью.

ИЗМЕНИТЬ

Я пробовал кучу разных маршрутов с этим. viewBox отлично работал, но только SVG. Я только что понял, как это сделать, используя наборы Raphael и небольшой код для события window.onresize. Я опубликую свои выводы сегодня вечером или завтра. Я все еще очень хотел бы увидеть другие решения вопроса, если они есть.


person Zevan    schedule 01.12.2010    source источник


Ответы (5)


Это заняло у меня некоторое время, но я, наконец, нашел решение этой проблемы. Я завернул решение в небольшой файл js, который можно использовать с Raphael. Вы можете получить файл js вместе с простой документацией здесь. Посмотрите, как это работает.

Как это работает:

  1. использовать viewBox для svg
  2. обернуть все узлы vml в узел группы
  3. оберните конструктор Raphael так, чтобы узел группы vml был передан конструктору Raphael
  4. изменить несколько свойств css при изменении размера бумаги, чтобы иметь дело с центрированием, обрезкой и сохранением правильного соотношения сторон.

Любая обратная связь будет принята с благодарностью.

person Zevan    schedule 04.12.2010
comment
может у вас только один экземпляр ScaleRaphael?? ... Я помещаю файлы .svg в миниатюры ... исходные файлы .svg имеют размер около 400x400, а миниатюры - 75x75 ... Я использовал уникальный экземпляр Raphael( container_id ) для каждой миниатюры. ... НО кажется, что когда я переключаюсь на new ScaleRaphael( container_id , 75, 75), все большие пальцы объединяются в один визуальный элемент. - person dsdsdsdsd; 04.11.2013

Ну привет Зеван,

Я нашел хороший ответ, сделанный парнем по имени Зеван. Тем не менее, я нашел код слишком сложным, на мой вкус (требуется jquery, делал странные вещи, такие как «$ (это)» и т. д.).

Поэтому я упростил. Теперь он достаточно короткий, чтобы поместиться в stackoverflow;):

var paper;

window.ScaleRaphael = function(container, width, height) {
    var wrapper = document.getElementById(container);
    wrapper.style.width = width + "px";
    wrapper.style.height = height + "px";
    wrapper.style.overflow = "hidden";

    wrapper.innerHTML = "<div id='svggroup'><\/div>";
    var nestedWrapper = document.getElementById("svggroup");

    paper = new Raphael(nestedWrapper, width, height);
    paper.w = width;
    paper.h = height;
    paper.canvas.setAttribute("viewBox", "0 0 "+width+" "+height);
    paper.changeSize = function() {
        var w = window.innerWidth
        var h = window.innerHeight
        var ratioW = w / width;
        var ratioH = h / height;
        var scale = ratioW < ratioH ? ratioW : ratioH;

        var newHeight = Math.floor(height * scale);
        var newWidth = Math.floor(width * scale);

        wrapper.style.width = newWidth + "px";
        wrapper.style.height = newHeight + "px";
        paper.setSize(newWidth, newHeight);
    }
    window.onresize = function() {
        paper.changeSize();
    }

    paper.changeSize();

    return paper;
}

Единственный недостаток вашей версии в том, что она требует SVG, а не VML. Это проблема?

Я использую его с упрощенной версией вашей демо-страницы:

<!DOCTYPE html> 
<html lang="en"> 
<head>
<title>ScaleRaphaël Demo 1</title>
<meta charset="utf-8"> 

<script type="text/javascript" src="raphael.js"></script>
<script type="text/javascript" src="scale.raphael.js"></script>
<script type="text/javascript">

    window.onload = function() {
        var paper = new ScaleRaphael("wrap", 600, 400);

        // draw some random vectors:
        var path = "M " + paper.w / 2 + " " + paper.h / 2;
        for (var i = 0; i < 100; i++){
            var x = Math.random() * paper.w;
            var y = Math.random() * paper.h;
            paper.circle(x, y,
                Math.random() * 60 + 2).
                attr("fill", "rgb("+Math.random() * 255+",0,0)").
                attr("opacity", 0.5);
            path += "L " + x + " " + y + " ";
        }

        paper.path(path).attr("stroke","#ffffff").attr("stroke-opacity", 0.2);

        paper.text(200,100,"Resize the window").attr("font","30px Arial").attr("fill","#ffffff");
    }

      </script>
<style type="text/css">
    body, html {
        margin: 0;
        padding: 0;
        overflow: hidden;
    }

    #wrap{
        background-color: orange;
    }
</style>

</head>
<body>

person Community    schedule 13.06.2011
comment
я знаю, что вы не поддерживали vml, поэтому ваша функция изменения размера не настроена для IE? Для меня огромной частью Raphael является поддержка VML... и поэтому метод изменения размера окна должен работать в IE. - person Zevan; 14.06.2011
comment
Превосходный ответ и код. Это только что избавило меня от огромного количества проб и ошибок. Спасибо! - person Adam Crossland; 25.10.2011

Вы можете перебрать все пути и масштабировать() их в соответствии с новым масштабом бумаги после изменения ее размера.

person Gipsy King    schedule 01.12.2010
comment
оказывается, нет необходимости зацикливаться, если вы используете набор и делаете myset.scale(2,2,0,0) - person Zevan; 02.12.2010
comment
@Zeven Интересно! Я не рассматривал наборы, когда использовал Рафаэля. - person Gipsy King; 02.12.2010
comment
Хотя я скоро поговорил. К сожалению, если вы масштабируете набор объектов, система координат не сохраняется, что может действительно испортить любую анимацию, которая может происходить. Значение cx и cy изменяется в зависимости от масштаба. Я почти уверен, что этого можно было бы избежать, если бы Рафаэль использовал материал SVG для преобразования(). Не уверен, почему масштабирование выполняется вручную, а не с помощью встроенных функций SVG. Возможно, это как-то связано с тем, что код легко совместим с VML. Я собираюсь продолжать изучать это. В крайнем случае напишу какой-нибудь плагин. - person Zevan; 02.12.2010


Это может быть просто слишком старая тема, но в Raphael 2.0 по крайней мере есть метод setViewBox -- http://raphaeljs.com/reference.html#Paper.setViewBox

Вам по-прежнему необходимо установить фактический размер холста равным 100 %, чтобы контейнер масштабировался до размера окна, но вызов setViewBox с соответствующим w/h в обратном вызове window.resize должен помочь.

person drzaus    schedule 21.01.2013
comment
вот не менее старый случайный пример использования setViewBox для масштабирования колесика мыши — jsfiddle.net/9zu4U/2 - person drzaus; 21.01.2013