123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- <!DOCTYPE html>
- <meta http-equiv="content-type" content="text/html; charset=UTF8">
- <title>saveSvgAsPng</title>
- <link href='https://fonts.googleapis.com/css?family=Open+Sans:400italic,400,300,600' rel='stylesheet' type='text/css' />
- <link rel=stylesheet href=bootstrap.min.css />
- <style>
- @font-face {
- font-family: 'Stalemate';
- font-style: normal;
- font-weight: 400;
- src: url(stalemate.ttf) format('truetype');
- }
- input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button {
- padding: 15px;
- }
- h2, h3 {
- margin-top: 0;
- }
- h3 .btn {
- margin-top: -8px;
- }
- ul {
- list-style-type: none;
- padding: 0;
- }
- ul li {
- padding: 30px 20px;
- border-bottom: 1px dashed gray;
- }
- svg, img {
- border: 1px solid lightgray;
- }
- textarea {
- width: 100%;
- height: 100px;
- }
- .error {
- border: 1px solid red;
- border-radius: 10px;
- color: red;
- padding: 8px 10px;
- }
- #sized-with-css svg {
- width: 200px;
- height: 200px;
- }
- #selectors-prefixed svg rect {
- fill: blue;
- }
- rect.css-styled {
- fill: green !important;
- }
- #selectors-prefixed rect.css-styled {
- fill: green !important;
- }
- /* Invalid selectors */
- [ng\:cloak] {
- display: block;
- }
- ng\:form {
- display: block;
- }
- </style>
- <script type=text/template id=inline-template>
- <div class=row>
- <div class=col-md-6>
- <h2></h2>
- </div>
- <div class=col-md-6>
- <h3>Preview <button class="save btn">Save as PNG</button></h3>
- </div>
- </div>
- <div class=row>
- <div class="canvas col-md-6">
- </div>
- <div class=col-md-6>
- <div class=preview></div>
- </div>
- </div>
- </script>
- <div class=container>
- <!-- Needed to trigger correct custom font rasterization in Chrome -->
- <span style='font-family: "Stalemate";color:white'>A</span>
- <h1>saveSvgAsPng</h1>
- <p>This page tests various features of saveSvgAsPng.</p>
- <p>You can test your own SVG code in the Sandbox. If something doesn't work as expected, you can <a href="https://github.com/exupero/saveSvgAsPng/issues">file an issue on GitHub</a>.</p>
- <ul>
- <li id=sandbox>
- <h2>Sandbox</h2>
- <p>Paste you SVG below to see how it renders.</p>
- <textarea><svg></svg></textarea>
- <br/>
- <button class="render btn">Preview</button>
- <div class=load-target style="margin-top:20px;"></div>
- <br/>
- <h3>Preview <button class="save btn">Save as PNG</button></h3>
- <span class=error style="display:none;"></span>
- <div class=preview></div>
- </li>
- <li id=filereader>
- <div class=row>
- <div class=col-md-6>
- <h2>Load from your hard drive</h2>
- </div>
- <div class=col-md-6>
- <h3>Preview <button class="save btn">Save as PNG</button></h3>
- </div>
- </div>
- <div class=row>
- <div class=col-md-6>
- <input type=file id=file name="files[]" />
- <div class=load-target></div>
- </div>
- <div class=col-md-6>
- <div class=preview>No file selected.</div>
- </div>
- </div>
- </li>
- <li id=inline>
- <svg width=200 height=200>
- <rect x=50 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=embedded-png>
- <svg width=200 height=200>
- <image xlink:href=image.png x=50 y=50 width=100 height=100></image>
- </svg>
- </li>
- <li id=embedded-svg>
- <svg width=200 height=200>
- <image xlink:href=test.svg x=50 y=50 width=100 height=100></image>
- </svg>
- </li>
- <li id=sized-with-pixels>
- <svg width="200px" height="200px">
- <rect x=50 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=sized-with-style>
- <svg style="width:200px;height:200px;">
- <rect x=50 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=sized-with-css>
- <svg>
- <rect x=50 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=scaling>
- <svg width=200 height=200>
- <rect width=100 height=100></rect>
- <image xlink:href=image.png x=50 y=50 width=100 height=100></image>
- </svg>
- </li>
- <li id=selectors-prefixed>
- <svg width=200 height=200>
- <rect x=0 y=50 width=100 height=100></rect>
- <rect class=css-styled x=100 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=modified-style>
- <svg width=200 height=200>
- <rect x=0 y=50 width=100 height=100></rect>
- <rect class=css-styled x=100 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=modified-css>
- <svg width=200 height=200>
- <rect x=0 y=50 width=100 height=100></rect>
- <rect class=css-styled x=100 y=50 width=100 height=100></rect>
- </svg>
- </li>
- <li id=group>
- <svg width=200 height=200>
- <g id=sub-group transform="translate(40,40)">
- <rect x=10 y=10 width=100 height=100></rect>
- </g>
- </svg>
- </li>
- <li id=percentage-size>
- <svg width="100%" height="100%">
- <rect x=25 y=25 width=100 height=100></rect>
- </svg>
- </li>
- <li id=background-color>
- <svg width=200 height=200>
- <g id=sub-group transform="translate(40,40)">
- <rect x=10 y=10 width=100 height=100></rect>
- </g>
- </svg>
- </li>
- <li id=pan-and-zoom>
- <svg width=200 height=200>
- <g transform="scale(2)">
- <rect x=10 y=10 width=100 height=100></rect>
- </g>
- </svg>
- </li>
- <li id=unicode>
- <svg width=200 height=200>
- <text x=100 y=100 text-anchor=middle dy=14>ö,i,ç,ğ</text>
- </svg>
- </li>
- <li id=gradient>
- <svg width=200 height=200>
- <defs>
- <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
- <stop offset="0%" style="stop-color:rgb(255,0,255);stop-opacity:1" />
- <stop offset="100%" style="stop-color:rgb(0,255,255);stop-opacity:1" />
- </linearGradient>
- </defs>
- <line x2="200" y2="200" stroke="url(#grad1)" stroke-width="5px" />
- </svg>
- </li>
- <li id=foreign-object>
- <svg width=200 height=200>
- <foreignobject x=50 y=50 width=50 height=100>
- <div>Foreign Object</div>
- </foreignobject>
- </svg>
- </li>
- <li id=xmlns-override>
- <svg width=200 height=200>
- <foreignobject x=50 y=50 width=50 height=100>
- <div xml:xmlns="http://www.w3.org/2000/xmlns/">Foreign Object</div>
- </foreignobject>
- </svg>
- </li>
- <li id=opacity>
- <svg width=200 height=200>
- <rect x=50 y=50 width=100 height=100 fill="green"></rect>
- <rect x=60 y=60 width=100 height=100 fill="blue" opacity="0.5"></rect>
- </svg>
- </li>
- <li id=entities>
- <svg width=200 height=200>
- <text x=50 y=100>"&¢ £»¼Ç</text>
- </svg>
- </li>
- <li id=transformed-text>
- <svg width=200 height=200>
- <text transform="translate(100,100)rotate(45)">Hello</text>
- </svg>
- </li>
- <li id=custom-font>
- <svg width=200 height=200>
- <text x=100 y=100 text-anchor=middle dy=14 style="font-family:'Stalemate';font-size:36pt;">Custom Fonts</text>
- </svg>
- <div style="color:red;">
- <p>
- Custom fonts are supported but in a very rudimentary way. Note: if you don't see the demo working,
- click "Save as PNG" - it should work.
- </p>
- <p>Make sure that the custom font is applied to a non-svg element first. This will help browser to rasterize SVG correctly onto canvas.</p>
- <p>@font-face declaration has to be inside document stylesheets (not in the external `link` tag)</p>
- <p>Only first `url()` is inlined into svg (don't have multiple urls in the font-face).</p>
- </div>
- </li>
- </ul>
- </div>
- <script src=https://code.jquery.com/jquery-latest.js></script>
- <script src=saveSvgAsPng.js></script>
- <script>
- function handleFileSelect(evt) {
- var $el = $('#filereader');
- var files = evt.target.files;
- for (var i = 0, f; f = files[i]; i++) {
- var reader = new FileReader();
- reader.onload = (function(file) {
- return function(e) {
- $el.find('.load-target').html(e.target.result);
- svgAsPngUri($el.find('.load-target svg')[0], null, function(uri) {
- $el.find('input').hide()
- $el.find('.preview').html('<img src="' + uri + '" />');
- });
- $el.find('.save').click(function() {
- saveSvgAsPng($el.find('.load-target svg')[0], 'test.png');
- });
- }
- })(f);
- reader.readAsText(f);
- }
- }
- if (window.File && window.FileReader && window.FileList && window.Blob) {
- document.getElementById('file').addEventListener('change', handleFileSelect, false);
- }
- function inlineTest(title, $el, saveOptions, testOptions) {
- var svg = $el.html();
- var template = $('#inline-template').html();
- var row = $el.html(template);
- row.find('h2').text(title);
- row.find('.canvas').html(svg);
- var canvas = row.find(testOptions && testOptions.selector || 'svg')[0];
- svgAsPngUri(canvas, saveOptions, function(uri) {
- row.find('.preview').html('<img src="' + uri + '" />');
- });
- row.find('.save').click(function() {
- saveSvgAsPng(canvas, 'test.png', saveOptions);
- });
- }
- inlineTest('Directly in the HTML', $('#inline'));
- inlineTest('With linked PNG image', $('#embedded-png'));
- inlineTest('With linked SVG image', $('#embedded-svg'));
- inlineTest('Sized with pixels', $('#sized-with-pixels'));
- inlineTest('Sized with style', $('#sized-with-style'));
- inlineTest('Sized with CSS', $('#sized-with-css'));
- inlineTest('At a higher resolution', $('#scaling'), {scale: 2});
- inlineTest('When CSS styling selectors are prefixed', $('#selectors-prefixed'), {
- selectorRemap: function(s) {return s.replace('#selectors-prefixed ', '')}
- });
- inlineTest('Modifying the style', $('#modified-style'), {
- modifyStyle: function(s) {return s.replace('green', 'red')}
- });
- inlineTest('Modifying the whole CSS rule', $('#modified-css'), {
- modifyCss: function(selector, properties) {
- selector = selector.replace('#selectors-prefixed ', '');
- properties = properties.replace('green', 'blue');
- return selector + '{' + properties + '}';
- }
- });
- inlineTest('Exporting a group within an SVG', $('#group'), null, {
- selector: '#sub-group'
- });
- inlineTest('Percentage Height and Width', $('#percentage-size'));
- inlineTest('Background color', $('#background-color'), {backgroundColor: 'lightblue'});
- inlineTest('Pan and Zoom', $('#pan-and-zoom'), {
- left: -50,
- top: -50,
- width: 300,
- height: 300
- });
- inlineTest('With Unicode characters', $('#unicode'));
- inlineTest('With gradients', $('#gradient'));
- inlineTest('With foreign objects', $('#foreign-object'));
- inlineTest('With opacity', $('#opacity'));
- inlineTest('When setting xmlns on foreign object children', $('#xmlns-override'));
- inlineTest('When using HTML entites', $('#entities'));
- inlineTest('Transformed text', $('#transformed-text'));
- inlineTest('With custom fonts', $('#custom-font'));
- var $sandbox = $('#sandbox');
- $sandbox.find('.render').click(function() {
- $sandbox.find('.error').hide().text('');
- $sandbox.find('.load-target').html($('#sandbox textarea').val());
- var canvas = $sandbox.find('.load-target svg')[0];
- try {
- svgAsPngUri(canvas, null, function(uri) {
- $sandbox.find('.preview').html('<img src="' + uri + '" />');
- });
- $sandbox.find('.save').unbind('click').click(function() {
- saveSvgAsPng(canvas, 'test.png');
- });
- } catch(err) {
- $sandbox.find('.error').show().text(err.message);
- $sandbox.find('.preview').html('');
- }
- });
- </script>
|