像 SWF 一样缩放 SVG (Raphael.js)

发布于 2024-10-05 07:39:15 字数 409 浏览 11 评论 0原文

几天前我开始使用 Raphael.js,我真的很喜欢它。我唯一无法弄清楚的是如何让“paper”或 svg/vml 标签像 swf 一样填充浏览器窗口。 查看此示例。

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

我能够通过浏览器窗口调整“纸张”的大小,但无法让所有矢量图形调整其大小。任何反馈将不胜感激。

编辑

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

I started using Raphael.js a few days ago and I'm really enjoying it. The only thing I haven't been able to figure out is how to get the "paper" or svg/vml tag to fill the browser window like an swf. See this example.

Note the way the above example resizes with the browser window

I was able to get the "paper" to resize with the browser window, but no luck getting all the vector graphics to adjust their size. Any feedback would be greatly appreciated.

EDIT

I tried a bunch of different routes with this. viewBox worked great but its SVG only. I just figured out how to do it using Raphael sets and a little code on the window.onresize event. I'll post my findings later tonight or tomorrow. I'd still really like to see other solutions to the question if there are any.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

揽清风入怀 2024-10-12 07:39:15

我花了一段时间,但我终于想出了解决这个问题的方法。我已将解决方案包装在一个可与 Raphael 一起使用的小 js 文件中。您可以在此处获取js文件以及一些简单的文档。 查看实际操作

工作原理:

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

任何反馈将不胜感激。

It took me awhile but I finally came up with a solution to this problem. I've wrapped the solution in a small js file that can be used with Raphael. You can get the js file along with some simple documentation here. See it in action.

How it works:

  1. use viewBox for svg
  2. wrap all vml nodes in a group node
  3. wrap the Raphael constructor up so that the vml group node is passed to the Raphael constructor
  4. alter a few css properties when the paper is resized to deal with centering, clipping and maintaining the correct aspect ratio.

Any feedback would be greatly appreciated.

飞烟轻若梦 2024-10-12 07:39:15

你好,Zévan,

我找到了一个很好的答案,是由一个叫 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>

Well hello Zévan,

I found a nice answer, made by a guy called Zevan. However, I found the code overcomplicated for my liking (Required jquery, did wierd stuff like "$(this)" etc).

So I simplified it. It's now short enough to fit into 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;
}

The only drawback from your version is that it requires SVG, it doesn't do VML. Is this a problem?

I'm using it with a simplified version of your demo page:

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

北音执念 2024-10-12 07:39:15

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

You could loop over all paths and scale() them acording to the new scale of the paper after resizing it.

九命猫 2024-10-12 07:39:15

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

You could add a 'viewBox' attribute on the svg root element to define the coordinate system, the shapes will then scale to whatever the size of the container is. Not sure how to deal with the VML side of things though. I'd suggest reporting an issue for it, https://github.com/DmitryBaranovskiy/raphael/issues.

旧情别恋 2024-10-12 07:39:15

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

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

This might just be too old of a thread, but Raphael 2.0 at least has a setViewBox method -- http://raphaeljs.com/reference.html#Paper.setViewBox

You'll still need to set the actual canvas size to 100%, so the container scales to the window, but calling setViewBox with appropriate w/h in your window.resize callback should do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文