Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨feat: 연관키워드 버블 구현완료 #48

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/components/common/bubble-relatedkeyword/RelatedKeyword.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Bubble from "../bubble/KeywordBubble";
import { StyledRelatedKeywordContainer, StyledBubbleContainer, StyledCircleContainer, StyledCircleItem, StyledMiniCircleItem, StyledKeyCircleItem } from "./RelatedKeyword.style";

export default function RelatedKeyword(){

// !! sample data -> 실제 데이터로 추후 변경해주세요.
const keyword_sample = '불닭';
const related_big_keywords_sample = ['맛집','카페','삼양','아이스크림','오랜만','인스타그램'];
const related_sml_keywords_sample = ['불닭','불닭','불닭','불닭','불닭','불닭'];

//data
const keyword = keyword_sample;
const related_big_keywords = related_big_keywords_sample;
const related_sml_keywords = related_sml_keywords_sample;

//버블 원형 배치를 위한 코드
const big_radius = 200; // 반지름
const sml_radius = 100;
const angleStep = 360 / related_big_keywords.length;

//버블 사이즈
const bubble_size = "170px";
const mini_bubble_size = "60px"
const key_bubble_size = "80px"

return(
<StyledRelatedKeywordContainer>
<StyledBubbleContainer>
<StyledCircleContainer>
<StyledKeyCircleItem >
<Bubble content={keyword} width={key_bubble_size} height={key_bubble_size} fontsize={"1.7rem"} nothover={true}></Bubble>
</StyledKeyCircleItem>
{related_big_keywords.map((item, index) => {
const angle = index * angleStep;
const radian = (angle * Math.PI) / 180;
const x = big_radius * Math.cos(radian);
const y = big_radius * Math.sin(radian);

return (
<StyledCircleItem key={index} x={x} y={y} distance={bubble_size} time={"1.3s"} delay={`${index * 0.5}s`}>
<Bubble opacity={"0.6"} content={item} width={bubble_size} height={bubble_size} fontsize={"1.7rem"}></Bubble>
</StyledCircleItem>
);
})}
{related_sml_keywords.map((item, index) => {
const angle = index * angleStep;
const radian = (angle * Math.PI) / 180;
const x = sml_radius * Math.cos(radian);
const y = sml_radius * Math.sin(radian);

return (
<StyledMiniCircleItem key={index} x={x} y={y} distance={mini_bubble_size} time={"1s"} delay={`${index * 0.5}s`}>
<Bubble opacity={"0.6"} content={item} width={mini_bubble_size} height={mini_bubble_size} fontsize={"1.3rem"}></Bubble>
</StyledMiniCircleItem>
);
})}
</StyledCircleContainer>
</StyledBubbleContainer>
</StyledRelatedKeywordContainer>

)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import styled , {keyframes} from "styled-components";

// @keyframes 애니메이션을 별도로 정의
const animate = keyframes`
0% {
transform: translateY(0);
}
100% {
transform: translateY(-6px);
}
`;

export const StyledRelatedKeywordContainer = styled.div`
display: flex;
width: 100%;
height: 100%;
`

export const StyledBubbleContainer = styled.div`
display: flex;
width: 100%;
height: 100%;
`

export const StyledCircleContainer = styled.div`
position: relative;
margin: 50px auto;
`

export const StyledCircleItem = styled.div`
width: ${(props) => props.width};
position: absolute;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;

left: ${( props ) => `calc(50% + ${props.x}px - ${parseInt(props.distance)*0.5}px)`};
top: ${( props ) => `calc(50% + ${props.y}px - ${parseInt(props.distance)*0.5}px)`};
animation: ${animate} ${(props) => props.time || '2s'} ${(props) => props.delay || 's'} ease-in-out infinite alternate;
cursor: pointer;
`

export const StyledMiniCircleItem = styled.div`
position: absolute;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;

left: ${(props) => `calc(50% + ${props.x}px - ${parseInt(props.distance)*0.5}px)`};
top: ${(props) => `calc(50% + ${props.y}px - ${parseInt(props.distance)*0.5}px)`};
animation: ${animate} ${(props) => props.time || '2s'} ${(props) => props.delay || 's'} ease-in-out infinite alternate;
cursor: pointer;
`

export const StyledKeyCircleItem = styled.div`
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
`
1 change: 1 addition & 0 deletions src/components/common/bubble/KeywordBubble.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function Bubble(props) {
width={props.width}
height={props.height}
opacity={props.opacity}
fontsize={props.fontsize}
>
{props.content}
</StyledBubbleDiv>
Expand Down
11 changes: 9 additions & 2 deletions src/components/common/bubble/KeywordBubble.style.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ export const StyledBubbleDiv = styled.div`
justify-content: center;
align-items: center;
position: relative;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
font-size: ${(props) => parseInt(props.width || "100px") * 0.12}px;
/* box-shadow: 0 4px 8px rgba(0, 0, 0, 0.03); */
/* font-size: ${(props) => parseInt(props.width || "100px") * 0.12}px; */
font-size: ${(props) => props.fontsize || "1rem"} !important;
color: #2a5676;

&:before {
Expand Down Expand Up @@ -49,4 +50,10 @@ export const StyledBubbleDiv = styled.div`
left: calc(50% - ${(props) => parseInt(props.width || "100px") * 0.2}px);
border-radius: 50%;
}

&:hover {
cursor: ${props => props.nothover ? "none" : "pointer"};
opacity: ${props => props.nothover ? "default" : 1};
}

`;
20 changes: 19 additions & 1 deletion src/pages/keyword/Keyword.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
import React from "react";
import { useRef } from "react";
import RelatedKeyword from "../../components/common/bubble-relatedkeyword/RelatedKeyword";
import Sidebar from "../../components/common/sidebar/Sidebar";
import Header from "../../components/common/header/Header";
import { StyledSocialDiv,StyledSocialInfoDiv } from "../social/Social.style";


export default function KeywordPage() {
return <div>keywordPage</div>;
const scrollRef = useRef(null);

return ( <StyledSocialDiv>
<Sidebar />
<StyledSocialInfoDiv ref={scrollRef}>
<Header />
<RelatedKeyword></RelatedKeyword>
</StyledSocialInfoDiv>
</StyledSocialDiv>
)
;
}