Skip to content

Commit

Permalink
i
Browse files Browse the repository at this point in the history
  • Loading branch information
holtzy committed Nov 8, 2024
1 parent 8069b14 commit 2cb13cc
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 33 deletions.
60 changes: 29 additions & 31 deletions pages/course/animation/react-spring-for-dataviz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import {
} from '@/component/ExerciseDoubleSandbox';
import { ExerciseAccordion } from '@/component/ExerciseAccordion';
import { Graph11 } from '@/viz/exercise/AnimationSimpleDivSolution/Graph';
import { Graph12 } from '@/viz/exercise/AnimationSimpleDivRotateSolution/Graph';
import { Graph2 } from '@/viz/exercise/AnimationSimpleDivHeavySolution/Graph';
import { Graph99 } from '@/viz/exercise/AnimationMultiCircleDelaySolution/Graph';

const previousURL = '/course/animation/introduction';
const currentURL = '/course/animation/react-spring-for-dataviz';
Expand Down Expand Up @@ -545,82 +548,77 @@ const exercises: Exercise[] = [
{
whyItMatters: (
<>
<p>
Unlike SVG, canvas doesn’t directly support complex shapes with
strings. Instead, we need to create loops for drawing such shapes.
</p>
<p>Just a bit of fun!</p>
</>
),
toDo: (
<>
<ul>
<li>
Draw a segmented line starting from <code>(50, 150)</code>.
</li>
<li>
Use <code>beginPath()</code> and <code>moveTo()</code>, then draw
lines to <code>(100, 120)</code>, <code>(150, 180)</code>,
<code>(200, 100)</code>, <code>(250, 160)</code>,{' '}
<code>(300, 90)</code>, and <code>(350, 140)</code>.
Use the <code>rotate</code> property of a div to make the rectangle
spin when it goes from one side to another!
</li>
</ul>
</>
),
practiceSandbox: 'exercise/AnimationDefaultPractice',
solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
solutionSandbox: 'exercise/AnimationSimpleDivRotateSolution',
fileToOpen: 'Graph.tsx',
},
{
whyItMatters: (
<>
<p>
Creating a scatterplot involves looping through a dataset and creating
a circle for each item.
</p>
<p>Spring physics matters!</p>
</>
),
toDo: (
<>
<ul>
<li>A dataset is provided in the sandbox.</li>
<li>
Draw a circle for each data point, using its <code>x</code> and{' '}
<code>y</code> values as coordinates.
Apply a mass of <code>120</code> to the moving <code>div</code>
</li>
<li>What happens? Why?</li>
<li>
Try to play with <code>friction</code> and <code>tension</code> too
to get an intuition on how physics work.
</li>
<li>Use a loop to complete the task.</li>
</ul>
</>
),
practiceSandbox: 'exercise/AnimationDefaultPractice',
solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
solutionSandbox: 'exercise/AnimationSimpleDivHeavySolution',
fileToOpen: 'Graph.tsx',
},
{
whyItMatters: (
<>
<p>
Handling text in canvas can be tricky. Whenever possible, we should
use HTML or SVG.
<code>delay</code> can give some cool effects to dataviz projects. But
use it with care, you do not want to waste people time!
</p>
</>
),
toDo: (
<>
<ul>
<li>Draw a large circle.</li>
<li>Instead of 1 circle (exercise 1), render 3 animated circles.</li>
<li>
Use y positions of 50, 100, 150 respectively (you need to create a y
prop in the Circle componetn)
</li>
<li>
Use the{' '}
<a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillText">
fillText
</a>{' '}
function to write "Hello, World!" at the center of the circle.
Add a new property called delay to the Circle component. Give values
of 10, 100 and 1000 to the 3 circles respectively.
</li>
<li>
Use this delay value to delay the start of the animation: you can
just pass it to the useSpring hook!
</li>
<li>Align the text vertically and horizontally.</li>
</ul>
</>
),
practiceSandbox: 'exercise/AnimationDefaultPractice',
solutionSandbox: 'exercise/AnimationSimpleCircleOpacitySolution',
solutionSandbox: 'exercise/AnimationMultiCircleDelaySolution',
fileToOpen: 'Graph.tsx',
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import { animated, useSpring } from 'react-spring';
type CircleVizProps = {
position: number;
color: string;
y: number;
delay: number;
};

export const Circle = ({ position, color }: CircleVizProps) => {
export const Circle = ({ position, color, y, delay }: CircleVizProps) => {
const springProps = useSpring({
to: { position, color },
delay: delay,
});

return (
<animated.circle
strokeWidth={2}
fillOpacity={0.4}
r={38}
cy={50}
cy={y}
cx={springProps.position}
stroke={springProps.color}
fill={springProps.color}
Expand Down
38 changes: 38 additions & 0 deletions viz/exercise/AnimationMultiCircleDelaySolution/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useState } from 'react';
import { Circle } from './Circle';

const width = 500;
const height = 300;

export const Graph = () => {
const [position, setPosition] = useState(40);

return (
<svg
width={width}
height={height}
onClick={() => {
position > 100 ? setPosition(40) : setPosition(width - 50);
}}
>
<Circle
position={position}
y={50}
delay={10}
color={position > 200 ? 'red' : 'blue'}
/>
<Circle
position={position}
y={150}
delay={100}
color={position > 200 ? 'red' : 'blue'}
/>
<Circle
position={position}
y={250}
delay={1000}
color={position > 200 ? 'red' : 'blue'}
/>
</svg>
);
};
6 changes: 6 additions & 0 deletions viz/exercise/AnimationMultiCircleDelaySolution/index.js
Original file line number Diff line number Diff line change
@@ -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(<Graph />, rootElement);
31 changes: 31 additions & 0 deletions viz/exercise/AnimationMultiCircleDelaySolution/package.json
Original file line number Diff line number Diff line change
@@ -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"
]
}
36 changes: 36 additions & 0 deletions viz/exercise/AnimationSimpleDivHeavySolution/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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 },
config: {
mass: 120,
},
});

return (
<div
style={{ width, height, position: 'relative' }}
onClick={() => {
setPosition(position > 100 ? 40 : width - 50);
}}
>
<animated.div
style={{
left: springProps.left,
top: 50,
position: 'absolute',
width: 50,
height: 50,
backgroundColor: 'red',
}}
></animated.div>
</div>
);
};
6 changes: 6 additions & 0 deletions viz/exercise/AnimationSimpleDivHeavySolution/index.js
Original file line number Diff line number Diff line change
@@ -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(<Graph />, rootElement);
31 changes: 31 additions & 0 deletions viz/exercise/AnimationSimpleDivHeavySolution/package.json
Original file line number Diff line number Diff line change
@@ -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"
]
}
34 changes: 34 additions & 0 deletions viz/exercise/AnimationSimpleDivRotateSolution/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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, rotate: position > 100 ? 0 : 360 },
});

return (
<div
style={{ width, height, position: 'relative' }}
onClick={() => {
setPosition(position > 100 ? 40 : width - 50);
}}
>
<animated.div
style={{
left: springProps.left,
rotate: springProps.rotate,
top: 50,
position: 'absolute',
width: 50,
height: 50,
backgroundColor: 'red',
}}
></animated.div>
</div>
);
};
6 changes: 6 additions & 0 deletions viz/exercise/AnimationSimpleDivRotateSolution/index.js
Original file line number Diff line number Diff line change
@@ -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(<Graph />, rootElement);
31 changes: 31 additions & 0 deletions viz/exercise/AnimationSimpleDivRotateSolution/package.json
Original file line number Diff line number Diff line change
@@ -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"
]
}

0 comments on commit 2cb13cc

Please sign in to comment.