Reputation: 75
I'm a beginner in programming, and I'm trying to build a page layout using the FLIP technique in React, but I'm stuck, so I'd like to ask for your help. For more information about the FLIP technique, please refer to the reference URL.
Quickly, what I would like to build is a page layout that consists of one main content and multiple sub-contents, as shown in the image below, and that can be repositioned with the main content by clicking on the sub-content.
I found a layout similar to the one I want to create by surfing the net, and I've included it below as a reference URL.
・What I tried.
I thought I could achieve this using hooks, CSS, and the react-flip-toolkit -library-. In fact, the code to swap the position of the two elements was easy to implement.
https://codesandbox.io/s/flip-l4o04?file=/src/index.js
However, I don't know how to write the code to control the behavior when the number of contents is increased. The react-flip-toolkit uses the flipkey as a key, so if I just add more containers, onclick will fire all the containers in the flipper tag and it won't work.
https://codesandbox.io/s/flip-test-f3pqb?file=/src/index.js
Next, I rewrote some of the code.
const AnimatedSquare = () => {
const [active, setActive] = useState(false);
const toggleActive = () => setActive(prevState => !prevState);
const [active1, setActive1] = useState(false);
const toggleActive1 = () => setActive1(prevState => !prevState);
return (
<div>
<Flipper flipKey={active,active1}>
<div className="box">
<Flipped flipId="square">
<div
className={active ? "square" : "square-active"}
onClick={toggleActive}/>
</Flipped>
<Flipped flipId="square1">
<div
className={active1 ? "square-active-1" : "square1"}
onClick={toggleActive1}/>
</Flipped>
Only the part of the code that was rewritten now behaves independently, but this is not good enough because it cannot be repositioned with the main content.
・Question
What code should I write to make each container behave independently and swap its position with the main content as shown in the reference URL? I would appreciate your help.
~Reference URL~
・What I want to build like this
Upvotes: 3
Views: 206
Reputation: 1302
I think this is what you want
I just divide active state on squares and accumulate active square classes
If someday the link stops opening, I attach the code below
import React, { useCallback, useState } from "react";
import ReactDOM from "react-dom";
import { Flipper, Flipped } from "react-flip-toolkit";
import "./styles.css";
const AnimatedSquare = () => {
const [active, setActive] = useState({
square1: true,
square2: false,
square3: false,
square4: false,
square5: false
});
const handleActive = useCallback(
(id) => () =>
setActive({
square1: false,
square2: false,
square3: false,
square4: false,
square5: false,
[id]: true
}),
[]
);
return (
<div>
<Flipper flipKey={true}>
<div className="box">
<Flipped flipId="square1">
<div
className={`square1${active.square1 ? " active" : ""}`}
onClick={handleActive("square1")}
></div>
</Flipped>
<Flipped flipId="square2">
<div
className={`square2${active.square2 ? " active" : ""}`}
onClick={handleActive("square2")}
/>
</Flipped>
</div>
<Flipped flipId="square3">
<div
className={`square3${active.square3 ? " active" : ""}`}
onClick={handleActive("square3")}
/>
</Flipped>
<Flipped flipId="square4">
<div
className={`square4${active.square4 ? " active" : ""}`}
onClick={handleActive("square4")}
/>
</Flipped>
<Flipped flipId="square5">
<div
className={`square5${active.square5 ? " active" : ""}`}
onClick={handleActive("square5")}
/>
</Flipped>
</Flipper>
</div>
);
};
ReactDOM.render(<AnimatedSquare />, document.querySelector("#root"));
* {
box-sizing: border-box;
}
body {
justify-content: left;
align-items: left;
min-height: 100vh;
}
.box {
position: relative;
}
.square1 {
transition: all 1s;
margin-top: 10px;
margin-left: 5px;
margin-right: 5px;
width: 17rem;
height: 12rem;
cursor: pointer;
background-image: linear-gradient(45deg, rgb(0, 255, 0), rgb(71, 182, 108));
}
.square2 {
transition: all 1s;
margin-top: 10px;
margin-left: 5px;
margin-right: 5px;
width: 17rem;
height: 12rem;
cursor: pointer;
background-image: linear-gradient(45deg, rgb(255, 0, 255), rgb(182, 71, 158));
}
.square3 {
transition: all 1s;
margin-top: 10px;
margin-left: 5px;
margin-right: 5px;
width: 17rem;
height: 12rem;
cursor: pointer;
background-image: linear-gradient(
45deg,
rgb(113, 206, 234),
rgb(60, 107, 170)
);
}
.square4 {
transition: all 1s;
margin-top: 10px;
margin-left: 5px;
margin-right: 5px;
width: 17rem;
height: 12rem;
cursor: pointer;
background-image: linear-gradient(45deg, rgb(253, 72, 0), rgb(170, 110, 60));
}
.square5 {
transition: all 1s;
margin-top: 10px;
margin-left: 5px;
margin-right: 5px;
width: 17rem;
height: 12rem;
cursor: pointer;
background-image: linear-gradient(45deg, rgb(255, 0, 0), rgb(182, 71, 71));
}
.active {
position: fixed;
top: 0;
transform: translateX(300px);
width: 75rem;
height: 50rem;
cursor: pointer;
}
Upvotes: 1