I am using React-Konva to draw shapes in my app. I have drawn a circle inside another circle and grouped them. Now, what I want to do is that on a button click the circles should animate (move horizontally). Here is my related code:
<Layer>
<Motion style={{a: spring(open ? 400 : x)}}>
{({a}) => {
return(
<div
style={{
WebkitTransform: `translate3d(${a}px, 0, 0)`,
transform: `translate3d(${a}px, 0, 0)`,
}}
>
<Group draggable={true}>
<CircleComponent
x={parseInt(x)}
y={parseInt(y)}
radius={parseInt(radius)}
color={color}
shadowValue={parseInt(shadowValue)}
/>
<CircleComponent
x={parseInt(x)}
y={parseInt(y)}
radius={parseInt(innerRadius)}
color={innerColor}
/>
</Group>
</div>
);}
}
</Motion>
</Layer>
Right now I am getting this error: 'Cannot read property '_idCounter' of undefined'. And this is because I'm introducing a div container inside Layer tag. But if I remove the div container and apply the transform styling to the Group tag, nothing happens. I have read the docs and the Group class doesn't accept any style props. Is there any workaround?
You can't add div as a child of Layer because layer can have only Konva.Group or Konva.Shape as children (not DOM elements).
Group don't style property, but you can use offsetX and offsetY to achieve our effect. Something like:
<Group draggable={true} offsetX={a}>
Related
I am working on a stacked barchart. Here is the codepen https://codepen.io/a166617/pen/NWvZGLd
As you can see in codepen, the x-axis label is overlapping each other and i am trying to make it at an angle so that they wont overlap each other. For e.g. this screenshot below
I tried to add transform: rotateX(90deg) as a style but it does not show properly. Here is the line of code where i added the above css
<text
x={125 + rowIndex * 60}
y={520}
textAnchor="middle"
style={{ fill: 'red',
fontSize: '13px',
transform: `rotateX(90deg)`
}}
>{entry.name}</text>
Can someone please let me know how to achieve this so that the x-axis label is clearly viewed.
Rotate transforms will rotate around the current origin. Which for SVGs defaults to the origin of the SVG. That is 0,0. Because your text is nowhere near (0, 0), your transform will rotate the text away from where you want it.
To avoid that you'll need to change the transform-origin before you rotate. Something like this:
<text
x={125 + rowIndex * 60}
y={520}
textAnchor="end"
style={{ fill: 'red',
fontSize: '13px',
transformOrigin: (125 + rowIndex * 60)+'px 520px',
transform: 'rotateZ(-45deg)'
}}
>{entry.name}</text>
I did it a slighlty different way in my updated answer to your previous question. I used the special version of rotate (rotate(angle,cx,cy)) that only the SVG transform attribute accepts. It includes an X,Y centre of rotation. For CSS, you have to use transform-origin.
I just begin to learn Three js and I face to a problem when tryng to add a plane geometry based on a img tag on the dom.
Context
Here is my actuel html template :
<figure>
<div class="aspect" />
<img class="img" src="#/assets/images/project1.jpg" />
</figure>
The img tag is hidden by css property display: none and the .aspect div give the size of the element by receiving width: 50vw and padding-top: 60%
I calculate the width - height of the element by using getBoundingClientRect func and applying it to the plane geometry like that :
const geometry = new THREE.PlaneBufferGeometry(el.width, el.height, 5)
Then I simply apply the texture of my image to it
My problem
As you can see on the screenshots, the plane geometry has not the exact size of my aspect div (in red) :
For the moment I manually set the z axis of my camera, but I know it's not the good solution and just wanted to know if there was an existing solution to acheive this ?
Thank you in advance !
Solved by using an OrthographicCamera
Doc here :
https://threejs.org/docs/#api/en/cameras/OrthographicCamera
I had an issue with Framer Motion in passing the event handler in the child component.
Sandbox below:
https://codesandbox.io/s/framer-motion-svg-checkbox-forked-vgrre?file=/src/Example.tsx
The expected behavior is that when i hover on the black circle, a capsule shape icon will appear. When I move my cursor out of the circle, the capsule shape icon will disappear.
In the example above, the onMouseEnter and onMouseOut doesn't work if i put them in the CircleBackground component. (as I have it now)
But if I move them to the <motion.svg>, then the capsule shape icon will appear when hover on svg container.
But the intention is to have the capsule shape appear only when I hover on the circle, not on the svg container. Because i don't need the animation when hovering on white space.
Hope i made my question clear. Thanks
Here is a possible solution to your problem:
https://codesandbox.io/s/so-q-63601325-68peh?file=/src/Example.tsx:1016-1344
Your HoverBackground and CircleBackground are covering each other and hence the mouse events are not reaching the child component.
Toggling the pointer-events property on the HoverBackground solves this:
<HoverBackground
path={editHoverBackground}
variants={tickVariants}
style={{
pathLength,
opacity,
pointerEvents: isChecked ? "all" : "none"
}}
custom={isChecked}
location="translate(23,39)"
onMouseOut={() => setIsChecked(!isChecked)}
/>
I'm trying to transform an image that sits behind another layer holding a png ( the template ). I want to transform the image below this layer but keep it where it is so the above layer stays as the template.
Is it possible to show the transform controls at the top above everything?
<Stage width={480} height={620} onMouseDown={this.handleStageMouseDown}>
{this.props.file ? (
<Layer>
<Uploaded file={this.props.file} />
<TransformerComponent
selectedShapeName={this.state.selectedShapeName}
/>
</Layer>
) : null}
<Layer listening={false}>
<Overlay />
</Layer>
</Stage>
You need to change the structure of your nodes. Just show transformer on top of all other shapes. If you need to disable events for overlayer, you can use listening={false}.
<Stage width={480} height={620} onMouseDown={this.handleStageMouseDown}>
<Layer>
{this.props.file &&
<Uploaded file={this.props.file} />
}
{/* use listening={false} for image in overlay */}
<Overlay/>
<TransformerComponent
selectedShapeName={this.state.selectedShapeName}
/>
</Stage>
If anyone's looking for a solution using hooks, I found that if you have a ref for the Transformer, you can easily call the zIndex() method with an arbitrarily high number when your shape is selected, then redraw it to be safe (it might work without this part)
useEffect(() => {
if (isSelected) {
trRef.current.zIndex(10000);
trRef.current.getLayer().batchDraw();
}
}, [isSelected]);
This seems to render the Transformer above everything else on the canvas, even if the shape itself is obscured.
I'm using recharts to create pie charts. When look at this example, http://recharts.org/#/en-US/examples/PieResponsiveContainer the pie chart can be centered using ResponsiveContainer component.
But my attempt failed : https://codesandbox.io/s/ll68p643xl. Try to change the size of the viewport to a larger width, the pie isn't center anymore. I wonder what's wrong here.
ResponsiveContainer just makes the pie take the size of its container. If you inspect the html, you will see that the container is in fact the size of its parent. If you want to center it, you can make the container not take the whole parent, and use css. Something like this:
.pie-row .pie-wrap > div {
background: red;
margin: 0 auto;
}
And then the container:
<ResponsiveContainer className="container" height={70} width='30%'>
I know this is a late answer, but for anyone who is trying to center <PieChart> with width and height, pass cx prop to half the width of <PieChart>.
Like,
<PieChart width={this.props.width} height={this.props.height}>
<Pie
cx={this.props.width / 2}
cy={200}
label
outerRadius={this.props.pieData.radius}
data={this.props.pieData.data}
dataKey={this.props.pieData.dataKey}>
</Pie>
</PieChart>