Convert svg to react-native-svg - javascript
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.
Related
How to fit svg path into svg viewbox in React Native
I am trying to implement barcode scanner viewFinder and I want to use svg icon to make it look nice, but I have a problem with forcing the path element inside the svg to take up the full svg width and height. I am using react native and to generate icon i use SVGR https://react-svgr.com/playground/?native=true&typescript=true in the scan handler I set the dimensions of the svg like so: const handleBarCodeScanned = ({ type, data, bounds }: BarCodeEvent) => { if (!bounds) return; const { origin, size } = bounds; setX(origin.x); setY(origin.y); setWidth(size.width); setHeight(size.height); }; and the I ise them inside the svg which looks like so import * as React from "react"; import Svg, { SvgProps, Path } from "react-native-svg"; export const ViewFinder = (props: SvgProps & { top: number; left: number }) => { const { width, height, top, left } = props; return ( <Svg width={width} height={height} style={{ borderColor: "green", borderWidth: 2, position: "absolute", left: 0, top: 0, width: "100%", height: "100%", }} fill="none" stroke="green" preserveAspectRatio="none" viewBox={`0 0 ${width} ${height}`} > <Path d="M6.13 1L6 16a2 2 0 0 0 2 2h15"></Path> <Path d="M1 6.13L16 6a2 2 0 0 1 2 2v15"></Path> </Svg> ); }; original icon is a featerIcons crop icon https://feathericons.com/ and the original code of the icon is: <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-crop"><path d="M6.13 1L6 16a2 2 0 0 0 2 2h15"></path><path d="M1 6.13L16 6a2 2 0 0 1 2 2v15"></path></svg> as you can see I set the border color and borderWidth on the svg itself, and it scales to fit the container so here everything seems to be ok. I have viewBox and preserveAspectRatio set up its just the inner path not scaling with the svg, and it is not just this icon I have tries several and the issue is still this same so there must be something wrong with my understanding of svg. Thanks a lot for any help.
Normally a viewBox would be 4 fixed numbers, i.e. unrelated to width and height. That should give you the result you want. Your content doesn't change in size so your viewBox shouldn't change either.
Too many re-renders, trying to change an svg in React, how to fix this
I'm trying to change the color of a SVG based on the tempature, I keep getting the too many re-renders errors. I'm wondering what is the right way to get this code working, i just can't figure it out ? My code (im trying first to change the id name, to see if its works) export default function Svg({ data }) { const [colorTemp, setColorTemp] = useState('red'); console.log(data); if (data > 20) { setColorTemp('blue'); } return ( <svg id={colorTemp} enable-background="new 0 0 379.181 379.181" height="512" viewBox="0 0 379.181 379.181"
In this case you do not want to be using state as it will trigger a re-render each time it is changed. Because the value is based only on the data prop passed do a simple check like so: export default function Svg({ data }) { let colorTemp = 'red'; if(data > 20) { colorTemp = 'blue' } return ( <svg id={colorTemp} enable-background="new 0 0 379.181 379.181" height="512" viewBox="0 0 379.181 379.181" // ...
Try to use useEffect hook and set it to take effect when data changes: export default function Svg({ data }) { const [colorTemp, setColorTemp] = useState('red'); console.log(data); useEffect(() => { data > 20 ? setColorTemp('blue') : setColorTemp('red') }, [data]) return ( <svg id={colorTemp} enable-background="new 0 0 379.181 379.181" height="512" viewBox="0 0 379.181 379.181"
Fabricjs svg parsing error
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
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.