rndr realm
Creative Studio
Mastering Motion Design in React
Motion design has become an essential part of creating engaging user experiences. In this article, we'll explore the principles and techniques for implementing smooth, performant animations in React applications.
Introduction
MDX allows you to use JSX in your markdown content, making it incredibly powerful for creating interactive blog posts. You can write regular markdown and seamlessly integrate React components.
Code Blocks
Here's a JavaScript code example:
Get World Position
1// Example: React Server Component2export default async function BlogPost({ params }) {3const post = await getPost(params.slug);45return (6<article>7<h1>{post.title}</h1>8<div>{post.content}</div>9</article>10);11}
Code Preview
import React, { useState } from 'react'; import './styles.css'; export default function App() { const [count, setCount] = useState(0); return ( <div className="App"> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> <div className="counter"> <button onClick={() => setCount(count - 1)}>-</button> <span>Count: {count}</span> <button onClick={() => setCount(count + 1)}>+</button> </div> </div> ); }
#1
q
import React, { useState } from 'react'; import TodoList from './TodoList'; import './styles.css'; export default function App() { const [todos, setTodos] = useState([ { id: 1, text: 'Learn React', completed: false }, { id: 2, text: 'Build awesome projects', completed: false }, ]); const [input, setInput] = useState(''); const addTodo = (e) => { e.preventDefault(); if (input.trim()) { setTodos([ ...todos, { id: Date.now(), text: input, completed: false } ]); setInput(''); } }; const toggleTodo = (id) => { setTodos(todos.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo )); }; const deleteTodo = (id) => { setTodos(todos.filter(todo => todo.id !== id)); }; return ( <div className="app"> <h1>📝 Todo App</h1> <form onSubmit={addTodo} className="add-todo"> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} placeholder="Add a new todo..." /> <button type="submit">Add</button> </form> <TodoList todos={todos} onToggle={toggleTodo} onDelete={deleteTodo} /> </div> ); }
#2
import React, { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import './styles.css'; const items = [ { id: 1, title: 'First Item', color: '#FF6B6B' }, { id: 2, title: 'Second Item', color: '#4ECDC4' }, { id: 3, title: 'Third Item', color: '#45B7D1' }, { id: 4, title: 'Fourth Item', color: '#FFA07A' }, ]; export default function App() { const [selectedId, setSelectedId] = useState(null); return ( <div className="app"> <h1>✨ Framer Motion Demo</h1> <p className="subtitle">Click on any card to expand it!</p> <div className="grid"> {items.map((item) => ( <motion.div key={item.id} layoutId={item.id} onClick={() => setSelectedId(item.id)} className="card" style={{ backgroundColor: item.color }} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > <motion.h2>{item.title}</motion.h2> </motion.div> ))} </div> <AnimatePresence> {selectedId && ( <> <motion.div className="backdrop" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={() => setSelectedId(null)} /> <motion.div layoutId={selectedId} className="expanded-card" style={{ backgroundColor: items.find(i => i.id === selectedId)?.color }} > <motion.h2> {items.find(i => i.id === selectedId)?.title} </motion.h2> <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.2 }} > This is an expanded view with more details. Framer Motion provides smooth layout animations! </motion.p> <motion.button onClick={() => setSelectedId(null)} whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }} > Close </motion.button> </motion.div> </> )} </AnimatePresence> </div> ); }