Menskalakan SVG (Raphael.js) seperti SWF

Saya mulai menggunakan Raphael.js beberapa hari yang lalu dan saya sangat menikmatinya. Satu-satunya hal yang belum dapat saya pahami adalah bagaimana cara mendapatkan tag "kertas" atau svg/vml untuk mengisi jendela browser seperti swf. Lihat contoh ini.

Perhatikan cara contoh di atas mengubah ukuran dengan jendela browser

Saya bisa mengubah ukuran "kertas" dengan jendela browser, tetapi tidak berhasil mendapatkan semua grafik vektor untuk menyesuaikan ukurannya. Umpan balik apa pun akan sangat dihargai.

EDIT

Saya mencoba banyak rute berbeda dengan ini. viewBox berfungsi dengan baik tetapi hanya SVG. Saya baru saja menemukan cara melakukannya menggunakan set Raphael dan sedikit kode pada acara window.onresize. Saya akan memposting temuan saya nanti malam atau besok. Saya masih sangat ingin melihat solusi lain untuk pertanyaan tersebut jika ada.


person Zevan    schedule 01.12.2010    source sumber


Jawaban (5)


Butuh beberapa saat, tetapi saya akhirnya menemukan solusi untuk masalah ini. Saya telah membungkus solusinya dalam file js kecil yang dapat digunakan dengan Raphael. Anda bisa mendapatkan file js beserta beberapa dokumentasi sederhana di sini. Lihat aksinya.

Cara kerjanya:

  1. gunakan viewBox untuk svg
  2. bungkus semua node vml dalam node grup
  3. bungkus konstruktor Raphael sehingga node grup vml diteruskan ke konstruktor Raphael
  4. ubah beberapa properti css saat kertas diubah ukurannya untuk menangani pemusatan, pemotongan, dan pemeliharaan rasio aspek yang benar.

Umpan balik apa pun akan sangat dihargai.

person Zevan    schedule 04.12.2010
comment
bisakah Anda hanya memiliki satu instance ScaleRaphael?? ... Saya memasukkan file .svg ke dalam thumbnail ... .svg asli berukuran sekitar 400x400, tetapi jempolnya 75x75 ... Saya telah menggunakan instance unik Raphael( container_id ) untuk setiap jempol. ... TETAPI tampaknya ketika saya beralih ke new ScaleRaphael( container_id , 75, 75), semua jempol disatukan menjadi satu elemen visual. - person dsdsdsdsd; 04.11.2013

Halo Zévan,

Saya menemukan jawaban yang bagus, dibuat oleh seorang pria bernama Zevan. Namun, saya menemukan kodenya terlalu rumit sesuai dengan keinginan saya (Jquery yang diperlukan, melakukan hal-hal aneh seperti "$(ini)" dll).

Jadi saya menyederhanakannya. Sekarang cukup pendek untuk masuk ke dalam 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;
}

Satu-satunya kelemahan dari versi Anda adalah memerlukan SVG, tidak melakukan VML. Apakah ini sebuah masalah?

Saya menggunakannya dengan versi sederhana dari halaman demo Anda:

<!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
saya tahu Anda tidak melakukan dukungan vml, itu sebabnya fungsi pengubahan ukuran Anda tidak diatur untuk IE? Bagi saya sebagian besar dari Raphael adalah dukungan VML... sehingga metode pengubahan ukuran jendela harus berfungsi di IE - person Zevan; 14.06.2011
comment
Jawaban dan kode yang luar biasa. Ini hanya menyelamatkan saya dari banyak percobaan dan kesalahan. Terima kasih! - person Adam Crossland; 25.10.2011

Anda dapat mengulang semua jalur dan menskalakannya() sesuai dengan skala kertas yang baru setelah mengubah ukurannya.

person Gipsy King    schedule 01.12.2010
comment
ternyata tidak perlu looping jika menggunakan set dan melakukan myset.scale(2,2,0,0) - person Zevan; 02.12.2010
comment
@Zeven Menarik! Saya tidak melihat set ketika saya menggunakan raphaël. - person Gipsy King; 02.12.2010
comment
Saya segera berbicara dengannya. Sayangnya jika Anda menskalakan sekumpulan objek, sistem koordinat tidak dipertahankan sehingga dapat mengacaukan animasi apa pun yang mungkin sedang berjalan. Artinya cx dan cy berubah tergantung skala. Saya cukup yakin ini bisa dihindari jika Raphael menggunakan barang transform() SVG. Tidak yakin mengapa penskalaan dilakukan secara manual daripada dengan fungsionalitas SVG bawaan. Mungkin ini ada hubungannya dengan membuat kodenya mudah kompatibel dengan VML. Saya akan terus memeriksanya. Kasus terburuk saya akan menulis semacam plug-in. - person Zevan; 02.12.2010


Ini mungkin thread yang terlalu lama, tetapi Raphael 2.0 setidaknya memiliki metode setViewBox -- http://raphaeljs.com/reference.html#Paper.setViewBox

Anda masih perlu mengatur ukuran kanvas sebenarnya menjadi 100%, sehingga container berskala ke jendela, tetapi memanggil setViewBox dengan w/h yang sesuai di callback window.resize Anda akan berhasil.

person drzaus    schedule 21.01.2013
comment
inilah contoh acak yang sama lamanya dalam menggunakan setViewBox untuk memperbesar roda mouse - jsfiddle.net/9zu4U/2 - person drzaus; 21.01.2013