Stretch a SVG image along the x-axis - reactjs

I'm looking to stretch my SVG image along the horizontal axis, which is acting as a background for some HTML divs. It is a simple bar that takes up the middle third horizontally :
It must not move on the vertical, and when horizontal is stretched, the image also must stretch so that the bar takes up the middle third.
Currently if I stretch horizontally, it maintains its vertical position which is good, but the SVG does not take up a third but maintains its original width:
Here is the React code :
function BackgroundSVG() {
let outerDiv = {
position:"relative",
border: "3px solid red",
}
let svgStyle = {
position:"absolute",
top:"0px",
border: "3px solid pink",
zIndex: -1,
width: "100%",
height: "200px"
}
return (
<div style={outerDiv}>
<div>Lorem ipsum .......</div>
<svg style={svgStyle}
viewBox={`0 0 ${600} ${200} `}
xmlns="http://www.w3.org/2000/svg">
<path d={`M ${200} ${100} H ${400}`} strokeWidth={12} stroke="blue"/>
</svg>
</div>
);
}
Here is a code pen
https://codepen.io/oliverwatkins/pen/MWqWmQz
How do I stretch the image along the x-axis, while preserving things on the y-axis?
I have tried to play around with the widths and heights but that does not seem to work. I assume that if I keep width at 100% and height at a 200px that this would solve the problem.

Default preserveAspectRatio attribute value is xMidYMid meet
so that browser try to maintain image aspect ratio.
For stretching SVG image, we need to set
preserveAspectRatio="none"

Related

make SVG document responsive with the viewbox based on aspect ratio

I have created this codesandbox to illustrate the problem.
I have this ResponsiveSVG component:
export function ResponsiveSVG({
height,
width,
children,
origin = { x: 0, y: 0 },
preserveAspectRatio = "xMidYMid meet",
innerRef,
className,
...props
}: ResponsiveSVGProps): JSX.Element {
const aspect = height === 0 ? 1 : width / height;
const adjustedHeight = Math.ceil(width / aspect);
return (
<div
data-testid="cutting-svg-container"
style={{
position: 'relative',
overflow: 'visible',
height: '1px',
}}
>
<svg
style={{ overflow: 'visible' }}
className={className}
preserveAspectRatio={preserveAspectRatio}
width={width}
height={adjustedHeight}
viewBox={`${origin.x} ${origin.y} ${width} ${height}`}
ref={innerRef}
{...props}
>
{children}
</svg>
</div>
);
}
I would like my ResponsiveSVG component to know how to fit its content to the full width of the container while keeping the aspect ratio the same.
In the example I have a circle as a child of the svg document:
<ResponsiveSVG width={width} height={height}>
<circle cx={width / 2} cy={height / 2} r={radius} />
</ResponsiveSVG>
On desktop, it looks like this:
But in mobile view, it looks like this:
My calculations make the viewBox width and height the same as the actual width and height I am passing in, so no change happens.
The viewBox coordinates are exactly the same as the viewport.
Passing the width and height of the containing element to the viewBox is actually the wrong direction. viewBox defines the canvas on which the svg content elements are drawn: if you draw a circle with r="50", the viewBox width value must be at least 100, otherwise, it will never fit. If the center is at cx=50, the viewBox x value must not be greater than 0, otherwise the left side is cut off.
Responsiveness in SVG is achieved because there needs not to be any relation between the viewBox values and the width and height of the <svg> element. The canvas the child elements are drawn on is always fitted to the parent element dimensions.
In short, if all you want to achieve is to fit a circle in a <svg> element, choose a arbitrary radius r, set cx=cy=r and viewBox="0 0 2r 2r", and it will work. There is no need to know anything explicit about the parent size.
If you want your <svg> element to be the width of the container, set it so: width: 100%. The default height is auto, so no need to write that or preserveAspectRatio. It will size itself such that the canvas defined by viewBox fits itself.
<div
style="
position: relative;
overflow: visible;
height: 1px;
"
>
<svg
style="
width: 100%;
overflow: visible;
"
viewBox="0 0 100 100"
>
<circle cx="50" cy="50" r="50" />
</svg>
</div>

Why does my React site resize incorrectly?

I have been using React to create my own professional website. With this, I wanted a cool background in which I decided to use https://www.npmjs.com/package/react-particles-js
The only issue I have is that on mobile the particles do not fill the screen but instead seem to be stuck at the top of the screen. The easiest way to see this is to go to https://my-app-bwp36ovux.vercel.app/ and look at the site on your monitor then use the F12 debug console to change it to a mobile device. When doing so take note of the floating particles in the background.
I got this const I use to set values for the particles
const particalOpt = {
particles:{
number:{
value: 150,
density: {
enable: true,
value_area: 800
}
},
line_linked:{
distance: 100,
opacity: .2,
width: 2,
},
move:{
speed: 1,
bounce: true,
}
}
}
I call it by simply using
<div className="background">
<Particles
params = {particalOpt}
/>
</div>
I can not seem to put my finger on why using the background attribute these particles do not fill mobile devices.
For the full code go to https://github.com/13Smat/MySite
Thank you in advance.
Issue
The background div has 100vw and 100vh, but the canvas has its own width and height with an override to 100% each. The problem is that the div rendering the canvas has no absolute dimensions for the canvas to inherit from or be relative to.
DOM
<div class="background">
<div id="tsparticles"> // <-- no height/width for canvas to be % of
<canvas
class="tsparticles-canvas-el"
width="558"
height="281"
style="width: 100%; height: 100%;" // <-- applied style
></canvas>
</div>
</div>
The canvas element's applied style:
element.style {
width: 100%;
height: 100%;
}
Solution
Provide a width and height to the #tsparticles div. Add the following CSS to your App.css file.
#tsparticles {
width: 100%;
height: 100%;
}
please take a look at #Drew Reese's comment and edit your question.
In the meantime I can provide a helpful example
The attributes that will help you most here are background-size, background-position. You can also look at other background properties that might help.
Side note: React does not particularly change how styling works, I would recommend playing around with CSS - it's the best way to learn
If you want particles to be set like a full screen background I would recommend the backgroundMode option, you can read more here
You can set that options like this:
{
backgroundMode: {
enable: true,
zIndex: 0
}
}
If you set the zIndex property to a negative value remember to change the detectsOn property to ”window” if you need mouse interactions

Unable to set Nuka Carousel slide content height

I can't get the content of my nuka-carousel slides to be the same height. Setting heightMode="max" on the carousel sets the slide heights equal, but trying to expand the slide content isn't working right.
I've tried setting height on the slides to 100%, inherit, 100vh but no matter what, the slides expand to maybe 2-20x what they should be (depending on the div with the most content).
I've also tried using flexbox with flex:1 and I've tried with css-grid. Nothing seems to help
const Item = ({ children }) => (
<div
style={{
boxShadow: "rgb(153, 153, 153) 2px 2px 4px 2px"
// height: "100%"
// height: "100vh"
/// height: 'inherit'
}}
>
{children}
</div>
);
<Carousel
wrapAround
heightMode="max"
slidesToShow={1.25}
cellAlign="center">
{/* Item components with varying content */}
</Carousel>
Here's a codesandbox, If anyone has any suggestions I'd appreciate it.
https://codesandbox.io/s/brave-khorana-bowrz?file=/src/index.js

Victory Charts background grid

Is it possible to display a grid like this using Victory charts?
So far I can only get a grid with both vertical and horizontal lines on top of my bars likes this:
The horizontal bars can be removed by removing stroke style.
The vertical bars which I wanted to keep can be 'moved' behind by changing the order of the elements as noted here: https://formidable.com/open-source/victory/guides/layout/#svg-render-order
By providing
style={{
grid: { stroke: '#ddd444', strokeWidth: 1.5 },
}}
to your dependant axis like
<VictoryAxis
dependentAxis
tickFormat={(tick) => `${tick}`}
style={{
grid: { stroke: '#F4F5F7', strokeWidth: 0.5 },
}}
/>
you will achieve desired result.

Autosizer making a div of height and width 0

My configuration goes as follows:
// Calling it
<div style={{ width: 1000, height: 800 }}>
<MyComponent />
</div>
// MyComponent.js
<InfiniteLoader { ...itsProps }>
{({ onRowsRendered }) => (
<AutoSizer>
{({ width, height }) => (
<Table
width={ width }
width={ height }
...
The problem is that this is what is being rendered:
<div style="overflow: visible; height: 0px; width: 0px;">
<div class="ReactVirtualized__Table" role="grid">
...
So nothing is seen in the screen.
Maybe I misunderstood Autosizer usage, so I set it up to adjust itself to the parent's width/height.
What am I missing?
The height: 0 style in the snippet of HTML you shared isn't actually a problem, because of the overflow: visible style. This is the way AutoSizer is meant to work.
I suggest you read the "Using AutoSizer" docs page. I suspect your problem is similar to one of the common issues mentioned there:
AutoSizer expands to fill its parent but it will not stretch the parent. This is done to prevent problems with flexbox layouts. If AutoSizer is reporting a height (or width) of 0- then it's likely that the parent element (or one of its parents) has a height of 0. One easy way to test this is to add a style property (eg background-color: red;) to the parent to ensure that it is the correct size. (eg You may need to add height: 100% or flex: 1 to the parent.)

Resources