@@ -304,6 +305,7 @@ const springProps = useSpring({
feel. Try them in this sandbox!
}
+ fileToOpen={'Circle.tsx'}
/>
To use one of the presets, you can do something like this:
Animating Text
@@ -401,6 +404,7 @@ return (
maxWidth={800}
height={200}
caption="Demo: react-spring can also animate text, colors and so much more!"
+ fileToOpen={'Circle.tsx'}
/>
Exercises
@@ -445,28 +449,25 @@ const exercises: Exercise[] = [
{
whyItMatters: (
<>
-
- Let’s apply what we just learned by creating your first{' '}
- canvas
element, modifying it using a ref
and{' '}
- useEffect
.
-
- And while we’re at it, let’s explore how to adjust opacity!
+ Just applying the very basic usage we just learned
>
),
toDo: (
<>
-
- Use
useRef()
to create a ref targeting the canvas
- element.
+ Create a Circle.tsx
file that makes a{' '}
+ Circle
component
-
- Add a
useEffect()
hook to draw a blue circle on the
- canvas.
+ Create a position
state in Graph.tsx
. Each
+ time the user click on the SVG area, this position must toggle
+ between 40
and width - 40
-
- Adjust the circle’s opacity with the
globalAlpha
{' '}
- property.
+ Provide the position to the Circle
component. Render a
+ circle at this x
position, animate its movement with{' '}
+ react-spring
.
>
@@ -479,49 +480,67 @@ const exercises: Exercise[] = [
whyItMatters: (
<>
- Unlike SVG elements, strokes and fills must be drawn separately on the
- canvas. 😱
+ react-spring can animate many sorts of values. Opacity is one of them,
+ but text, and colors work too!
>
),
toDo: (
<>
- - Draw a rectangle on the canvas.
-
- Use
strokeRect()
and fillRect()
to apply a
- green stroke and fill it with pink.
+ Same as previous exercise, but add a property for the{' '}
+ opacity
.
+
+ -
+
opacity
must toggle between 0.2
and{' '}
+ 1
depending on if the circle is on the left or on the
+ right.
>
),
- practiceSandbox: 'exercise/CanvasRectOutlinePractice',
- solutionSandbox: 'exercise/CanvasRectOutlineSolution',
+ practiceSandbox: 'exercise/AnimationDefaultPractice',
+ solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
+ fileToOpen: 'Graph.tsx',
},
{
whyItMatters: (
<>
- When working with canvas drawings, you’ll often need to clear previous
- content.{' '}
+ react-spring
does not only work with SVG! HTML elements
+ can be animated too!
- This is possible with clearRect()
.
+ note also that the spring can be made directly in the{' '}
+ Graph
component. Making a separate component to organise
+ your work is nice IMO, but not required.
>
),
toDo: (
<>
- - Draw a large circle on the canvas.
-
- Use
clearRect()
to erase part of the circle.
+ In Graph.tsx
, render a parent div
using
+ the width
and height
provided at the top
+ of the component instead of the usual SVG area.
+
+ -
+ In this
div
, render another div
. It must
+ be square, have a backgroundColor
of red
{' '}
+ and be absolutely positioned.
+
+ -
+ Now make the red
div
moves from right to left when user
+ clicks on the parent div.
>
),
- practiceSandbox: 'exercise/CanvasClearRectPractice',
- solutionSandbox: 'exercise/CanvasClearRectSolution',
+ practiceSandbox: 'exercise/AnimationDefaultPractice',
+ solutionSandbox: 'exercise/AnimationSimpleDivSolution',
+ fileToOpen: 'Graph.tsx',
},
{
whyItMatters: (
@@ -547,8 +566,9 @@ const exercises: Exercise[] = [
>
),
- practiceSandbox: 'exercise/CanvasBasicLinePractice',
- solutionSandbox: 'exercise/CanvasBasicLineSolution',
+ practiceSandbox: 'exercise/AnimationDefaultPractice',
+ solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
+ fileToOpen: 'Graph.tsx',
},
{
whyItMatters: (
@@ -571,8 +591,9 @@ const exercises: Exercise[] = [
>
),
- practiceSandbox: 'exercise/CanvasTenCirclesPractice',
- solutionSandbox: 'exercise/CanvasTenCirclesSolution',
+ practiceSandbox: 'exercise/AnimationDefaultPractice',
+ solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
+ fileToOpen: 'Graph.tsx',
},
{
whyItMatters: (
@@ -598,7 +619,8 @@ const exercises: Exercise[] = [
>
),
- practiceSandbox: 'exercise/CanvasBasicTextPractice',
- solutionSandbox: 'exercise/CanvasBasicTextSolution',
+ practiceSandbox: 'exercise/AnimationDefaultPractice',
+ solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
+ fileToOpen: 'Graph.tsx',
},
];
diff --git a/viz/ReactSpringText/index.js b/viz/ReactSpringText/index.js
index 2f7ae90af..dd6a2d70e 100644
--- a/viz/ReactSpringText/index.js
+++ b/viz/ReactSpringText/index.js
@@ -1,5 +1,5 @@
-import ReactDOM from "react-dom";
-import { ReactSpringMostBasic } from "./ReactSpringMostBasic";
+import ReactDOM from 'react-dom';
+import { ReactSpringTextDemo } from './ReactSpringTextDemo';
-const rootElement = document.getElementById("root");
-ReactDOM.render(, rootElement);
+const rootElement = document.getElementById('root');
+ReactDOM.render(, rootElement);
diff --git a/viz/exercise/AnimationSimpleCircleOpacitySolution/Circle.tsx b/viz/exercise/AnimationSimpleCircleOpacitySolution/Circle.tsx
new file mode 100644
index 000000000..d2d943bbb
--- /dev/null
+++ b/viz/exercise/AnimationSimpleCircleOpacitySolution/Circle.tsx
@@ -0,0 +1,25 @@
+import { animated, useSpring } from 'react-spring';
+
+type CircleVizProps = {
+ position: number;
+ color: string;
+ opacity: number;
+};
+
+export const Circle = ({ position, color, opacity }: CircleVizProps) => {
+ const springProps = useSpring({
+ to: { position, color, opacity },
+ });
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/AnimationSimpleCircleOpacitySolution/Graph.tsx b/viz/exercise/AnimationSimpleCircleOpacitySolution/Graph.tsx
new file mode 100644
index 000000000..82f96443f
--- /dev/null
+++ b/viz/exercise/AnimationSimpleCircleOpacitySolution/Graph.tsx
@@ -0,0 +1,25 @@
+import { useState } from 'react';
+import { Circle } from './Circle';
+
+const width = 500;
+const height = 300;
+
+export const Graph = () => {
+ const [position, setPosition] = useState(40);
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/AnimationSimpleCircleOpacitySolution/index.js b/viz/exercise/AnimationSimpleCircleOpacitySolution/index.js
new file mode 100644
index 000000000..fa564d27f
--- /dev/null
+++ b/viz/exercise/AnimationSimpleCircleOpacitySolution/index.js
@@ -0,0 +1,6 @@
+// File used to render something in codesandbox only
+import ReactDOM from 'react-dom';
+import { Graph } from './Graph';
+
+const rootElement = document.getElementById('root');
+ReactDOM.render(, rootElement);
diff --git a/viz/exercise/AnimationSimpleCircleOpacitySolution/package.json b/viz/exercise/AnimationSimpleCircleOpacitySolution/package.json
new file mode 100644
index 000000000..df56d88f4
--- /dev/null
+++ b/viz/exercise/AnimationSimpleCircleOpacitySolution/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "pie-chart-basic",
+ "version": "1.0.0",
+ "description": "",
+ "keywords": [],
+ "main": "index.js",
+ "dependencies": {
+ "react": "17.0.2",
+ "d3": "7.1.1",
+ "react-dom": "17.0.2",
+ "react-scripts": "4.0.0",
+ "@react-spring/web": "^9.3.1",
+ "react-spring": "9.3.2"
+ },
+ "devDependencies": {
+ "@babel/runtime": "7.13.8",
+ "typescript": "4.1.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
diff --git a/viz/exercise/AnimationSimpleDivSolution/Circle.tsx b/viz/exercise/AnimationSimpleDivSolution/Circle.tsx
new file mode 100644
index 000000000..4befcab1c
--- /dev/null
+++ b/viz/exercise/AnimationSimpleDivSolution/Circle.tsx
@@ -0,0 +1,24 @@
+import { animated, useSpring } from 'react-spring';
+
+type CircleVizProps = {
+ position: number;
+ color: string;
+};
+
+export const Circle = ({ position, color }: CircleVizProps) => {
+ const springProps = useSpring({
+ to: { position, color },
+ });
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/AnimationSimpleDivSolution/Graph.tsx b/viz/exercise/AnimationSimpleDivSolution/Graph.tsx
new file mode 100644
index 000000000..a6ca75825
--- /dev/null
+++ b/viz/exercise/AnimationSimpleDivSolution/Graph.tsx
@@ -0,0 +1,33 @@
+import { useState } from 'react';
+import { animated, useSpring } from 'react-spring';
+
+const width = 500;
+const height = 300;
+
+export const Graph = () => {
+ const [position, setPosition] = useState(40);
+
+ const springProps = useSpring({
+ to: { left: position },
+ });
+
+ return (
+ {
+ setPosition(position > 100 ? 40 : width - 50);
+ }}
+ >
+
+
+ );
+};
diff --git a/viz/exercise/AnimationSimpleDivSolution/index.js b/viz/exercise/AnimationSimpleDivSolution/index.js
new file mode 100644
index 000000000..fa564d27f
--- /dev/null
+++ b/viz/exercise/AnimationSimpleDivSolution/index.js
@@ -0,0 +1,6 @@
+// File used to render something in codesandbox only
+import ReactDOM from 'react-dom';
+import { Graph } from './Graph';
+
+const rootElement = document.getElementById('root');
+ReactDOM.render(, rootElement);
diff --git a/viz/exercise/AnimationSimpleDivSolution/package.json b/viz/exercise/AnimationSimpleDivSolution/package.json
new file mode 100644
index 000000000..df56d88f4
--- /dev/null
+++ b/viz/exercise/AnimationSimpleDivSolution/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "pie-chart-basic",
+ "version": "1.0.0",
+ "description": "",
+ "keywords": [],
+ "main": "index.js",
+ "dependencies": {
+ "react": "17.0.2",
+ "d3": "7.1.1",
+ "react-dom": "17.0.2",
+ "react-scripts": "4.0.0",
+ "@react-spring/web": "^9.3.1",
+ "react-spring": "9.3.2"
+ },
+ "devDependencies": {
+ "@babel/runtime": "7.13.8",
+ "typescript": "4.1.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}