Масштабирование SVG (Raphael.js) как SWF - PullRequest
20 голосов
/ 01 декабря 2010

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

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

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

EDIT

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

Ответы [ 5 ]

37 голосов
/ 04 декабря 2010

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

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

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

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

7 голосов
/ 14 июня 2011

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

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

Поэтому я упростил его.Теперь оно достаточно короткое, чтобы поместиться в 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>

2 голосов
/ 01 декабря 2010

Вы можете добавить атрибут 'viewBox' в корневой элемент svg, чтобы определить систему координат, тогда формы будут масштабироваться до любого размера контейнера. Не уверен, как бороться с VML стороной вещей, хотя. Я бы предложил сообщить о проблеме, https://github.com/DmitryBaranovskiy/raphael/issues.

2 голосов
/ 01 декабря 2010

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

1 голос
/ 21 января 2013

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

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

...