Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
react-zdog
Advanced tools
react-zdog is a React wrapper for Zdog, a pseudo-3D engine for canvas and SVG. It allows you to create and animate 3D-like illustrations using a simple and intuitive API.
Creating Shapes
This code demonstrates how to create a basic shape using react-zdog. The `Shape` component is used to draw a simple shape with a specified stroke and color.
```jsx
import React from 'react';
import { Illustration, Shape } from 'react-zdog';
const MyShape = () => (
<Illustration>
<Shape
stroke={20}
color="#636"
/>
</Illustration>
);
export default MyShape;
```
Animating Shapes
This code demonstrates how to animate a shape using react-zdog. The `useRef` and `useEffect` hooks are used to rotate the shape continuously.
```jsx
import React, { useRef, useEffect } from 'react';
import { Illustration, Shape } from 'react-zdog';
const AnimatedShape = () => {
const shapeRef = useRef(null);
useEffect(() => {
const animate = () => {
shapeRef.current.rotate.y += 0.03;
requestAnimationFrame(animate);
};
animate();
}, []);
return (
<Illustration>
<Shape
ref={shapeRef}
stroke={20}
color="#636"
/>
</Illustration>
);
};
export default AnimatedShape;
```
Combining Shapes
This code demonstrates how to combine multiple shapes using the `Group` component in react-zdog. The `Group` component allows you to group multiple shapes together and manipulate them as a single entity.
```jsx
import React from 'react';
import { Illustration, Shape, Group } from 'react-zdog';
const CombinedShapes = () => (
<Illustration>
<Group>
<Shape
stroke={20}
color="#636"
/>
<Shape
translate={{ x: 40 }}
stroke={20}
color="#E62"
/>
</Group>
</Illustration>
);
export default CombinedShapes;
```
react-three-fiber is a React renderer for Three.js, a popular 3D library. It allows you to create complex 3D scenes and animations using React components. Compared to react-zdog, react-three-fiber offers more advanced 3D capabilities and is suitable for more complex and high-performance 3D applications.
react-konva is a React wrapper for the Konva framework, which is used for creating 2D canvas applications. While it focuses on 2D rather than 3D, it provides a powerful API for creating and animating shapes, images, and text. It is more suitable for 2D graphics compared to the pseudo-3D capabilities of react-zdog.
react-pixi is a React wrapper for PixiJS, a fast 2D rendering engine. It allows you to create high-performance 2D graphics and animations using React components. Similar to react-konva, it is focused on 2D graphics but offers a more performance-oriented approach compared to react-zdog's pseudo-3D capabilities.
npm install zdog react-zdog
# or
yarn add zdog react-zdog
react-zdog is a declarative abstraction of zdog, a cute pseudo 3d-engine. Doing zdog in React allows you to break up your scene graph into declarative, re-usable components with clean, reactive semantics. Try a live demo here.
import ReactDOM from "react-dom";
import React from "react";
import { Illustration, Shape } from "react-zdog";
ReactDOM.render(
<Illustration zoom={8}>
<Shape stroke={20} color="lightblue" rotate={{ x: Math.PI }} />
</Illustration>,
document.getElementById("root")
);
The Illustration
object is your portal into zdog. It forwards unreserved properties to the internal Zdog.Illustration instance. The component auto adjusts to re-size changes and fills out the wrapping relative/absolute parent.
<Illustration element="svg" /> // Can be either 'svg' or 'canvas'
element
: Sets the graphics rendering DOM Element. Can be either 'svg' or 'canvas'. Default is "svg"frameloop
: Determins the render loop behavior, Can be either 'always' or 'demand'. default is 'always'.pointerEvents
: enables pointer events on zdog elements if set to true. Default is False.style
: styles for main renderer dom elemeent container.onDragStart
: callback on illustration's on drag start event listeneronDragMove
: callback on illustration's on drag move event listeneronDragEnd
: callback on illustration's on drag end event listenerAnd all the other props you will pass will be attached to illustration object. So any other properties or methods that you wanna set on illustration can be passed as prop as it is.
All hooks can only be used inside the Illustration element because they rely on context updates!
If you're running effects that need to get updated every frame, useRender gives you access to the render-loop.
import { useRender } from "react-zdog";
function Spin({ children }) {
const ref = useRef(undefined);
useRender((t) => (ref.current.rotate.y += 0.01));
return <Anchor ref={ref}>{children}</Anchor>;
}
Gives you access to the underlying state-model.
import { useZdog } from 'react-zdog'
function MyComponent() {
const {
illu, // The parent Zdog.Illustration object
scene, // The Zdog.Anchor object that's being used as the default scene
size, // Current canvas size
} = useZdog()
Gives you access to function that updates the one scene frame on each call. It is useful only if you're setting frameloop
props on Illustration component as demand
function MyComponent() {
const invalidate = useInvalidate()
const boxRef = useRef()
const rotate = () => {
boxRef.current.rotate.x += 0.03;
boxRef.current.rotate.y += 0.03; //this will update underlying javascript object
invalidate() //But you need to call invalidate to render the changes on screen
}
return (
<Box
ref={boxRef}
{/* ...other props */}
/>
)}
React-zdog supports the Click, Pointer Move, Pointer Enter and Pointer Leave events on Zdog elemets.
To use pointer events just enable the pointer events by setting pointerEvents
prop to true
on Illustration
component.
<Illustration pointerEvents={true} />
and use onClick, onPointerMove, onPointerEnter and OnPointerLeave on any zdog element.
const onClick = (e, ele) => {
//runs when user clicks on box
};
const onPointerMove = (e, ele) => {
//runs when user moves pointer over box
};
const onPointerEnter = (e, ele) => {
//runs when user's pointer enters the box
};
const onPointerLeave = (e, ele) => {
//runs when user's pointer leaves the box
};
return (
<Box
onClick={onClick}
onPointerMove={onPointerMove}
onPointerEnter={onPointerEnter}
onPointerLeave={onPointerLeave}
/>
);
import React, { useRef, useEffect } from 'react';
import { Illustration, useRender, useInvalidate, Box } from 'react-zdog';
// RotatingCube Component
const RotatingCube = () => {
const boxRef = useRef();
// Use the useRender hook to continuously update the rotation
useRender(() => {
if (boxRef.current) {
boxRef.current.rotate.x += 0.03;
boxRef.current.rotate.y += 0.03;
}
});
return (
<Box
ref={boxRef}
width={50}
height={50}
depth={50}
color="#E44"
leftFace="#4E4"
rightFace="#44E"
topFace="#EE4"
bottomFace="#4EE"
/>
);
};
// App Component
const App = () => {
return (
<Illustration zoom={4}>
<RotatingCube />
</Illustration>
);
};
export default App;
import React, { useRef, useState } from 'react';
import { Illustration, useRender, Box } from 'react-zdog';
// InteractiveCube Component
const InteractiveCube = () => {
const [isClicked, setIsClicked] = useState(false);
const colorsBeforeClick = {
main: "#E44",
left: "#4E4",
right: "#44E",
top: "#EE4",
bottom: "#4EE"
};
const colorsAfterClick = {
main: "#FF5733",
left: "#33FF57",
right: "#3357FF",
top: "#FF33A1",
bottom: "#A133FF"
};
const currentColors = isClicked ? colorsAfterClick : colorsBeforeClick;
const handleBoxClick = () => {
setIsClicked(!isClicked);
};
return (
<Box
width={50}
height={50}
depth={50}
color={currentColors.main}
leftFace={currentColors.left}
rightFace={currentColors.right}
topFace={currentColors.top}
bottomFace={currentColors.bottom}
onClick={handleBoxClick}
/>
);
};
// App Component
const App = () => {
return (
<Illustration pointerEvents={true} zoom={4}>
<InteractiveCube />
</Illustration>
);
};
export default App;
import React, { useRef, useEffect } from "react";
import { Illustration, useInvalidate, Box } from "react-zdog";
// RotatingCube Component
const RotatingCube = () => {
const boxRef = useRef();
const invalidate = useInvalidate();
useEffect(() => {
const animate = () => {
if (boxRef.current) {
boxRef.current.rotate.x += 0.03;
boxRef.current.rotate.y += 0.03;
invalidate(); // Manually trigger a render
}
};
const intervalId = setInterval(animate, 1000); // only renders the scene graph one a second instead of 60 times per second
return () => intervalId && clearInterval(intervalId);
}, [invalidate]);
return (
<Box
ref={boxRef}
width={50}
height={50}
depth={50}
color="#E44"
leftFace="#4E4"
rightFace="#44E"
topFace="#EE4"
bottomFace="#4EE"
/>
);
};
// App Component
const App = () => {
return (
<Illustration zoom={4} frameloop="demand">
<RotatingCube />
</Illustration>
);
};
export default App;
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
FAQs
React-fiber renderer for zdog
We found that react-zdog demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.