728x90
반응형
목차
데스크톱에 캐릭터를 띄어보고자 해서 일렉트론으로 만들어 보았다.
main.js
// public/electron.js
const { app, BrowserWindow} = await import("electron");
const path = await import("path");
const isDev = await import("electron-is-dev");
let mainWindow;
function createWindow() {
//const { width, height } = screen.getPrimaryDisplay().workAreaSize;
mainWindow = new BrowserWindow({
width: 500, //크기 조정
height: 400,
frame: false, //frame제거
transparent: true, //투명하게 만들어 줌
alwaysOnTop: true, //우선적으로 선택하게 해줌
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
devTools: isDev,
},
});
mainWindow.loadURL(
isDev
? "http://localhost:3000"
: `file://${path.join(__dirname, "../build/index.html")}`
);
if (isDev) mainWindow.webContents.openDevTools({ mode: "detach" }); //개발모드
mainWindow.setResizable(true);
mainWindow.on("closed", () => {
mainWindow = null;
app.quit();
});
mainWindow.focus();
mainWindow.setPosition(1000, 480); //창이 띄어질 위치 구현
}
app.on("ready", createWindow);
app.on("activate", () => {
if (mainWindow === null) createWindow();
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
MainPage.tsx
import { motion, AnimatePresence } from "framer-motion";
import { useState } from "react";
import styled from "styled-components";
import MainCharacter from "./MainCharacter";
import ChattingContainer from "./ChattingContainer";
const Styledback = styled.div`
width: 100vw;
height: 100vw;
border: none;
display: flex;
flex-direction: row;
`;
function MainPage() {
return (
<Styledback>
<ChattingContainer></ChattingContainer>
<MainCharacter></MainCharacter>
</Styledback>
);
}
export default MainPage;
MainCharacter.tsx
import { motion, AnimatePresence } from "framer-motion"; //부드러운 애니메이션용 라이브러리
import styled from "styled-components";
import { emotionState } from "./recoil/EmotionAtom";
import { useState } from "react";
import { useRecoilState } from "recoil";
const Styledback = styled.div`
width: 40vw;
height: 85vh;
//position: fixed;
//bottom: 0;
//right: 0;
text-align: center;
`;
const Styledimg = styled.img`
width: 40vw;
height: 80vh;
border-radius: 10px;
`;
function MainCharacter() {
const [isVisible, setVisible] = useState<boolean>(false);
const [emotion, setemotion] = useRecoilState(emotionState); //상태 관리 recoil이용
function handleClick() {
setVisible(!isVisible);
}
return (
<div>
<Styledback>
<AnimatePresence initial={false}>
{isVisible && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
whileHover={{ scale: 1.2 }}
>
<Styledimg src={`./img/${emotion}.jpg`} alt="img" />
</motion.div>
)}
</AnimatePresence>
Ai bot
</Styledback>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default MainCharacter;
ChattingContainer.tsx
import Chatting from "./Chatting";
import styled from "styled-components";
//말풍선 css
const StyledChat = styled.div`
position: relative;
width: 40vw;
height: 30vh;
padding: 1px;
background: #ffffff;
-webkit-border-radius: 33px;
-moz-border-radius: 33px;
border-radius: 33px;
text-align: center;
&::after {
content: "";
position: absolute;
border-style: solid;
border-width: 15px 0 15px 15px;
border-color: transparent #ffffff;
display: block;
width: 0;
z-index: 1;
right: -15px;
top: 46px;
}
`;
function ChattingContainer() {
return (
<StyledChat>
<Chatting></Chatting>
</StyledChat>
);
}
export default ChattingContainer;
.env.local
BROWSER = none
웹에 창이 안띄어지게 설정을 위해 필요하다.
recoil 상태관리
import { atom, useRecoilState } from "recoil";
export const emotionState = atom({
key: "imgState", // unique ID (with respect to other atoms/selectors)
default: "happy", // default value (aka initial value)
});
export const textState = atom({
key: "textState", // unique ID (with respect to other atoms/selectors)
default: "hello", // default value (aka initial value)
});
리덕스보다 훨씬 쉽다 ㅎㅎ
반응형
'프로젝트' 카테고리의 다른 글
[재활용 프로젝트][리액트] 카카오맵 api 내 위치 기능 구현 (0) | 2024.04.11 |
---|---|
[재활용 프로젝트][리액트] 카카오 api 맵 코드 리뷰하면서 배운 점 정리 (0) | 2024.04.05 |
[재활용 프로젝트][리액트] 카카오 api map scss모듈 적용 (0) | 2024.04.04 |
[재활용 프로젝트][리액트] 카카오 api Typescript 맵 구현 (0) | 2024.04.01 |
[프로젝트] git 협업 시에 pull request및 코드 리뷰 방법 (0) | 2024.03.24 |