This working codepen demo here shows SVG code that makes up the Number 9 in terms of bitmaps. May I ask if there is a way to convert the bitmaps into a real number 9 that is readable? The Number 9 color is a little faint in my demo, so have to look closely.
Any help will be very much appreciated :)
SVG Code for Number 9
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1066.6667 800"
height="800"
width="1066.6667"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6" /><g
transform="matrix(1.3333333,0,0,-1.3333333,0,800)"
id="g10"><path
id="path20"
style="fill:none;stroke:#000000;stroke-width:0.074;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 294.09,426.05 -0.46,-1.38 -0.92,-0.92 -1.38,-0.46 h -0.46 l -1.37,0.46 -0.92,0.92 -0.46,1.38 v 0.46 l 0.46,1.37 0.92,0.92 1.37,0.46 h 0.46 l 1.38,-0.46 0.92,-0.92 0.46,-1.83 v -2.3 l -0.46,-2.29 -0.92,-1.38 -1.38,-0.46 h -0.91 l -1.38,0.46 -0.46,0.92" /></g></svg>
Related
I have an external SVG file which contains the following SVG definition:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>
The SVG has multiple paths, so for me to be able to change colours of individual paths I need to be able to load the SVG file contents into a Javascript variable like this:
var svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';
Then I can use conditional statements to alter the colours e.g.
switch(centerId) {
case 1:
svgSource = svgSource.replace("#ffbf00", "#005D00");
break;
case 2:
svgSource = svgSource.replace("#ffbf00", "#A20000");
break;
case 3:
svgSource = svgSource.replace("#ffbf00", "#ffbf00");
break;
}
I could define and use the inline SVG code hard coded into the Javascript as shown, but for maintenance and continuity it would be much better to use existing, centralised, external SVG files.
How can I load the contents of the SVG file into a javascript variable/object?
CSS Styling
Try using CSS to style the paths instead of replacing parts of source code.
Concept code example, using the style attribute of svg elements to apply some CSS:
"use strict";
const svg = document.querySelector("svg");
const paths = svg.querySelectorAll("path");
paths[0].style = "fill: #FF0000;"
svg.querySelector("circle").style = "fill: rebeccapurple";
svg {
height: 150px;
width: 100px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>
Potentially you could improve on this by writing svg source that expects to be styled by CSS instead of being over-ridden by style attribute values.
See also: How to use external SVG in HTML?
Getting the source of an external SVG file
An external svg file can be included in HTML using a pair of <object> tags. For example if "svg-file.svg" is in the same directory as the HTML file:
<object type="image/svg+xml" id="mySVG"
data="svg-file.svg"
width="100"
height="150"
></object>
Subject to security policies: the svg file must be from the same domain and served from a network or localhost server - due to blanket security restriction placed on local files, the source of svg files loaded using the file:// protocol. can't be accessed.
Picking up the svg source is a bit obscure. This worked for me after page load, using the above HTML:
window.onload = ()=> {
console.log("loaded");
const svgObject = document.querySelector("#mySVG");
const svg = svgObject.getSVGDocument().documentElement;
const svgSource = svg.outerHTML;
console.log("svgElement, tag name '%s' ", svg.tagName, svg);
console.log("svgSource: ", svgSource);
console.log("path.st0: ", svg.querySelector('.st0'));
};
One solution is to load the svg image by setting the innerHTML property of an arbitrary container to your svg string.
This then gives you two options: firstly, for heavy changes, you have access to each path as part of the DOM and can maniulate them using javascript. This simply requires making a reference to container.children[0]; Alternatively, for simple changes such as colour changes, it makes each element directly targetable by style rules where you can specify colours in the usual way.
The snippet illustrates adding the svg to the dom using your string, and resets some colours with simple style rules. Making a reference for changes using javascript is shown commented at the foot of the code.
let svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';
const container = document.getElementsByTagName('div')[0];
container.innerHTML = svgSource;
// for js manipulation:
// svgObject = container.children[0];
div {
width: 50%;
}
.st0 {
fill: red;
}
.st1 {
fill: yellow;
}
circle {
fill: green;
}
<div>
</div>
i have square shape made of 4 lines and as these are 4 different paths so am not able to get size of the shape for that am trying to merge these lines together so that i have square shape as single path and then i can get its size using getBBox() method :
square shape
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 -237.4911 302.46116 237.4911">
<g xmlns="http://www.w3.org/2000/svg" transform="matrix(1 0 0 -1 0 0)">
<path d= "M129.734598 192.711157V226.160594" stroke="red" stroke-width=".56693" id="1"/>
<path d= "M129.734598 192.711157H159.496439" stroke="red" stroke-width=".56693" id="2"/>
<path d= "M159.496439 192.711157V226.160594" stroke="red" stroke-width=".56693" id="3"/>
<path d= "M129.734598 226.160594H159.496439" stroke="red" stroke-width=".56693" id="4"/>
</g>
</svg>
so i try to merged them which is partially ok like this
M129.734598 192.711157 V226.160594 H159.496439 V226.160594 H159.496439
so any idea how to properly do it to get square shape as single path
Hint 1
Your first path
M 129.734598 192.711157 V 226.160594
is equivalent to
M 129.734598 192.711157 L 129.734598 226.160594
Your second path
M 129.734598 192.711157 H 159.496439
is equivalent to
M 129.734598 192.711157 L 159.496439 192.711157
Perhaps in this form, the sequence of moves might be more obvious.
Hint 2
In your first attempt you were close (I've rounded these values for more clarity)
M 129 192 V 226 H 159 V 226 H 159
Your last two path commands are not doing anything.
In order to complete the square, your third side (the second V) needs to return to the start Y position. And your fourth side (the second H) needs to return to the start X position.
Hope this helps, and is not too cryptic.
Summary
Please see this example notebook, which isn't working as expected. The third cell in the notebook should show an SVG window containing a simple green box. Example output is shown in cell 4*.
Details
After running the notebook, a tooltip popup is displayed when I hover over the element in the console. Because of this popup I believe the SVG container and box (which is a PATH element) are definitely being created, they just aren't being displayed. The popup says they are being rendered at size 0x0.
How can I get this to work as expected, so that the contents of the SVG window show up in the output cell (cell #3)?
Code
Here is the cell by cell code for convenience.
Cell #1
import ipywidgets.widgets as widgets
from traitlets import Unicode
class Test(widgets.DOMWidget):
_view_name = Unicode('TestView').tag(sync=True)
_view_module = Unicode('test').tag(sync=True)
_view_module_version = Unicode('0.1.0').tag(sync=True)
Cell #2
%%javascript
require.undef('test');
define('test', ["#jupyter-widgets/base"], function(widgets) {
var TestView = widgets.DOMWidgetView.extend({
render: function() {
TestView.__super__.render.apply(this, arguments);
var svg = document.createElement('svg');
svg.innerHTML = '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 0.0,0.0 L 50.0,0.0 L 50.0,50.0 L 0.0,50.0 L 0.0,0.0 z" />';
this.el.appendChild(svg);
console.log(svg); // when you hover over this line in the console, you can see the SVG has been created...
},
});
return {
TestView : TestView,
};
});
Cell #3
Test() # this cell should output a green box
Cell #4: Example Output
%%html
<svg>
<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 0.0,0.0 L 50.0,0.0 L 50.0,50.0 L 0.0,50.0 L 0.0,0.0 z" />
</svg>
* NOTE: clone and run notebook to show the expected output at the bottom.
Figured this out: for reasons I don't understand, you have to utilize document.createElementNS() function to add SVG, not document.createElement(). You also have to use svg.setAttributeNS() rather than svg.setAttribute().
Here's a fixed version of the notebook. Code:
%%javascript
require.undef('test');
define('test', ["#jupyter-widgets/base"], function(widgets) {
var TestView = widgets.DOMWidgetView.extend({
render: function() {
TestView.__super__.render.apply(this, arguments);
var xmlns = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(xmlns, "svg");
svg.setAttributeNS(null, "viewBox", "0 0 100 100");
svg.innerHTML = '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 0.0,0.0 L 50.0,0.0 L 50.0,50.0 L 0.0,50.0 L 0.0,0.0 z" />';
this.el.appendChild(svg);
console.log(svg); // when you hover over this line in the console, you can see the SVG has been created...
},
});
return {
TestView : TestView,
};
});
Is there a way to reverse draw (so actually erase) a chosen path drawn before using Vivus for SVG?
Let's say we have a fiddle like this:
http://jsfiddle.net/z7x4ovn7/92/
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" id="keyhole" version="1.1" width="306" height="296" id="svg2">
<g transform="translate(-162.46995,-477.2863)" id="layer1">
<path d="m 314,480 l 0,100" stroke="#20552a" id="path2000" stroke-width="2" fill="none"/>
<path d="m 314.15745,481.69558 c -59.20089,0.53774 -114.80979,36.72219 -137.3125,95.34375 -29.39129,76.56693 8.83932,162.45246 85.40625,191.84375 l 34.03125,-88.6875 c -20.0678,-7.71358 -34.3125,-27.15324 -34.3125,-49.9375 0,-29.54723 23.95277,-53.5 53.5,-53.5 29.54723,0 53.5,23.95277 53.5,53.5 0,22.78426 -14.2447,42.22392 -34.3125,49.9375 l 34.03125,88.6875 c 39.29085,-15.08234 70.3239,-46.1154 85.40625,-85.40625 29.39129,-76.56693 -8.83932,-162.48371 -85.40625,-191.875 -17.94537,-6.88859 -36.40853,-10.07087 -54.53125,-9.90625 z" id="path2830" fill="#40aa54" stroke="#20552a" stroke-width="8" stroke-miterlimit="4"/>
</g>
</svg>
new Vivus('keyhole', {
type: 'oneByOne',
duration: 50
}, function doDone(obj) {
obj.el.classList.add('finished');
});
After drawing all paths I would like to reverse-draw the path with id path2000. Would you have any ideas?
The library has a few restrictions that make it circuitous, but the effect can be achieved if you divide the SVG with two inner <svg> tags. This makes them addressable for different animations, and you can play one of them backwards:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" id="keyhole" version="1.1" width="306" height="296">
<svg id="part1">
<path transform="translate(-162.46995,-477.2863)" d="m 314,480 l 0,100" stroke="#20552a" id="path2000" stroke-width="2" fill="none"/>
</svg>
<svg id="part2">
<path transform="translate(-162.46995,-477.2863)" d="m 314.15745,481.69558 c -59.20089,0.53774 -114.80979,36.72219 -137.3125,95.34375 -29.39129,76.56693 8.83932,162.45246 85.40625,191.84375 l 34.03125,-88.6875 c -20.0678,-7.71358 -34.3125,-27.15324 -34.3125,-49.9375 0,-29.54723 23.95277,-53.5 53.5,-53.5 29.54723,0 53.5,23.95277 53.5,53.5 0,22.78426 -14.2447,42.22392 -34.3125,49.9375 l 34.03125,88.6875 c 39.29085,-15.08234 70.3239,-46.1154 85.40625,-85.40625 29.39129,-76.56693 -8.83932,-162.48371 -85.40625,-191.875 -17.94537,-6.88859 -36.40853,-10.07087 -54.53125,-9.90625 z" id="path2830" fill="#40aa54" stroke="#20552a" stroke-width="8" stroke-miterlimit="4"/>
</svg>
</svg>
// started immediately
var inner = new Vivus('part1', {
duration: 20
}, function () {
// start outer animation after inner has been drawn
outer.play(1);
});
// started later
var outer = new Vivus('part2', {
duration: 50,
start: 'manual'
}, function (obj) {
obj.el.classList.add('finished');
// reverse inner animation after outer has been drawn
inner.play(-1);
});
In EaselJS only shapes can became a masks, so I was wondering if I can convert somehow SVG made in Inkscape into EaselJS, I found this great tool - http://www.professorcloud.com/svg-to-canvas/ that allows me to convert SVG to Context, but is there a way/tool to easily convert SVG to EaselJS Shape (this is almost the same object as Shape in Flash/AS3)? I need only a basic shape like this:
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="776.4032"
height="405.87927"
id="svg1383">
<defs
id="defs1385" />
<metadata
id="metadata1388">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(15.455332,-13.016229)"
id="layer1">
<path
d="m 1193.5963,82.437378 a 369.81683,206.47517 0 1 1 -739.63371,0 A 369.81683,206.47517 0 1 1 1193.5963,82.437378 Z"
transform="matrix(1.0497132,0,0,0.98287671,-491.98585,134.93009)"
id="mask"
style="fill:#008000;fill-opacity:1;stroke:none;display:inline" />
</g>
<g
transform="translate(15.455332,-13.016229)"
id="layer2" />
</svg>
After you generate your js code on webpage you gave, you can override function in shape called draw. Just paste generated code in your function and you should be able to see your image.
Example code:
var s = new createjs.Shape();
// this is important because if we dont change graphics our overriden
// function wont be called.
s.graphics.beginFill("#FF0000").rect(0, 0, 75, 100);
//save old draw function
var oldDraw = s.draw;
// here we switch draw funciton to the one generated from svg file
s.draw = this.draw;
// draw our model on cache
s.cache(0, 0, 66, 113, 2);
// and now we can back to old drawing function
s.draw = oldDraw;