Scaling SVG (RAF.js) jak SWF

Zacząłem używać Raphaela.js kilka dni temu i bardzo mi się podoba. Jedyne, czego nie udało mi się dowiedzieć, to jak sprawić, by znacznik "paper" lub svg/vml wypełniał okno przeglądarki jak swf. Zobacz ten przykład.

zwróć uwagę na sposób, w jaki powyższy przykład zmienia rozmiar w oknie przeglądarki

Udało mi się zmienić rozmiar "papieru" w oknie przeglądarki, ale nie udało mi się dopasować wszystkich grafik wektorowych do ich rozmiaru. Wszelkie opinie będą być bardzo doceniane.

EDIT

Próbowałem różnych tras z tym. viewBox działał świetnie, ale tylko jego SVG. Właśnie wymyśliłem jak to zrobić używając zestawów Raphaela i małego kodu na oknie.onresize event. Opublikuję wyniki później wieczorem lub jutro. Nadal chciałbym zobaczyć inne rozwiązania tego pytania, czy są jakieś.

Author: Zevan, 2010-12-01

5 answers

Zajęło mi to trochę czasu, ale w końcu wymyśliłem rozwiązanie tego problemu. Zapakowałem rozwiązanie w mały plik js, który można wykorzystać z Raphaelem. Możesz pobrać plik js wraz z prostą dokumentacją tutaj . Zobacz to w akcji .

Jak to działa:

  1. użyj viewBox dla svg
  2. zawiń wszystkie węzły vml w węzeł Grupowy
  3. zawiń konstruktor Raphael tak, aby węzeł grupy vml został przekazany do Raphael konstruktor
  4. Zmień kilka właściwości css, gdy papier jest zmieniany, aby poradzić sobie z centrowaniem, przycinaniem i utrzymywaniem prawidłowego współczynnika proporcji.

Wszelkie opinie będą bardzo mile widziane.

 37
Author: Zevan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-29 08:55:45

Witaj Zévan,]} Znalazłem ładną odpowiedź, którą dał facet o imieniu Zevan. Jednak, znalazłem kod zbyt skomplikowane dla moich upodobań(wymagane jquery, nie dziwnych rzeczy jak "$(this) " itp).

Więc uprościłem to. Jest teraz wystarczająco krótki, aby zmieścić się w 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;
}

Jedyną wadą Twojej wersji jest to, że wymaga SVG, nie robi VML. Czy to jakiś problem?

Używam go z uproszczoną wersją Twojej strony demo:

<!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>

 7
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-17 16:52:30

Możesz pętlować wszystkie ścieżki i skalować je zgodnie z nową skalą papieru po zmianie jego rozmiaru.

 2
Author: Gipsy King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 09:10:14

Możesz dodać atrybut 'viewBox' do elementu głównego svg, aby zdefiniować układ współrzędnych, kształty będą skalowane do rozmiaru kontenera. Nie wiem jednak, jak radzić sobie ze stroną VML. Proponuję zgłosić problem, https://github.com/DmitryBaranovskiy/raphael/issues .

 2
Author: Erik Dahlström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 12:05:45

To może być za stary wątek, ale Raphael 2.0 ma przynajmniej metodę setViewBox -- http://raphaeljs.com/reference.html#Paper.setViewBox

Nadal będziesz musiał ustawić rzeczywisty rozmiar obszaru roboczego na 100%, więckontener będzie skalował się do okna, ale wywołanie setViewBox z odpowiednim w/h w oknie.zmiana rozmiaru połączenia zwrotnego powinna załatwić sprawę.

 2
Author: drzaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-21 03:50:35