I am using jsPDF in React js. I am crating some content and drawings inside a <svg>. When I want to render the pdf, everything inside the SVG is not rendered. Is there any solution to solve this or another one to export the SVG to pdf? I want the text inside the pdf to be selectable as well, I don't want just to transform the SVG into a picture and drop it into a pdf, that is not a solution. Below is my code that is not working
import React from 'react'
import jsPDF from 'jspdf'
const About = () => {
const downloadPDF = () => {
let doc = new jsPDF("p","pt","a4")
doc.html(document.querySelector("#graph"), {
callback: function(pdf){
pdf.save("doc.pdf");
}
})
}
return (
<div id = "graph">
Some text // {/*This is rendered */}
<h1>some title</h1> {/*This is rendered */}
<svg width="500" height="500"> {/*This is not rendered */}
<circle cx="50" cy="80" r={radius} stroke="rgb(0,125,225)" stroke-width="2" fill="red"/>
</svg>
</div>
)
}
export default About
Related
I'm trying to create a custom progress bar for the HTML5 video tag. The progress bar doesn't need any controls, it's just an SVG that I'd like to fill as the video progresses.
The video is a React component:
import React, {useRef} from 'react'
const VideoSection = () => {
const videoRef = useRef()
const handlePlayVideo = () => videoRef.current.play()
return (
<div>
<button onClick={handlePlayVideo}>
Play video
</button>
<video src='./video.mp4' ref={videoRef}/>
//The SVG I'd like to animate
<svg width="595" height="28" viewBox="0 0 595 28" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M0 14C0 6.26801 6.26801 0 14 0H595V28H14C6.26801 28 0 21.732 0
14V14Z" fill="#072760"/>
</svg>
</div>
)
}
export default VideoSection
Or is there an alternative way to approach/build the progress bar? Thanks!
I want to dynamically draw/turn an SVG with React from degree paramters that im recieving. Its like the direction arrow from a weather-info.
How do I dynamically draw an SVG in Javascript / ReactJS?
How do I turn the SVG with variable input?
I'm aware, that you can draw SVG-Graphics like this:
function draw_square() {
var draw = SVG('square_1');
draw.size(120, 120);
var square = draw.rect(100, 100);
square.attr({ fill: '#f06' });
}
draw_square()
but how do I connect different svg-paths to each other?
I recommend a slightly different approach:
const WindDirectionIcon = ({ width, height }) => {
return (
<svg
id="wind-direction-arrow"
width={width}
height={height}
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M6 0L0 12L6 9L12 12L6 0Z" fill="black" />
</svg>
);
};
export default function App() {
useEffect(() => {
const degrees = 90; // Retrieve from your API
const arrow = document.getElementById("wind-direction-arrow");
arrow.setAttribute("transform", `rotate(${degrees})`);
}, []);
return (
<div className="App">
<WindDirectionIcon width="24" height="24" />
</div>
);
}
So the svg itself can be composed of a single path and the only thing we do with javascript is to set the transform attribute to rotate a certain number of degrees based on the API data you receive using template literals.
Rotate with javascript based on this answer.
Sandbox Example
I'm working on building a range slider and I am stuck trying to use the .drag function. Specifically I can't seem to get any function to run during start or drag.
I have a very simple component here:
<g
className="handle1"
transform={`translate(${xScale(value)},0)`}
onMouseOver={() => onMouseOver()}
>
<rect
className="valueBuble"
x="-8"
y="-2.5rem"
width="1rem"
height="1rem"
fill="green"
></rect>
<text
x="0"
y="-1.75rem"
width="1rem"
height="1rem"
fill="white"
textAnchor="middle"
>
{value}
</text>
<circle r="10px" fill="#fa7070" />
</g>
The entire <g> moves according to a value prop. Now my d3 code with the drag function:
d3.select("g.handle1")
.call(d3.drag().on("start", drag).on("drag", drag));
Here I attempted to call a function named drag however this function is not being called. I'm testing this with a console.log:
const drag = (event, d) => {
console.log(event.target.value);
};
I am using React functional components. Any advice on how to fix the problem.
Code Pen example: https://codepen.io/trevordammon/pen/WNxWQRm
I have an SVG file: check.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28.3 28.3"><path d="M25.2 3.638l-1.6 1.6c-4.3 4.3-8.9 9.2-13.2 13.6l-5.9-4.9-1.7-1.4-2.8 3.3 1.7 1.4 7.5 6.2 1.6 1.3 1.4-1.4c4.8-4.8 9.9-10.4 14.6-15l1.6-1.6-3.2-3.1z"/></svg>
I want a React component from it; but I don't want any wrapper tag, just
<svg>
<path […]/>
</svg>
I know I can do something like
const renderSvg = svg => React.createElement('svg', {
dangerouslySetInnerHTML: { __html: svg }
});
or even easier
const RenderSvg = (svg) => <svg dangerouslySetInnerHTML={{ __html: svg }} />;
But I would end up with:
<svg>
<svg>
<path […]/>
</svg>
</svg>
Does anyone know how to achieve this without using an external library?
Have your SVG in a separate file, than import that as a component, like this:
import {ReactComponent as Circle} from "./circle.svg"
Following is a demo sandbox
I'm working on a project with react native and we chose to use react-native-svg in order to display our map. Everything's worked perfectly so far, except for this :
I have an array of objects that each have coordinates and a size. I want to loop through this array to display an image at all of these coordinates. But no luck, I managed to diplay shapes and texts but no images.
Here is the render function of my parent element :
render() {
return (
<View>
<Svg
height={screen.height}
width={screen.width}
>
<G
width={mapSize.x}
height={mapSize.y}
x={this.state.center.x}
y={this.state.center.y}
originX={mapSize.x / 2}
originY={mapSize.y / 2}
rotation={this.state.orientation}
scale={1}
>
<Rect
width={mapSize.x}
height={mapSize.y}
x={0}
y={0}
scale={1}
fill="#0071e9"
/>
<G
width={mapSize.x}
height={mapSize.y}
x={this.state.cnv.x}
y={this.state.cnv.y}
scale={1}
>
// this is my child component's tag
<Islands
islands={this.state.contentToRender}
deg={this.state.orientation}
/>
</G>
</G>
<Image
x={(screen.width / 2) - 50}
y={-(screen.height / 2) + 94.46}
width="100"
height="189.9"
preserveAspectRatio="xMidYMid slice"
href={images.bateau}
/>
</G>
</Svg>
</View>
)
}
}
here is my child component's render :
render(){
const that = this
return(
this.props.islands.map((c) => {
return (
<Image
key={ c.id }
x={ c.position.x }
y={ c.position.y }
width={ c.size.x }
height={ c.size.y }
preserveAspectRatio="xMidYMid slice"
rotation={-that.props.deg}
originX={ c.position.x + (c.size.x / 2) }
originY={ c.position.y + (c.size.y / 2) }
href={images.rouge}
/>
)
})
)
}
And finally my images.js file :
const images = {
boussole: require('./img/Boussole.png'),
aiguille: require('./img/Aiguille.png'),
bateau: require('./img/Bateau.png'),
home: require('./img/home.png'),
cyclop_island: require('./img/ile_cyclope_navig.png'),
rouge: require('./img/smiley-carre-rouge-simple-face-magnetique.jpg'),
}
export default images
I have no issue with any aspect of the Svg component, I can display every image of the images.js file as long as they are not in a loop.
Also, even if the image doesn't display the console shows no error.