Fabricjs svg parsing error - javascript

guys, i've got a very mysterious problem here.
I've got an svg <svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='263.342' height='132.29' viewBox='0 0 263.342 132.29'><path fill='#FFC55D' d='M148.718 39.53S152.442 0 199.442 0v57.604l-26.236-18.628-16.908 18.628-.467 42.678s-.99 18.658-20.113 18.658'/><path fill='#FEDBC8' d='M63.44 132.29c-44 0-46.084-38.09-45.903-44.62-1.45 0-11.837-1.268-11.837-9.974 0-13.785 11.74-11.97 11.74-11.97V55.567l-.644-24.077H63.44v100.8zM63.44 132.29c43 0 45.76-38.09 45.58-44.62 1.45 0 11.5-1.268 11.5-9.974 0-13.785-12.08-11.97-12.08-11.97V55.567l.995-24.077H63.44v100.8z'/><path fill='#1CA97E' d='M46.18 70.078c0 3.405-2.76 6.167-6.167 6.167-3.406 0-6.167-2.762-6.167-6.167 0-3.406 2.76-6.167 6.167-6.167 3.406 0 6.167 2.762 6.167 6.168M80.642 70.078c0 3.405 2.76 6.167 6.167 6.167 3.405 0 6.166-2.762 6.166-6.167 0-3.406-2.76-6.167-6.167-6.167s-6.168 2.762-6.168 6.168'/><path fill='#F37885' d='M49.263 99.49c0 8 6.356 14.196 14.196 14.196s14.196-6.195 14.196-14.195H49.263zM63.335 113.688c7.84 0 14.32-6.196 14.32-14.196H63.44'/><path fill='#78492F' d='M18.44 67.9V31.627s-11 1.995-11 7.98V61.37s4 6.53 11 6.53'/><path fill='#78492F' d='M74.44 9.49H14.62s2.54 13 8.888 13H.11s-2.72 14 18.863 14H74.44v-27zM108.44 31.626V20.562c0-5.985-4.88-10.07-8.21-11.07H71.21c-3.33 1-7.77 5.085-7.77 11.07v15.93h45V67.9s11-1.995 11-7.98V38.157s-5-6.53-11-6.53'/><path fill='#FEDBC8' d='M199.44 132.29c-42 0-44.34-36.73-44.164-43.028-1.398 0-11.287-1.224-11.287-9.62 0-13.293 11.45-11.544 11.45-11.544v-9.794l-.775-17.812h44.776v91.798z'/><path fill='#82A0D7' d='M183 72.296c0 3.284-2.663 5.946-5.947 5.946s-5.947-2.662-5.947-5.946 2.663-5.947 5.947-5.947S183 69.01 183 72.295'/><path fill='#F37885' d='M185.974 100.49c0 8 6.13 13.69 13.69 13.69s13.69-5.69 13.69-13.69h-27.38z'/><path fill='#FFC55D' d='M250.282 39.53S246.442 0 199.442 0v57.49h43.377l.466 42.736s.933 18.687 20.056 18.687M199.44 57.603V.233s-48.974-3.266-48.974 39.88c0 30.275 4.956 27.518 4.956 27.518l.32-10.494s16.66-2.798 16.66-14.925c5.863 7.695-1.96 15.393 27.04 15.393'/><path fill='#FEDBC8' d='M199.44 132.29c42 0 44.232-36.73 44.058-43.028 1.398 0 11.34-1.224 11.34-9.62 0-13.293-11.396-11.544-11.396-11.544v-9.794l.558-.813h-44.56v74.8z'/><path fill='#82A0D7' d='M216.232 72.296c0 3.284 2.663 5.946 5.947 5.946s5.946-2.662 5.946-5.946-2.663-5.947-5.947-5.947-5.948 2.662-5.948 5.946'/><path fill='#F37885' d='M199.44 114.18c7.563 0 13.913-5.688 13.913-13.688H199.44'/></svg>
And some code, which renders this svg on my canvas, using fabricjs:
fabric.loadSVGFromString(str, function(objects, options) {
var obj = fabric.util.groupSVGElements(objects, options);
obj.lockUniScaling = true;
obj.scaleToWidth(200);
canvas.add(obj).renderAll();
});
So i got this:
Instead of this:
P.S. Background color is ok – canvas' color.
Help guys

so this svg works fine.
you probably used an old version of fabricjs when trying to parse it. that comes out is an old "a" command drawing bug.
if you copy paste this svg in the fabricjs.com/kitchensink that is a general demo/tester you will see it working good.
so please download latest version of library and you should be fine

Related

Is it possible to create single path SVG for below image?

I was able to create this(however it has the transparent part at the center - want it solid white)
"M62,31c0,17.1-13.9,31-31,31S0,48.1,0,31S13.9,0,31,0S62,13.9,62,31z M48.5,43.9L46,44l-7.3-11.3 c-0.5-0.8-1.4-1.2-2.3-1.2L26.7,32l-0.2-2.8l9.6-2.7c0.9-0.3,1.4-1.2,1.2-2.1c-0.2-0.9-1.2-1.4-2.1-1.2l-8.9,2.5L25.9,19 c-0.1-1.4-1.3-2.5-2.7-2.4c-1.4,0.1-2.5,1.3-2.4,2.7l0.9,15.6c0.1,1.4,1.3,2.5,2.7,2.4l10.7-0.6L42.5,48c0.5,0.7,1.3,1.2,2.1,1.2 c0,0,0.1,0,0.1,0l4-0.1c1.4-0.1,2.5-1.2,2.5-2.6C51.1,44.9,49.9,43.8,48.5,43.9z M23.4,6c-2.8,0-5.1,2.3-5.1,5.1s2.3,5.1,5.1,5.1 s5.1-2.3,5.1-5.1S26.2,6,23.4,6z M35.2,42.4c-0.2,5.7-4.8,10.2-10.5,10.2c-5.8,0-10.5-4.7-10.5-10.5c0-3.5,1.8-6.7,4.5-8.6v-3.9 c-4.6,2.3-7.9,7-7.9,12.5c0,7.7,6.2,13.9,13.9,13.9c6.1,0,11.3-4,13.2-9.5L35.2,42.4z"
Path 1 result :
Later, I was able to extract another path for the center figure, which is:
"M40.3,40.3c0.1,1.4-1,2.6-2.5,2.6l-4,0.1c0,0-0.1,0-0.1,0c-0.9,0-1.7-0.4-2.1-1.2l-7.3-11.3l-10.7,0.6 c-1.4,0.1-2.6-1-2.7-2.4L10,13.3c-0.1-1.4,1-2.6,2.4-2.7c1.4-0.1,2.6,1,2.7,2.4l0.4,6.8l8.9-2.5c0.9-0.2,1.8,0.3,2.1,1.2 c0.3,0.9-0.3,1.8-1.2,2.1l-9.6,2.7l0.2,2.8l9.6-0.5c0.9,0,1.8,0.4,2.3,1.2L35.1,38l2.5-0.1C39.1,37.8,40.3,38.9,40.3,40.3z M12.5,10.2c2.8,0,5.1-2.3,5.1-5.1S15.4,0,12.5,0C9.7,0,7.4,2.3,7.4,5.1S9.7,10.2,12.5,10.2z M13.9,46.6c-5.8,0-10.5-4.7-10.5-10.5 c0-3.5,1.8-6.7,4.5-8.6v-3.9C3.2,25.9,0,30.6,0,36.1C0,43.8,6.2,50,13.9,50c6.1,0,11.3-4,13.2-9.5l-2.7-4.1 C24.2,42,19.6,46.6,13.9,46.6z"
Path 2 result :
Looking for a single path SVG, which creates an exact image like .
Thank you in advance.
Haters will say I'm cheating. And they will be absolutely right.
<svg
width="60"
height="60"
style="background-color: LightSalmon; border-radius: 100%"
viewBox="1 1 60 60"
>
<path d="M62 31c0 17.1-13.9 31-31 31S0 48.1 0 31 13.9 0 31 0s31 13.9 31 31zM48.5 43.9L46 44l-7.3-11.3c-.5-.8-1.4-1.2-2.3-1.2l-9.7.5-.2-2.8 9.6-2.7c.9-.3 1.4-1.2 1.2-2.1-.2-.9-1.2-1.4-2.1-1.2l-8.9 2.5-.4-6.7c-.1-1.4-1.3-2.5-2.7-2.4-1.4.1-2.5 1.3-2.4 2.7l.9 15.6c.1 1.4 1.3 2.5 2.7 2.4l10.7-.6L42.5 48c.5.7 1.3 1.2 2.1 1.2h.1l4-.1c1.4-.1 2.5-1.2 2.5-2.6-.1-1.6-1.3-2.7-2.7-2.6zM23.4 6c-2.8 0-5.1 2.3-5.1 5.1s2.3 5.1 5.1 5.1 5.1-2.3 5.1-5.1S26.2 6 23.4 6zm11.8 36.4c-.2 5.7-4.8 10.2-10.5 10.2-5.8 0-10.5-4.7-10.5-10.5 0-3.5 1.8-6.7 4.5-8.6v-3.9c-4.6 2.3-7.9 7-7.9 12.5C10.8 49.8 17 56 24.7 56c6.1 0 11.3-4 13.2-9.5l-2.7-4.1z"/>
</svg>
The real answer is that compound paths in a single <path/> element can only have one style (as the style is defined by the said path).

Convert svg to react-native-svg

What is the easiest way to do this? I found plenty of svg to JSX converters, which is what I want, but that doesn't work in react-native. I need to convert the svg code to something I can display in my app using react-native-svg. Thanks!
I can think of the following options. The one you use will depend on the amount of files you have to convert.
Option 1 (few files)
Copy-paste your svg code on this site and check the React Native checkbox. This will give you the code which you can then use with react-native-svg
Use that output within the following code (replace the SvgComponent with what was generated):
import React, { Component } from 'react';
import { View } from 'react-native';
import Svg, { Circle, Path } from 'react-native-svg';
const SvgComponent = props => (
<Svg viewBox="0 0 48 1" style={props.style}>
<Path d="M0 0h48v1H0z" fill="#063855" fillRule="evenodd" />
</Svg>
);
class MySVGIcon extends Component {
render() {
const { style } = this.props;
const component = SvgComponent(style);
return <View style={style}>{component}</View>;
}
}
export default MySVGIcon;
Option 2 (many files)
Instead of converting them, you can embed them directly in your code with react-native-remote-svg.
For instance you can do this:
import Image from 'react-native-remote-svg';
class MyImageClass extends Component {
render () {
// Embed code or read a SVG file...
const mySVGImage = '<svg width="48px" height="1px" viewBox="0 0 48 1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><rect id="Rectangle-5" x="25" y="36" width="48" height="1"></rect></svg>';
return (
<Image source={{
uri: "data:image/svg+xml;utf8," + mySVGImage
}}/>
);
}
}
Option 3 (coolest option)
It isn't free like the two other options, but it isn't expensive either. PaintCode is one of those tools that I just love. Version 3+ now supports java-script. So you could load your svg files in it, and it will spit out code that you can use in your app. The advantage here that the interface is friendlier than the first option above, and you can then animate each object inside the svg file from your code.
I'm using expo for building react native app and I had the same inquiry but I found some solution here react-native-svg. I use the XML Option which was as below.
STEP 1- first I used this link convert SVG to JSX for React to convert the SVG to JSX (Some times you don't need to convert it, it depends on icon itself).
STEP 2- open new file component and import react and import { SvgXml } from 'react-native-svg', then create a normal functional component inside.
STEP 3- wrap the converted SVG icon tag with Quotation mark to be like this "<svg>some icon code inside</svg>" then store it in a variable var, const, let..etc.
STEP 4- return <SvgXml xml={the variable goes here} />.
STEP 5- export the component as usual.
here is an example code
import React from 'react'
import { SvgXml } from 'react-native-svg';
function FastRunningIcon(props) {
const xml = `<svg
xmlns="http://www.w3.org/2000/svg"
width="${props.width}"
height="${props.height}"
viewBox="0 0 21.244 20"
>
<path
fill="#595959"
d="M7.379 20a1.21 1.21 0 01-.783-.291.235.235 0 01-.04-.041 1.258 1.258 0 01-.293-1.036 2.179 2.179 0 01.544-1.049c.387-.459 1.089-1.209 2.085-2.231H6.874a1.426 1.426 0 01-1.062-.412 1.263 1.263 0 01-.332-.863 1.166 1.166 0 01.345-.85 1.7 1.7 0 011.01-.425c.454-.05 1.532-.07 2.575-.09h.187c.4-.008.649-.009.869-.01h.506L8.4 8.925 8.38 8.9a2.075 2.075 0 01-.2-1.877 3.3 3.3 0 011.165-1.272l.013-.013L12.412 3.6l-1.221-.957-4.011.094h-.04c-.064 0-.116.007-.168.007a2.209 2.209 0 01-.642-.1 1.271 1.271 0 01-.43-.213.755.755 0 01-.279-.478.014.014 0 00-.006-.006s-.006 0-.007-.007A1.132 1.132 0 016.078.9 2.949 2.949 0 017.02.492a.547.547 0 01.067-.013l4.356-.465h.027a1.174 1.174 0 01.2-.014h.052a1.324 1.324 0 01.743.252l.008.005.008.005.019.018.019.013c.6.392 1.155.764 1.575 1.049.373.251.8.54 1.142.784.177.125.3.218.4.293a.7.7 0 01.087.077l.045.041a.251.251 0 00.028.022.364.364 0 01.105.112.038.038 0 00.011.014.111.111 0 01.015.026l.008.012c.171.258.752 1.14 1.041 1.675a1.8 1.8 0 01.226.678.438.438 0 01.08.212l.185 2.005 2.178.12h.013c.062.005.124.007.185.009h.032a2.025 2.025 0 01.66.1.857.857 0 01.451.358 1.063 1.063 0 01.12.625v.013a1.108 1.108 0 01-.6.851 2.419 2.419 0 01-1.022.252h-.027c-.568 0-3.523.171-3.545.173h-.08a1.093 1.093 0 01-.632-.324 1.458 1.458 0 01-.276-.454v-.022l-.006-.014a.384.384 0 01-.04-.093l-.226-1.3-.688.437-.483.307-.029.019-1.138.724.119.184.117.182c.267.414.555.863.88 1.374l.162.256.014.023.02.031.031.048.015.023c.464.732 1.165 1.838 1.365 2.211v.013a1.29 1.29 0 010 1.395 1.568 1.568 0 01-1.3.545h-.969l-.1.1-.026.027c-.005.005-.6.615-1.48 1.49-.9.9-1.878 1.874-2.284 2.231a3.069 3.069 0 01-1.2.757.963.963 0 01-.299.036zm2.7-4.647c-.019.02-1.972 2.024-2.616 2.788a1.347 1.347 0 00-.345.638.333.333 0 00.066.292l.008.007c.061.054.091.081.146.081a.442.442 0 00.113-.021 2.415 2.415 0 00.85-.571c.339-.3 1.428-1.376 2.257-2.2.333-.332.51-.514.682-.689.1-.1.2-.2.314-.32zm-.133-.894a.486.486 0 01.186.043h3.6a.771.771 0 00.611-.2c.062-.082.109-.186-.053-.478v-.014c-.133-.247-.908-1.49-1.58-2.55-.534-.841-1-1.572-1.18-1.847v-.009l-.076-.117-.067-.1-.014-.022a.426.426 0 01.127-.585l3.1-1.98a.424.424 0 01.266-.173l.366-.233.167-.106.473-.3.021-.013.141-.09a.683.683 0 00.319-.346.646.646 0 00-.12-.531c-.2-.365-.66-1.094-1.014-1.641l-.007-.011-.007-.012v.008a.075.075 0 010 .021l-.005-.01-.01-.009a.772.772 0 00-.071-.059l-.031-.023a10.05 10.05 0 00-.341-.256 53.275 53.275 0 00-.807-.553l-.091-.063-.015-.01-.023-.015-.011-.011-.014-.01-.16-.108c-.479-.323-.967-.645-1.289-.858l-.174-.115-.009-.005-.009-.006-.057-.038L12 .97V.965a.16.16 0 01-.022-.021.388.388 0 00-.278-.092.654.654 0 00-.127.012h-.014l-4.316.452a.014.014 0 00-.006.006s0 .006-.007.007a2.253 2.253 0 00-.651.266c-.115.084-.126.112-.119.185a.482.482 0 00.119.053A1.62 1.62 0 007 1.891h.13l4.21-.093a.456.456 0 01.266.093L13.399 3.3a.425.425 0 01-.026.677l-3.52 2.47a2.649 2.649 0 00-.889.93 1.1 1.1 0 00.146 1.076l.014.013a.01.01 0 010 .007.005.005 0 000 .006l3 4.4a.424.424 0 01.024.436.419.419 0 01-.37.229c-.008 0-1.056.005-2.151.027-1.131.022-2.4.059-2.7.093a.867.867 0 00-.517.186.268.268 0 00-.08.238.422.422 0 00.106.279.519.519 0 00.438.146h2.9a.382.382 0 01.12-.04.492.492 0 01.047-.014zm6.6-8.084l-.02.013-.026.012-.053.034-.008.005c-.53.343-.844.544-1.014.652l.281 1.609a.836.836 0 00.119.186.143.143 0 00.1.049h.063c.457-.028 2.77-.168 3.443-.17h.026a1.842 1.842 0 00.651-.146c.124-.066.139-.1.147-.173a.745.745 0 000-.122v-.012a2.468 2.468 0 00-.387-.036h-.041l-.22-.014H19.6l-2.54-.133a.428.428 0 01-.4-.385l-.12-1.368zm-8.41 4.693a.48.48 0 01-.063 0H.42a.43.43 0 01-.08-.851h7.729a.48.48 0 01.063 0 .43.43 0 110 .859zm-1.7-2.125a.539.539 0 01-.063 0H.42a.43.43 0 01-.08-.851h6.029a.539.539 0 01.063 0 .43.43 0 110 .859zm0-2.125a.542.542 0 01-.063 0H.42a.43.43 0 01-.08-.851h6.029a.542.542 0 01.063 0 .43.43 0 110 .859zm2.123-2.124a.51.51 0 01-.065 0H.42a.43.43 0 01-.08-.85h8.154a.51.51 0 01.065 0 .429.429 0 010 .859zm10.347 0a2.337 2.337 0 112.337-2.337 2.34 2.34 0 01-2.337 2.332zm0-3.825a1.472 1.472 0 00-1.488 1.488 1.487 1.487 0 102.974 0A1.471 1.471 0 0018.906.864z"
data-name="Shape Copy 4"
></path>
</svg>`
return <SvgXml xml={xml} />
}
export default FastRunningIcon;
You can simply try this tool that will do the conversion for you: https://github.com/MoOx/react-from-svg
It can convert SVG to React Native files, but also to Reason/ReScript React Native files, and even React DOM files with some option to remove fill or strokes attributes.

Chrome adds attributes [requiredExtensions, systemLanguage] when logging a cloned SVGElement [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Issue
Was working with transforms on SVGElements and discovered something I do not comprehend.
Basically I am trying to clone an exising SVGElement using cloneNode(true) and change its Matrix by using transform.baseVal.getItem(0).setMatrix(). This all works fine as long as I do not log the new SVGElement using console.log().
Here is an example
Have to check the actual console and not the inline output of the snippet.
;window.onload = function(){
var tSVG = document.querySelector('svg');
var tSVGElement = tSVG.querySelector('#AL > g');
var tSVGElement2 = tSVGElement.cloneNode(1);
var tMatrix2 = tSVGElement2.transform.baseVal.numberOfItems ? tSVGElement2.transform.baseVal.getItem(0).matrix : tSVGElement2.transform.baseVal.appendItem(tSVG.createSVGTransform()).matrix
console.log(1, tSVGElement2);
tMatrix2.e += 50;
tMatrix2.f += 50;
tSVGElement2.transform.baseVal.getItem(0).setMatrix(tMatrix2)
tSVGElement.parentNode.appendChild(tSVGElement2);
console.log(2, tSVGElement2);
};
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2253" width="811" height="661">
<g id="AL" class="Touchable">
<g transform="matrix(0.0736096,0,0,0.0736094,313.881,379.029)">
<g stroke-width=".39819491" transform="matrix(2.51133 0 0 2.51134 -239.06 -636.03)">
<rect width="397" height="397" x="95.790001" y="253.86" fill="#ccc" stroke="#000" stroke-width="1.19458485" stroke-miterlimit="3" ry="0" rx="0"></rect>
<path fill="#fff" d="M153.88 347.3H354.4v207.58H153.88z"></path>
<path fill="#010002" d="M202.2 395.8c-3.22-3.24-4.84-7.17-4.84-11.8 0-4.63 1.62-8.55 4.85-11.8 3.3-3.23 7.2-4.85 11.8-4.85 4.6 0 8.6 1.62 11.8 4.86 3.3 3.3 4.9 7.2 4.9 11.8 0 4.6-1.6 8.6-4.8 11.8-3.2 3.3-7.1 4.9-11.8 4.9-4.7 0-8.5-1.6-11.8-4.8zm-21.32 79.6c1.04.8 2.26 1.22 3.64 1.22 1.4 0 2.6-.4 3.65-1.22 1.04-.8 1.56-2.13 1.56-3.98v-45.1c0-.7.34-1.16 1.04-1.4.7-.22 1.27-.33 1.73-.33.46 0 1.04.1 1.74.3.7.2 1.04.7 1.04 1.4V530c0 2.1.75 3.83 2.25 5.2 1.5 1.4 3.3 2.1 5.38 2.1s3.9-.7 5.4-2.1c1.5-1.37 2.3-3.1 2.3-5.2v-63.46c0-1.16.5-1.9 1.4-2.26.9-.36 1.6-.53 2.1-.53s1.1.18 1.9.52c.8.34 1.2 1.1 1.2 2.25V530c0 2.08.8 3.8 2.3 5.2 1.5 1.4 3.3 2.08 5.4 2.08 2.3 0 4.2-.7 5.6-2.07 1.4-1.4 2.1-3.1 2.1-5.2l.4-103.7c0-.7.4-1.1 1.1-1.4.7-.2 1.3-.3 1.78-.3.5 0 1.05.1 1.75.4.7.3 1 .7 1 1.4v45.1c0 1.9.5 3.2 1.55 4 1 .8 2.2 1.2 3.45 1.2s2.4-.4 3.46-1.2c1.03-.8 1.55-2.1 1.55-4v-47.9c0-4.6-1.54-8.8-4.66-12.5-3.15-3.7-7.37-5.5-12.7-5.5h-36.5c-5.3 0-9.2 1.9-11.6 5.6-2.44 3.7-3.65 7.8-3.65 12.5v47.8c0 1.9.5 3.2 1.53 4zm179.86-134.93c2.08 1.96 3.12 4.45 3.12 7.46v206.73c0 3-1.04 5.5-3.12 7.46-2.1 1.97-4.63 2.95-7.64 2.95H155.04c-3 0-5.55-.98-7.63-2.95-2-1.96-3.1-4.45-3.1-7.46V347.93c0-3 1.1-5.5 3.1-7.46 2.1-1.97 4.7-2.95 7.7-2.95h198c3 0 5.6.98 7.7 2.95zm-14.23 14.4H161.7v192.86h184.8V354.86zm-52.7 45.78c4.6 0 8.6-1.62 11.8-4.85 3.2-3.23 4.9-7.17 4.9-11.8 0-4.63-1.6-8.55-4.8-11.8-3.2-3.23-7.1-4.85-11.8-4.85-4.6 0-8.5 1.62-11.8 4.86-3.2 3.3-4.8 7.2-4.8 11.8 0 4.6 1.6 8.6 4.9 11.8 3.3 3.2 7.2 4.9 11.8 4.9zm-33.1 74.75c1.1.8 2.3 1.22 3.7 1.22 1.4 0 2.6-.4 3.7-1.22 1.1-.8 1.6-2.13 1.6-3.98v-45.1c0-.7.4-1.16 1.1-1.4.7-.22 1.3-.33 1.8-.33s1.1.1 1.8.3c.7.2 1.06.7 1.06 1.4V530c0 2.1.75 3.83 2.25 5.2 1.5 1.4 3.3 2.1 5.4 2.1 2.08 0 3.87-.7 5.38-2.1 1.5-1.37 2.27-3.1 2.27-5.2v-63.46c0-1.16.43-1.9 1.4-2.26.9-.35 1.6-.53 2.1-.53s1.1.18 2 .52c.95.34 1.4 1.1 1.4 2.25V530c0 2.08.7 3.8 2.1 5.2 1.4 1.4 3.24 2.08 5.56 2.08 2.1 0 3.9-.7 5.4-2.07 1.5-1.4 2.26-3.1 2.26-5.2V426.3c0-.7.3-1.16 1-1.4.7-.22 1.25-.33 1.7-.33.46 0 1.03.1 1.73.32s1.02.7 1.02 1.4v45.1c0 1.8.5 3.1 1.56 3.9 1.05.8 2.27 1.2 3.65 1.2 1.4 0 2.6-.4 3.65-1.2 1.04-.8 1.56-2.2 1.56-4v-47.8c0-4.7-1.6-8.8-4.84-12.5-3.25-3.7-7.53-5.6-12.84-5.6H275c-5.3 0-9.26 1.8-11.8 5.5-2.55 3.7-3.8 7.8-3.8 12.5v47.8c0 1.8.5 3.1 1.54 4zm180.6 49.16h-15.6V472.7s.1-2.13-2.7-2.13h-23.7c-3.9 0-3.2 2.55-3.2 2.55v52.52h-16.8c-4.9 0-.4 4.27-.4 4.27l29.8 36.1s2.5 2.9 5.1.3c3.6-3.5 28.9-37.2 28.9-37.2s4.5-4.4-1.4-4.4zm-61.2-140.98h15.6v51.85s0 2.14 2.7 2.14H422c3.88 0 3.2-2.56 3.2-2.56v-52.5H442c4.9 0 .4-4.2.4-4.2l-29.87-36.1s-2.45-2.8-5.02-.3c-3.5 3.6-28.9 37.3-28.9 37.3s-4.5 4.5 1.5 4.5z"></path>
</g>
</g>
</g>
</svg>
Expected output:
<g transform="matrix(0.0736096 0 0 0.0736094 363.881 429.029)">..</g>
Actual output:
<g transform="matrix(0.0736096 0 0 0.0736094 363.881 429.029)" requiredExtensions="" systemLanguage="">..</g>
So as soon as I log the cloned SVGElement Chrome adds the two attributes requiredExtensions and systemLanguage, which leads to the element no being rendered. As soon as I remove the console.log(tSVGElement2); on the clone it all works fine.
Why does Chrome add those two attributes on logging?
IE11 adds it also just on the child element.
FOR YOUR WHY QUESTION:
I opened an issue for this, confirmed by chrome (https://bugs.chromium.org/p/chromium/issues/detail?id=873470), seems like this is a bug. And the reason is:
I'd guess that this is caused by attribute synchronization, and the reason console.log triggers it is that it enumerates all properties and thus creates the tear-off/wrapper for systemLanguage/requiredExtensions - which in turn makes them require synching.
pre-edit: Seems like I was wrong about namespace not being inherited, one interesting thing is though ‘requiredExtensions’ attribute should either be set to 'true' or not exist for an element to render. This is part of SVG spec # 5.7.1 here and normally the attribute (together with systemLanguage) is set on the switch element. Interestingly, consoling the cloned g within the main thread, adds this attribute with value "" which translates to false and ends up the element not being rendered.
However if you wait for the event loop to finish and then log, the attributes are not there, see this FIDDLE.
As a conclusion, if you clone a g node and console log it without appending it to the tree, these attributes will appear and the element won't be rendered. Though I do not know whether this was the intended behavior or a bug.
SOLUTION
Until the behavior is sorted out, monkey patch the appendChild, I had to use a microtask queue because apparently the attributes are added during calling appendChild:
SVGGraphicsElement.prototype.appendChild = (function(append){
return function(node){
setTimeout(function(){
node.removeAttribute("requiredExtensions");
node.removeAttribute("systemLanguage");
},0);
return append.apply(this,arguments);
}
}(SVGGraphicsElement.prototype.appendChild));
http://jsfiddle.net/ibowankenobi/8s97ophj/
SOLUTION 2:
Obviously, you'd have to monkey patch other functions that modify DOM tree as well such as inserNode etc. In that case a mutation observer provides a more generic solution. You can watch multiple times with different parents, the same observer is recycled:
function watch(node,parentNode){
var config = watch._config,
callback = function(list,observer){
list.forEach(function(d,i){
if(d.type !== "childList"){return}
if(
Array.prototype.slice.call(d.addedNodes)
.some(function(d,i){
return d === node
})
) {
console.log("added??");
setTimeout(function(){
node.removeAttribute("requiredExtensions");
node.removeAttribute("systemLanguage");
},0);
observer.disconnect();
}
})
},
observer = node._observer || (node._observer = new MutationObserver(callback));
observer.observe(parentNode,config);
return node;
}
watch._config = {childList:true,subtree:true};
to use:
var tSVG = document.querySelector('svg');
var tSVGElement = tSVG.querySelector('#AL > g');
var tSVGElement2 = tSVGElement.cloneNode(1);
watch(tSVGElement2,tSVGElement.parentNode/*Or tSVG since subtree:true*/);
....
Once in the DOM, the observer is disconnected and the attributes are removed, you can modify the function and provide a list of attributes to change if you want. See this working FIDDLE
~~This happens because you are not cloning the entire svg, but the g, at that instant the xmlns is not defined for this g because it inherited it from its ownerSVG. The moment you append it to its parent svg, the browser understands that it is part of SVG. If you console log after tSVGElement.parentNode.appendChild(tSVGElement2), it should output fine.~~

Is there in Jquery or Dojo or plain JavaScript way to convert div to image?

Is there in Jquery or Dojo or pure JavaScript way to convert div to image ? Extension of image is arbitrary.
You could create an empty div and create a class with the background-image property set to your image. Then, using jQuery or Dojo, add the class to your div.
.myImage {
background-image: url(image.png);
background-repeat: no-repeat;
}
<div id="myDiv"></div>
$('#myDiv').addClass('myImage');
Yes, there is, but it's tricky and maybe impossible to get it to render exactly as it appears on the page unless the div element and its appearance as possibly defined in CSS are defined in a manner than can fully stand-alone from the page.
Embed the desired HTML into SVG as a foreign object.
Draw the image. (These two steps are summarized here https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas?redirectlocale=en-US&redirectslug=Web%2FHTML%2FCanvas%2FDrawing_DOM_objects_into_a_canvas )
Obtain the canvas data using getImageData()
Encode the data into the desired image format (or send the stream of data to the server encoded as base64 (step 3 and 4 can be done as one step by using toDataURL)
An example image format easy to work with on one's own is the Unix PNM (PBM, PGM, and PPM) formats which can be sent as ASCII data.
P2
# foo.pgm
18 7
9
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 3 3 3 3 0 0 6 6 6 6 0 0 9 9 9 9 0
0 3 0 0 0 0 0 6 0 0 6 0 0 9 0 0 9 0
0 3 3 3 0 0 0 6 0 0 6 0 0 9 0 0 9 0
0 3 0 0 0 0 0 6 0 0 6 0 0 9 0 0 9 0
0 3 0 0 0 0 0 6 6 6 6 0 0 9 9 9 9 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
(Enlarged 20x: http://www.codelib.net/html/foo.png )
Stealing from https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement to show you an example of using toDataURL to output PNG image data:
function test() {
var canvas = document.getElementById("canvas");
var url = canvas.toDataURL();
var newImg = document.createElement("img");
newImg.src = url;
document.body.appendChild(newImg);
}
Another way is to build upon the work done by html2canvas:
create screenshot of webpage using html2canvas (unable to initialize properly)
The accepted answer there shows how to screenshot the HTML body element, but it could easily be modified to "screenshot" the contents of a div by modifying the jQuery selector on the first line of the code.

From Javascript array to an image of some kind

Ok, so I have the following array of data:
shipGrid = [
['0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0'],
['0','0','1','0','0','0','0','1','0','0'],
['0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','1','1','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0'],
['0','0','1','0','0','0','0','1','0','0'],
['0','0','0','1','1','1','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0']];
Which I have translated into this clickable group of <li>'s:
Is it possible to convert this array of <li>'s into an image of somekind?
It doesn't have to be just a PNG, GIF or JPG - it can be a SVG or Vector based thing.
I'm a bit stumped, I'd like to do it without a server side language - so I thought maybe a SVG library or would work well...?
Cheers.
edit: This needs to be viewable in the browser itself.
Since you're mentioning SVG I guess that you could accept a solution that would only work in modern browsers. If so, you should defenitely take a look at the HTML 5 <canvas> element. Note however, that the canvas element will not be supported in Internet Explorer until version 9. ExplorerCanvas is an open source project that tries to fill in that gap, but I have not tried it.
<!DOCTYPE html>
<html>
<head>
<title>From JavaScript array to canvas</title>
<style>
body {
background-color: #eee;
}
</style>
</head>
<body>
<canvas id="image"></canvas>
<script>
var imageArray = [
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,1,0,0],
[0,0,0,1,1,1,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0]
];
var imageCanvas = document.getElementById('image');
// getContext will be supported in Internet Explorer 9.
if (imageCanvas.getContext) {
imageCanvas.height = imageArray.length;
imageCanvas.width = imageArray[0].length;
var imageContext = imageCanvas.getContext("2d");
imageContext.fillStyle = "#fff";
imageContext.fillRect(0, 0, imageCanvas.width,
imageCanvas.height);
imageContext.fillStyle = "#000";
for (var x = 0; x < imageCanvas.width; x++) {
for (var y = 0; y < imageCanvas.height; y++) {
if (imageArray[y][x] === 1) {
imageContext.fillRect(x, y, 1, 1);
}
}
}
}
</script>
</body>
</html>
The code above has only been tested in Google Chrome.
Dive Into HTML5 has a nice chapter on the canvas element. Other resources are Mozilla Developer Network's Canvas tutorial. You could also take a look at Bill Mill's canvas tutorial.
A simple way of doing this would be to save it into Portable Bitmap Format (PBM), which it just a simple ASCII file
The above example might look sonmething like the following in the contents this ASCII file
P1
# This is a smiley
10 10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
It's pretty trivial to convert tour array into a map like the above.
If you're saving this from JavaScript then the user's browser security settings may prevent you from doing this. See the following link: http://www.c-point.com/JavaScript/articles/file_access_with_JavaScript.htm
Edit:
Yeah, this image type won't display in the browser. Check out the following link for supported image types by browser:
http://en.wikipedia.org/wiki/Comparison_of_web_browsers#Image_format_support
Javascript can't convert HTML into images by itself, you will need Ajax and a server side plugin to do this for you.
I would tackle this problem by sending the shipGrid data to the server, which interprets the sent data and renders the image in the desired style.
Without knowing what server side languages you have available to you we can't assist further, but any image plugin should have extensive documentation and examples.
Edit
Forgot about SVG's, you might be able to get JS to dynamically render an SVG image for you, take a look at this tetris example:
http://croczilla.com/bits_and_pieces/svg/samples/svgtetris/svgtetris.svg
Take a look at the source, should give you something to work by.

Categories