20

几天前我开始使用 Raphael.js,我真的很喜欢它。我唯一不知道的是如何让“paper”或 svg/vml 标签像 swf 一样填充浏览器窗口。请参阅此示例。

请注意上述示例使用浏览器窗口调整大小的方式

我能够使用浏览器窗口调整“纸张”的大小,但没有运气让所有矢量图形调整它们的大小。任何反馈将不胜感激。

编辑

我用这个尝试了很多不同的路线。viewBox 效果很好,但只有 SVG。我只是想出了如何使用 Raphael 集和 window.onresize 事件上的一些代码来做到这一点。我将在今晚或明天晚些时候发布我的发现。如果有的话,我仍然很想看到这个问题的其他解决方案。

4

5 回答 5

37

我花了一段时间,但我终于想出了解决这个问题的方法。我已经将解决​​方案封装在一个可以与 Raphael 一起使用的小 js 文件中。您可以在此处获取 js 文件以及一些简单的文档。看到它在行动

这个怎么运作:

  1. 为 svg 使用 viewBox
  2. 将所有 vml 节点包装在一个组节点中
  3. 将 Raphael 构造函数包装起来,以便将 vml 组节点传递给 Raphael 构造函数
  4. 当调整纸张大小以处理居中、剪裁和保持正确的纵横比时,更改一些 css 属性。

任何反馈将不胜感激。

于 2010-12-04T19:04:23.833 回答
7

你好,泽万,

我找到了一个很好的答案,由一个叫 Zevan 的人提出。但是,我发现我喜欢的代码过于复杂(必需的 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>

于 2011-06-13T20:38:49.203 回答
2

您可以在调整大小后根据纸张的新比例循环遍历所有路径并缩放()它们。

于 2010-12-01T09:10:14.293 回答
2

您可以在 svg 根元素上添加一个“viewBox”属性来定义坐标系,然后形状将缩放到容器的大小。不确定如何处理 VML 方面的事情。我建议为它报告一个问题,https://github.com/DmitryBaranovskiy/raphael/issues

于 2010-12-01T12:05:45.617 回答
2

这可能是一个太旧的线程,但 Raphael 2.0 至少有一个setViewBox方法——http://raphaeljs.com/reference.html#Paper.setViewBox

您仍然需要将实际画布大小设置为 100%,以便容器缩放到窗口,但setViewBox在 window.resize 回调中使用适当的 w/h 调用应该可以解决问题。

于 2013-01-21T03:50:35.870 回答