├── .eslintrc.json ├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── __tests__ └── test-page.test.tsx ├── jest.config.js ├── jest.setup.js ├── next-env.d.ts ├── next.config.js ├── package.json ├── pnpm-lock.yaml ├── public ├── common │ └── profile-photo.jpg ├── fonts │ ├── NotoSansKR │ │ ├── NotoSansKR-Bold.woff │ │ ├── NotoSansKR-Bold.woff2 │ │ ├── NotoSansKR-Medium.woff │ │ ├── NotoSansKR-Medium.woff2 │ │ ├── NotoSansKR-Regular.woff │ │ └── NotoSansKR-Regular.woff2 │ ├── OpenSans │ │ ├── open-sans-v27-latin-500.woff │ │ ├── open-sans-v27-latin-500.woff2 │ │ ├── open-sans-v27-latin-700.woff │ │ ├── open-sans-v27-latin-700.woff2 │ │ ├── open-sans-v27-latin-regular.woff │ │ └── open-sans-v27-latin-regular.woff2 │ └── SourceCodePro │ │ ├── source-code-pro-v18-latin-500.woff │ │ ├── source-code-pro-v18-latin-500.woff2 │ │ ├── source-code-pro-v18-latin-700.woff │ │ ├── source-code-pro-v18-latin-700.woff2 │ │ ├── source-code-pro-v18-latin-regular.woff │ │ ├── source-code-pro-v18-latin-regular.woff2 │ │ ├── source-code-pro-v20-latin-600.woff │ │ └── source-code-pro-v20-latin-600.woff2 ├── images │ ├── brand1-thumbnail.jpg │ ├── default-thumbnail.jpg │ ├── design1-01.jpg │ ├── design1-02.jpg │ ├── design1-03.jpg │ ├── design1-04.jpg │ ├── design1-05.jpg │ ├── design1-06.jpg │ ├── design1-07.jpg │ ├── design1-08.jpg │ ├── design1-09.jpg │ ├── design1-10.jpg │ ├── design1-11.jpg │ ├── design1-12.jpg │ ├── design1-13.jpg │ ├── design1-thumbnail.jpg │ ├── design2-01.jpg │ ├── design2-02.jpg │ ├── design2-03.jpg │ ├── design2-04.jpg │ ├── design2-05.jpg │ ├── design2-06.jpg │ ├── design2-07.jpg │ ├── design2-08.jpg │ ├── design2-09.jpg │ ├── design2-10.jpg │ ├── design2-11.jpg │ ├── design2-12.jpg │ ├── design2-thumbnail.jpg │ ├── design3-01.jpg │ ├── design3-02.jpg │ ├── design3-03.jpg │ ├── design3-04.jpg │ ├── design3-05.jpg │ ├── design3-06.jpg │ ├── design3-07.jpg │ ├── design3-08.jpg │ ├── design3-09.jpg │ ├── design3-10.jpg │ ├── design3-11.jpg │ ├── design3-12.jpg │ ├── design3-13.jpg │ ├── design3-14.jpg │ ├── design3-15.jpg │ ├── design3-thumbnail.jpg │ ├── design4-01.jpg │ ├── design4-02.jpg │ ├── design4-03.jpg │ ├── design4-04.jpg │ ├── design4-05.jpg │ ├── design4-06.jpg │ ├── design4-07.jpg │ ├── design4-08.jpg │ ├── design4-09.jpg │ ├── design4-10.jpg │ ├── design4-11.jpg │ ├── design4-thumbnail.jpg │ ├── design5-01.jpg │ ├── design5-02.jpg │ ├── design5-03.jpg │ ├── design5-thumbnail.jpg │ ├── design6-thumbnail.jpg │ ├── dev1-01.png │ ├── dev1-02.png │ ├── dev1-03.png │ ├── dev1-04.png │ ├── dev1-thumbnail.jpg │ ├── dev2-01.png │ ├── dev2-thumbnail.jpg │ └── ux-collection-thumbnail.jpg ├── record.ico └── ux-collection │ ├── 1.jpg │ ├── 10.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ └── 9.jpg ├── src ├── SEO │ ├── headForSEO.tsx │ └── index │ │ └── index-info.ts ├── canvas │ └── stage-lighting-wave-animation │ │ ├── light-source.ts │ │ ├── point.ts │ │ └── stage-lighting-wave-animation.tsx ├── components │ ├── block-wysiwyg │ │ ├── editable-element-switch.tsx │ │ ├── editable-element.module.scss │ │ ├── editable-element.tsx │ │ └── editable-element │ │ │ ├── code │ │ │ ├── code-textarea.tsx │ │ │ ├── editable-code-block.module.scss │ │ │ ├── editable-code-block.tsx │ │ │ └── 나중에 시도 │ │ │ │ └── highlight.tsx │ │ │ ├── image │ │ │ ├── editable-image-block.module.scss │ │ │ ├── editable-image-block.tsx │ │ │ └── upload-image.tsx │ │ │ ├── link │ │ │ ├── editable-link-block.module.scss │ │ │ ├── editable-link-block.tsx │ │ │ ├── url-input.module.scss │ │ │ └── url-input.tsx │ │ │ └── text │ │ │ ├── editable-text-block.module.scss │ │ │ └── editable-text-block.tsx │ ├── bottom-floating-button │ │ ├── BottomFloatingButton.module.scss │ │ └── BottomFloatingButton.tsx │ ├── contact │ │ ├── career.tsx │ │ ├── contact.module.scss │ │ ├── email.tsx │ │ └── profile.tsx │ ├── footer │ │ ├── footer.module.scss │ │ ├── footer.tsx │ │ ├── left-side.tsx │ │ └── right-side.tsx │ ├── header │ │ ├── gnb.tsx │ │ ├── header.module.scss │ │ ├── header.tsx │ │ ├── mobile-menu-button.tsx │ │ └── theme-toggle.tsx │ ├── menu │ │ └── select-category.tsx │ ├── modal │ │ ├── modal.module.scss │ │ └── modal.tsx │ ├── navigation │ │ ├── post │ │ │ ├── brunch-list.tsx │ │ │ ├── list.module.scss │ │ │ ├── list.tsx │ │ │ ├── post-list.module.scss │ │ │ └── post-list.tsx │ │ └── table-of-contents │ │ │ ├── table-of-contents.module.scss │ │ │ └── table-of-contents.tsx │ └── post │ │ ├── article │ │ ├── article.tsx │ │ ├── message │ │ │ ├── message.module.scss │ │ │ └── message.tsx │ │ ├── paragraph │ │ │ └── wysiwyg.tsx │ │ └── title │ │ │ ├── profile.tsx │ │ │ ├── title-wysiwyg.module.scss │ │ │ └── title-wysiwyg.tsx │ │ ├── author │ │ ├── author.module.scss │ │ └── author.tsx │ │ ├── post.module.scss │ │ ├── post.tsx │ │ ├── reference │ │ ├── link-wysiwyg.module.scss │ │ └── link-wysiwyg.tsx │ │ ├── response │ │ ├── response-list │ │ │ ├── response-list.module.scss │ │ │ └── response-list.tsx │ │ ├── response.module.scss │ │ ├── response.tsx │ │ └── write-response │ │ │ ├── write-response.module.scss │ │ │ └── write-response.tsx │ │ ├── share │ │ ├── share.module.scss │ │ └── share.tsx │ │ ├── sponsor │ │ ├── sponsor.module.scss │ │ └── sponsor.tsx │ │ └── subscription │ │ ├── subscription.module.scss │ │ └── subscription.tsx ├── constants │ └── contants.ts ├── data │ └── brunch-list.ts ├── lib │ ├── hooks │ │ ├── useAfterInitialMount.ts │ │ ├── useCanvas.ts │ │ ├── useClientWidthHeight.ts │ │ ├── useEditable.ts │ │ ├── useGetClientPostData.ts │ │ ├── useGetClientTempPostData.ts │ │ ├── useInitializeClientData.ts │ │ ├── useIsAdmin.ts │ │ ├── useModal.ts │ │ ├── usePreventRightClick.ts │ │ ├── useSetCaretPosition__afterAddInlineCode.ts │ │ ├── useUpdateVisitors.ts │ │ └── useWindowInnerWidthHeight.ts │ └── utils │ │ ├── Math.ts │ │ ├── data.ts │ │ ├── editable-block │ │ ├── add-inline-code.ts │ │ ├── add-spacing-after-inline-code.ts │ │ ├── move-caret-between-inline-code-and-spacing.ts │ │ ├── node.ts │ │ └── paste.ts │ │ ├── focus-content-editable-text-to-end.ts │ │ ├── get-caret-coordinates.ts │ │ ├── get-caret-index.ts │ │ ├── get-date.ts │ │ ├── gradientGenerator.ts │ │ └── id.ts ├── pages │ ├── [category] │ │ ├── [order].tsx │ │ └── index.tsx │ ├── _app.tsx │ ├── _document.tsx │ ├── contact.tsx │ ├── draft │ │ ├── [order].tsx │ │ ├── list.tsx │ │ └── new.tsx │ ├── examples │ │ └── canvas │ │ │ └── stage-lighting-wave │ │ │ └── index.tsx │ ├── index.tsx │ ├── login │ │ ├── index.tsx │ │ └── login.module.scss │ ├── story.tsx │ └── ux-collection.tsx ├── redux-toolkit │ ├── model │ │ ├── code-data-model.ts │ │ ├── image-data-model.ts │ │ ├── link-data-model.ts │ │ ├── post-data-model.ts │ │ └── text-data-model.ts │ ├── slices │ │ ├── post-slice.ts │ │ ├── temp-post-slice.ts │ │ └── user-slice.ts │ └── store.ts ├── service │ └── firebase │ │ ├── authentication.ts │ │ ├── config.ts │ │ ├── firestore.ts │ │ ├── realtime-db.ts │ │ └── storage.ts ├── styles │ ├── colors.css │ ├── common.scss │ ├── fonts.css │ ├── globals.css │ ├── motion.module.scss │ └── text-styles.module.scss ├── svg │ ├── icon-facebook-24.tsx │ ├── icon-linkedin-24.tsx │ ├── icon-menu-24.tsx │ ├── icon-new-tap-24.tsx │ ├── icon-plant-family-logo-24.tsx │ ├── icon-reminder-logo-24.tsx │ ├── icon-theme-24.tsx │ ├── icon-today-todo-logo-24.tsx │ ├── icon-twitter-24.tsx │ └── icon-yoonseul-logo-24.tsx ├── types │ └── type.d.ts └── views │ └── screens │ └── ux-collection │ └── list.module.scss └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [dalgudot] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | 39 | # local 40 | component.tsx 41 | reference.txt 42 | writing-subject.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 경험의 기록 2 | 3 | [기술 블로그 위한 contentEditable WYSIWYG 에디터 제작기](https://blog.dalgu.app/dev/2) 4 | 5 | ✔️ WYSIWYG 에디터 개발 6 | 7 | ✔️ Next.js `Static Generation` 활용해 성능 최적화 및 서버 비용 최소화 8 | 9 | ✔️ PostCSS + SCSS 로 디자인 시스템 구축 및 스타일, 모션 코드 분리 10 | 11 | ✔️ 파이어베이스 Firestore, Realtime Database로 DB 운영 12 | 13 | ✔️ SEO(Search Engine Optimization, 검색 엔진 최적화) 자동화 14 | -------------------------------------------------------------------------------- /__tests__/test-page.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import TestPage from '../src/pages/test-page'; 3 | 4 | describe('PostList', () => { 5 | it('renders a heading', () => { 6 | render(); 7 | 8 | const heading = screen.getByRole('heading', { 9 | name: /Test!/i, 10 | }); 11 | 12 | expect(heading).toBeInTheDocument(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const nextJest = require('next/jest'); 2 | 3 | const createJestConfig = nextJest({ 4 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment 5 | dir: './', 6 | }); 7 | 8 | // Add any custom config to be passed to Jest 9 | const customJestConfig = { 10 | setupFilesAfterEnv: ['/jest.setup.js'], 11 | // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work 12 | moduleDirectories: ['node_modules', '/'], 13 | testEnvironment: 'jest-environment-jsdom', 14 | }; 15 | 16 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async 17 | module.exports = createJestConfig(customJestConfig); 18 | -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | // Optional: configure or set up a testing framework before each test. 2 | // If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js` 3 | 4 | // Used for __tests__/testing-library.js 5 | // Learn more: https://github.com/testing-library/jest-dom 6 | import '@testing-library/jest-dom/extend-expect' 7 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: true, 4 | 5 | images: { 6 | domains: ['firebasestorage.googleapis.com'], 7 | }, 8 | 9 | eslint: { 10 | ignoreDuringBuilds: true, 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog", 3 | "version": "1.5.20 - 2024.1.3.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "test": "jest --watchAll" 11 | }, 12 | "dependencies": { 13 | "@dalgu/react-toast": "^1.2.6", 14 | "@dalgu/react-utility-hooks": "^0.1.3", 15 | "@emotion/react": "^11.11.1", 16 | "@emotion/styled": "^11.11.0", 17 | "@reduxjs/toolkit": "^1.7.1", 18 | "@types/react-redux": "^7.1.22", 19 | "classnames": "^2.3.1", 20 | "dompurify": "^2.3.4", 21 | "firebase": "^9.6.3", 22 | "next": "^12.3.1", 23 | "next-themes": "^0.0.15", 24 | "react": "^17.0.2", 25 | "react-copy-to-clipboard": "^5.0.4", 26 | "react-dom": "^17.0.2", 27 | "react-redux": "^7.2.6", 28 | "react-syntax-highlighter": "^15.4.5", 29 | "react-textarea-autosize": "^8.3.3", 30 | "recoil": "^0.6.1", 31 | "sass": "^1.49.0" 32 | }, 33 | "devDependencies": { 34 | "@testing-library/jest-dom": "^5.16.1", 35 | "@testing-library/react": "^12.1.2", 36 | "@types/dompurify": "^2.3.3", 37 | "@types/node": "17.0.8", 38 | "@types/react": "17.0.38", 39 | "@types/react-copy-to-clipboard": "^5.0.2", 40 | "@types/react-syntax-highlighter": "^13.5.2", 41 | "@types/react-textarea-autosize": "^4.3.6", 42 | "eslint": "8.6.0", 43 | "eslint-config-next": "12.0.7", 44 | "jest": "^27.4.7", 45 | "typescript": "4.5.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /public/common/profile-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/common/profile-photo.jpg -------------------------------------------------------------------------------- /public/fonts/NotoSansKR/NotoSansKR-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/NotoSansKR/NotoSansKR-Bold.woff -------------------------------------------------------------------------------- /public/fonts/NotoSansKR/NotoSansKR-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/NotoSansKR/NotoSansKR-Bold.woff2 -------------------------------------------------------------------------------- /public/fonts/NotoSansKR/NotoSansKR-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/NotoSansKR/NotoSansKR-Medium.woff -------------------------------------------------------------------------------- /public/fonts/NotoSansKR/NotoSansKR-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/NotoSansKR/NotoSansKR-Medium.woff2 -------------------------------------------------------------------------------- /public/fonts/NotoSansKR/NotoSansKR-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/NotoSansKR/NotoSansKR-Regular.woff -------------------------------------------------------------------------------- /public/fonts/NotoSansKR/NotoSansKR-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/NotoSansKR/NotoSansKR-Regular.woff2 -------------------------------------------------------------------------------- /public/fonts/OpenSans/open-sans-v27-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/OpenSans/open-sans-v27-latin-500.woff -------------------------------------------------------------------------------- /public/fonts/OpenSans/open-sans-v27-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/OpenSans/open-sans-v27-latin-500.woff2 -------------------------------------------------------------------------------- /public/fonts/OpenSans/open-sans-v27-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/OpenSans/open-sans-v27-latin-700.woff -------------------------------------------------------------------------------- /public/fonts/OpenSans/open-sans-v27-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/OpenSans/open-sans-v27-latin-700.woff2 -------------------------------------------------------------------------------- /public/fonts/OpenSans/open-sans-v27-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/OpenSans/open-sans-v27-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/OpenSans/open-sans-v27-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/OpenSans/open-sans-v27-latin-regular.woff2 -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v18-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v18-latin-500.woff -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v18-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v18-latin-500.woff2 -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v18-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v18-latin-700.woff -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v18-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v18-latin-700.woff2 -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v18-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v18-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v18-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v18-latin-regular.woff2 -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v20-latin-600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v20-latin-600.woff -------------------------------------------------------------------------------- /public/fonts/SourceCodePro/source-code-pro-v20-latin-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/fonts/SourceCodePro/source-code-pro-v20-latin-600.woff2 -------------------------------------------------------------------------------- /public/images/brand1-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/brand1-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/default-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/default-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/design1-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-01.jpg -------------------------------------------------------------------------------- /public/images/design1-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-02.jpg -------------------------------------------------------------------------------- /public/images/design1-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-03.jpg -------------------------------------------------------------------------------- /public/images/design1-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-04.jpg -------------------------------------------------------------------------------- /public/images/design1-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-05.jpg -------------------------------------------------------------------------------- /public/images/design1-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-06.jpg -------------------------------------------------------------------------------- /public/images/design1-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-07.jpg -------------------------------------------------------------------------------- /public/images/design1-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-08.jpg -------------------------------------------------------------------------------- /public/images/design1-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-09.jpg -------------------------------------------------------------------------------- /public/images/design1-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-10.jpg -------------------------------------------------------------------------------- /public/images/design1-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-11.jpg -------------------------------------------------------------------------------- /public/images/design1-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-12.jpg -------------------------------------------------------------------------------- /public/images/design1-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-13.jpg -------------------------------------------------------------------------------- /public/images/design1-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design1-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/design2-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-01.jpg -------------------------------------------------------------------------------- /public/images/design2-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-02.jpg -------------------------------------------------------------------------------- /public/images/design2-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-03.jpg -------------------------------------------------------------------------------- /public/images/design2-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-04.jpg -------------------------------------------------------------------------------- /public/images/design2-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-05.jpg -------------------------------------------------------------------------------- /public/images/design2-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-06.jpg -------------------------------------------------------------------------------- /public/images/design2-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-07.jpg -------------------------------------------------------------------------------- /public/images/design2-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-08.jpg -------------------------------------------------------------------------------- /public/images/design2-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-09.jpg -------------------------------------------------------------------------------- /public/images/design2-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-10.jpg -------------------------------------------------------------------------------- /public/images/design2-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-11.jpg -------------------------------------------------------------------------------- /public/images/design2-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-12.jpg -------------------------------------------------------------------------------- /public/images/design2-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design2-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/design3-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-01.jpg -------------------------------------------------------------------------------- /public/images/design3-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-02.jpg -------------------------------------------------------------------------------- /public/images/design3-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-03.jpg -------------------------------------------------------------------------------- /public/images/design3-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-04.jpg -------------------------------------------------------------------------------- /public/images/design3-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-05.jpg -------------------------------------------------------------------------------- /public/images/design3-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-06.jpg -------------------------------------------------------------------------------- /public/images/design3-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-07.jpg -------------------------------------------------------------------------------- /public/images/design3-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-08.jpg -------------------------------------------------------------------------------- /public/images/design3-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-09.jpg -------------------------------------------------------------------------------- /public/images/design3-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-10.jpg -------------------------------------------------------------------------------- /public/images/design3-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-11.jpg -------------------------------------------------------------------------------- /public/images/design3-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-12.jpg -------------------------------------------------------------------------------- /public/images/design3-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-13.jpg -------------------------------------------------------------------------------- /public/images/design3-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-14.jpg -------------------------------------------------------------------------------- /public/images/design3-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-15.jpg -------------------------------------------------------------------------------- /public/images/design3-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design3-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/design4-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-01.jpg -------------------------------------------------------------------------------- /public/images/design4-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-02.jpg -------------------------------------------------------------------------------- /public/images/design4-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-03.jpg -------------------------------------------------------------------------------- /public/images/design4-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-04.jpg -------------------------------------------------------------------------------- /public/images/design4-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-05.jpg -------------------------------------------------------------------------------- /public/images/design4-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-06.jpg -------------------------------------------------------------------------------- /public/images/design4-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-07.jpg -------------------------------------------------------------------------------- /public/images/design4-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-08.jpg -------------------------------------------------------------------------------- /public/images/design4-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-09.jpg -------------------------------------------------------------------------------- /public/images/design4-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-10.jpg -------------------------------------------------------------------------------- /public/images/design4-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-11.jpg -------------------------------------------------------------------------------- /public/images/design4-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design4-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/design5-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design5-01.jpg -------------------------------------------------------------------------------- /public/images/design5-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design5-02.jpg -------------------------------------------------------------------------------- /public/images/design5-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design5-03.jpg -------------------------------------------------------------------------------- /public/images/design5-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design5-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/design6-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/design6-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/dev1-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev1-01.png -------------------------------------------------------------------------------- /public/images/dev1-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev1-02.png -------------------------------------------------------------------------------- /public/images/dev1-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev1-03.png -------------------------------------------------------------------------------- /public/images/dev1-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev1-04.png -------------------------------------------------------------------------------- /public/images/dev1-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev1-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/dev2-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev2-01.png -------------------------------------------------------------------------------- /public/images/dev2-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/dev2-thumbnail.jpg -------------------------------------------------------------------------------- /public/images/ux-collection-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/images/ux-collection-thumbnail.jpg -------------------------------------------------------------------------------- /public/record.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/record.ico -------------------------------------------------------------------------------- /public/ux-collection/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/1.jpg -------------------------------------------------------------------------------- /public/ux-collection/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/10.jpg -------------------------------------------------------------------------------- /public/ux-collection/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/2.jpg -------------------------------------------------------------------------------- /public/ux-collection/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/3.jpg -------------------------------------------------------------------------------- /public/ux-collection/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/4.jpg -------------------------------------------------------------------------------- /public/ux-collection/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/5.jpg -------------------------------------------------------------------------------- /public/ux-collection/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/6.jpg -------------------------------------------------------------------------------- /public/ux-collection/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/7.jpg -------------------------------------------------------------------------------- /public/ux-collection/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/8.jpg -------------------------------------------------------------------------------- /public/ux-collection/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dalgudot/blog/4e7d00683ad5040e6271df650f91a8f248865097/public/ux-collection/9.jpg -------------------------------------------------------------------------------- /src/SEO/index/index-info.ts: -------------------------------------------------------------------------------- 1 | import { NextRouter } from 'next/router'; 2 | 3 | export const indexInfo = (router: NextRouter) => { 4 | const info = { 5 | title: 6 | router.pathname === '/ux-collection' 7 | ? 'UX 수집 | 경험의 기록' 8 | : router.pathname === '/story' 9 | ? '이야기 | 경험의 기록' 10 | : router.pathname === '/contact' 11 | ? '연락처 | 경험의 기록' 12 | : '경험의 기록', 13 | 14 | url: 15 | router.pathname === '/ux-collection' 16 | ? 'https://blog.dalgu.app/ux-collection' 17 | : router.pathname === '/story' 18 | ? 'https://blog.dalgu.app/story' 19 | : router.pathname === '/contact' 20 | ? 'https://blog.dalgu.app/contact' 21 | : 'https://blog.dalgu.app/', 22 | 23 | type: 'website', 24 | 25 | thumbnail: 26 | router.pathname === '/ux-collection' 27 | ? '/images/ux-collection-thumbnail.jpg' 28 | : '/images/default-thumbnail.jpg', 29 | 30 | description: 31 | router.pathname === '/ux-collection' 32 | ? '사용자 경험(UX)을 수집하고 공유합니다.' 33 | : '디자인과 개발 경험을 기록하고 공유합니다.', 34 | }; 35 | 36 | return info; 37 | }; 38 | -------------------------------------------------------------------------------- /src/canvas/stage-lighting-wave-animation/light-source.ts: -------------------------------------------------------------------------------- 1 | import { PI2 } from '../../lib/utils/Math'; 2 | 3 | export interface ILightSource { 4 | drawRadialGradientBehindLightSource: (ctx: CanvasRenderingContext2D) => void; 5 | drawLightSource: (ctx: CanvasRenderingContext2D) => void; 6 | drawLightLines: ( 7 | ctx: CanvasRenderingContext2D, 8 | pointCenterX: number, 9 | pointCenterY: number 10 | ) => void; 11 | } 12 | 13 | export class LightSource implements ILightSource { 14 | private centerX: number; 15 | private centerY: number; 16 | private radius: number; 17 | 18 | constructor(canvasWidth: number, canvasHeight: number) { 19 | this.centerX = canvasWidth / 2; 20 | this.centerY = canvasHeight / 1.4; 21 | this.radius = 22 | canvasWidth / 48 > 48 23 | ? 48 24 | : canvasWidth / 48 < 24 25 | ? 24 26 | : canvasWidth / 48; 27 | } 28 | 29 | drawRadialGradientBehindLightSource(ctx: CanvasRenderingContext2D) { 30 | const gradientRadius = this.radius * 16; 31 | const gradient = ctx.createRadialGradient( 32 | this.centerX, 33 | this.centerY, 34 | 0, 35 | this.centerX, 36 | this.centerY, 37 | gradientRadius 38 | ); 39 | gradient.addColorStop(0, 'rgb(102, 103, 171, 0.2)'); 40 | gradient.addColorStop(1, 'rgb(31, 31, 36, 0.1)'); 41 | ctx.fillStyle = gradient; 42 | ctx.arc(this.centerX, this.centerY, gradientRadius, 0, PI2); 43 | ctx.fill(); 44 | } 45 | 46 | drawLightSource(ctx: CanvasRenderingContext2D) { 47 | ctx.beginPath(); 48 | ctx.fillStyle = 'rgb(102, 103, 171)'; 49 | ctx.arc(this.centerX, this.centerY, this.radius, 0, PI2); 50 | ctx.fill(); 51 | } 52 | 53 | drawLightLines( 54 | ctx: CanvasRenderingContext2D, 55 | pointCenterX: number, 56 | pointCenterY: number 57 | ) { 58 | ctx.strokeStyle = 'rgb(176, 176, 212, 0.24)'; 59 | ctx.lineWidth = 1; 60 | ctx.moveTo(this.centerX, this.centerY - this.radius); 61 | ctx.lineTo(pointCenterX, pointCenterY); 62 | ctx.stroke(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/canvas/stage-lighting-wave-animation/point.ts: -------------------------------------------------------------------------------- 1 | import { PI2 } from '../../lib/utils/Math'; 2 | 3 | export interface IPoint { 4 | pointCenterX: number; 5 | pointCenterY: number; 6 | animate: (ctx: CanvasRenderingContext2D) => void; 7 | } 8 | 9 | export class Point implements IPoint { 10 | pointCenterX: number; 11 | pointCenterY: number; 12 | private radian: number; 13 | private CENTER_LINE: number; 14 | private VELOCITY: number; 15 | private AMPLITUDE: number; 16 | private POINT_RADIUS: number; 17 | 18 | constructor( 19 | POINT_GAP: number, 20 | i: number, 21 | canvasWidth: number, 22 | canvasHeight: number 23 | ) { 24 | this.pointCenterX = POINT_GAP * i; 25 | this.radian = i * 0.38; 26 | this.CENTER_LINE = canvasHeight / 3; 27 | this.VELOCITY = 0.005; 28 | this.AMPLITUDE = canvasHeight / 14; 29 | this.POINT_RADIUS = 30 | canvasWidth / 370 > 5.8 31 | ? 5.8 32 | : canvasWidth / 370 < 2.5 33 | ? 2.5 34 | : canvasWidth / 370; 35 | this.pointCenterY = 36 | this.AMPLITUDE * Math.sin(this.radian) + this.CENTER_LINE; 37 | } 38 | 39 | animate(ctx: CanvasRenderingContext2D) { 40 | this.radian += this.VELOCITY; 41 | this.pointCenterY = 42 | this.AMPLITUDE * Math.sin(this.radian) + this.CENTER_LINE; 43 | 44 | ctx.beginPath(); 45 | ctx.fillStyle = 'rgb(102, 103, 171)'; 46 | ctx.arc(this.pointCenterX, this.pointCenterY, this.POINT_RADIUS, 0, PI2); 47 | ctx.fill(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/canvas/stage-lighting-wave-animation/stage-lighting-wave-animation.tsx: -------------------------------------------------------------------------------- 1 | import { RefObject } from 'react'; 2 | import { useCanvas } from '../../lib/hooks/useCanvas'; 3 | import { ILightSource, LightSource } from './light-source'; 4 | import { IPoint, Point } from './point'; 5 | 6 | type StageLightingWaveAnimationProps = { 7 | canvasWidth: number; 8 | canvasHeight: number; 9 | }; 10 | 11 | const StageLightingWaveAnimation: React.FC = ({ 12 | canvasWidth, 13 | canvasHeight, 14 | }) => { 15 | const fillBackground = (ctx: CanvasRenderingContext2D) => { 16 | ctx.fillStyle = 'rgb(31, 31, 36)'; 17 | ctx.fillRect(0, 0, canvasWidth, canvasHeight); 18 | }; 19 | 20 | const lightSource: ILightSource = new LightSource(canvasWidth, canvasHeight); 21 | 22 | let points: IPoint[] = []; 23 | const initPoints = () => { 24 | const POINT_NUMBER = 72; 25 | const POINT_GAP = canvasWidth / POINT_NUMBER; 26 | 27 | for (let i = 0; i <= POINT_NUMBER; i++) { 28 | const point: IPoint = new Point(POINT_GAP, i, canvasWidth, canvasHeight); 29 | points.push(point); 30 | } 31 | }; 32 | if (canvasWidth !== 0 && canvasHeight !== 0) { 33 | initPoints(); 34 | } 35 | 36 | const animate = (ctx: CanvasRenderingContext2D) => { 37 | ctx.clearRect(0, 0, canvasWidth, canvasHeight); 38 | 39 | fillBackground(ctx); 40 | lightSource.drawRadialGradientBehindLightSource(ctx); 41 | lightSource.drawLightSource(ctx); 42 | 43 | for (let i = 0; i < points.length; i++) { 44 | lightSource.drawLightLines( 45 | ctx, 46 | points[i].pointCenterX, 47 | points[i].pointCenterY 48 | ); 49 | points[i].animate(ctx); 50 | } 51 | }; 52 | 53 | const canvasRef: RefObject = useCanvas( 54 | canvasWidth, 55 | canvasHeight, 56 | animate 57 | ); 58 | 59 | return ; 60 | }; 61 | 62 | export default StageLightingWaveAnimation; 63 | -------------------------------------------------------------------------------- /src/components/block-wysiwyg/editable-element.module.scss: -------------------------------------------------------------------------------- 1 | @use '../../styles/common'; 2 | 3 | .editable__element { 4 | @include common.placeholder; 5 | } 6 | 7 | .edit__block__type__editable__element__switch { 8 | position: relative; 9 | top: 55px; 10 | left: -144px; 11 | width: 87px; 12 | } 13 | 14 | .currentIndex { 15 | position: absolute; 16 | left: -32px; 17 | bottom: 2px; 18 | color: var(--g5); 19 | } 20 | -------------------------------------------------------------------------------- /src/components/block-wysiwyg/editable-element/code/code-textarea.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ChangeEvent, 3 | Dispatch, 4 | FC, 5 | KeyboardEvent, 6 | SetStateAction, 7 | useEffect, 8 | useRef, 9 | } from 'react'; 10 | import { focusContentEditableTextToEnd } from '../../../../lib/utils/focus-content-editable-text-to-end'; 11 | import { IParagraphData } from '../../../../redux-toolkit/model/post-data-model'; 12 | import styles from './editable-code-block.module.scss'; 13 | 14 | type Props = { 15 | codeString: string; 16 | setCodeString: Dispatch>; 17 | setCurrentBlockTempPostHtmlData: (inputHtml: string) => void; 18 | onKeyPress: (e: KeyboardEvent) => void; 19 | onKeyDown: (e: KeyboardEvent) => void; 20 | addBlockFocusUseEffectDependency?: IParagraphData; 21 | removeCurrentBlockFocusUseEffectDependency?: IParagraphData; 22 | placeholder: string; 23 | }; 24 | 25 | const CodeTextarea: FC = ({ 26 | codeString, 27 | setCodeString, 28 | setCurrentBlockTempPostHtmlData, 29 | onKeyPress, 30 | onKeyDown, 31 | addBlockFocusUseEffectDependency, 32 | removeCurrentBlockFocusUseEffectDependency, 33 | placeholder, 34 | }) => { 35 | const ref = useRef(null); 36 | 37 | const handleChange = (e: ChangeEvent) => { 38 | setCodeString(e.target.value); 39 | setCurrentBlockTempPostHtmlData(e.target.value); 40 | }; 41 | 42 | useEffect(() => { 43 | ref.current && focusContentEditableTextToEnd(ref.current); 44 | }, [ 45 | addBlockFocusUseEffectDependency, 46 | removeCurrentBlockFocusUseEffectDependency, 47 | ]); 48 | 49 | return ( 50 | <> 51 |