Skip to content

Commit

Permalink
Merge pull request #48 from CheatSOL/feat/related-keyword-page
Browse files Browse the repository at this point in the history
✨feat: 연관키워드 버블 구현완료
  • Loading branch information
JaeIn1 authored Jun 18, 2024
2 parents 25ac12c + 336b30b commit 605cf45
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 3 deletions.
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>
)
;
}

0 comments on commit 605cf45

Please sign in to comment.