From 5954e6721da8e2c48f851208af1315db982a4b42 Mon Sep 17 00:00:00 2001 From: Petter Hancock Date: Tue, 27 Feb 2024 16:21:44 +0100 Subject: [PATCH 1/2] feat: icons for filters in drawer --- package.json | 1 + pnpm-lock.yaml | 52 ++++++++++- src/components/icons/filters/BlurIcon.tsx | 10 +++ src/components/icons/filters/ContrastIcon.tsx | 21 +++++ src/components/icons/filters/DropletIcon.tsx | 21 +++++ src/components/icons/filters/PixelateIcon.tsx | 10 +++ .../icons/{ => filters}/SparklesIcon.tsx | 0 src/components/icons/filters/SunDimIcon.tsx | 28 ++++++ src/components/icons/filters/SunHighIcon.tsx | 28 ++++++ .../icons/{ => social}/GithubIcon.tsx | 0 .../icons/{ => social}/LinkedInIcon.tsx | 0 .../icons/{ => tools}/FitViewIcon.tsx | 0 .../icons/{ => tools}/FlipHorizontalIcon.tsx | 0 .../icons/{ => tools}/FlipVerticalIcon.tsx | 0 .../icons/{ => tools}/FullscreenIcon.tsx | 0 .../icons/{ => tools}/RotateCcwIcon.tsx | 0 .../icons/{ => tools}/RotateCwIcon.tsx | 0 src/components/layout/BasicLayout.tsx | 4 +- .../editor/atoms/filters/FilterAtoms.ts | 24 +++++ .../editor/drawer/FilterDrawer.stories.tsx | 1 + .../library/editor/drawer/FilterDrawer.tsx | 88 +++++++++++++++++-- .../library/editor/stage/StageComponent.tsx | 8 +- .../library/editor/stage/StagedFilters.tsx | 7 ++ .../library/editor/stage/UseStageFilters.ts | 11 +-- .../library/editor/toolbar/ToolbarTools.tsx | 14 +-- src/components/views/home/HomeView.tsx | 4 +- 26 files changed, 302 insertions(+), 30 deletions(-) create mode 100644 src/components/icons/filters/BlurIcon.tsx create mode 100644 src/components/icons/filters/ContrastIcon.tsx create mode 100644 src/components/icons/filters/DropletIcon.tsx create mode 100644 src/components/icons/filters/PixelateIcon.tsx rename src/components/icons/{ => filters}/SparklesIcon.tsx (100%) create mode 100644 src/components/icons/filters/SunDimIcon.tsx create mode 100644 src/components/icons/filters/SunHighIcon.tsx rename src/components/icons/{ => social}/GithubIcon.tsx (100%) rename src/components/icons/{ => social}/LinkedInIcon.tsx (100%) rename src/components/icons/{ => tools}/FitViewIcon.tsx (100%) rename src/components/icons/{ => tools}/FlipHorizontalIcon.tsx (100%) rename src/components/icons/{ => tools}/FlipVerticalIcon.tsx (100%) rename src/components/icons/{ => tools}/FullscreenIcon.tsx (100%) rename src/components/icons/{ => tools}/RotateCcwIcon.tsx (100%) rename src/components/icons/{ => tools}/RotateCwIcon.tsx (100%) diff --git a/package.json b/package.json index dedeb67..49b86bf 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@fontsource/rubik": "5.0.18", "@heroicons/react": "2.1.1", "@pixi/filter-adjustment": "5.1.1", + "@pixi/filter-pixelate": "5.1.1", "@pixi/react": "7.1.1", "clsx": "2.1.0", "immer": "10.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fa0ece..bddda14 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,18 @@ dependencies: '@pixi/filter-adjustment': specifier: 5.1.1 version: 5.1.1(@pixi/core@7.4.0) + '@pixi/filter-pixelate': + specifier: 5.1.1 + version: 5.1.1(@pixi/core@7.4.0) + '@pixi/filter-tilt-shift': + specifier: 5.2.0 + version: 5.2.0(@pixi/core@7.4.0) + '@pixi/filter-twist': + specifier: 5.1.1 + version: 5.1.1(@pixi/core@7.4.0) '@pixi/react': specifier: 7.1.1 - version: 7.1.1(@babel/runtime@7.22.5)(@pixi/app@7.4.0)(@pixi/constants@7.4.0)(@pixi/core@7.4.0)(@pixi/display@7.4.0)(@pixi/extensions@7.4.0)(@pixi/graphics@7.4.0)(@pixi/math@7.4.0)(@pixi/mesh-extras@7.4.0)(@pixi/mesh@7.4.0)(@pixi/particle-container@7.4.0)(@pixi/sprite-animated@7.4.0)(@pixi/sprite-tiling@7.4.0)(@pixi/sprite@7.4.0)(@pixi/text-bitmap@7.4.0)(@pixi/text@7.4.0)(@pixi/ticker@7.4.0)(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + version: 7.1.1(@babel/runtime@7.23.9)(@pixi/app@7.4.0)(@pixi/constants@7.4.0)(@pixi/core@7.4.0)(@pixi/display@7.4.0)(@pixi/extensions@7.4.0)(@pixi/graphics@7.4.0)(@pixi/math@7.4.0)(@pixi/mesh-extras@7.4.0)(@pixi/mesh@7.4.0)(@pixi/particle-container@7.4.0)(@pixi/sprite-animated@7.4.0)(@pixi/sprite-tiling@7.4.0)(@pixi/sprite@7.4.0)(@pixi/text-bitmap@7.4.0)(@pixi/text@7.4.0)(@pixi/ticker@7.4.0)(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) clsx: specifier: 2.1.0 version: 2.1.0 @@ -1549,6 +1558,14 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 + dev: true + + /@babel/runtime@7.23.9: + resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false /@babel/template@7.22.15: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} @@ -2883,6 +2900,30 @@ packages: '@pixi/core': 7.4.0 dev: false + /@pixi/filter-pixelate@5.1.1(@pixi/core@7.4.0): + resolution: {integrity: sha512-qTs0Sv10aIbMFW//BPlhcFh1ByyKiVmvXfytYTTXNLrlK5DU3H3x8Pgy5Vy4lacS9VtOO69/CQ1QObBFCHnEBQ==} + peerDependencies: + '@pixi/core': ^7.0.0-X + dependencies: + '@pixi/core': 7.4.0 + dev: false + + /@pixi/filter-tilt-shift@5.2.0(@pixi/core@7.4.0): + resolution: {integrity: sha512-bCQE/BTGsqu8EhRMyiGg+9/FXsPBYxjfODbGTWWQNsXtbFVqZXvg1vEjUZQXvuso1v/Fh/BtZ3u+t2kFfWpBXA==} + peerDependencies: + '@pixi/core': ^7.0.0-X + dependencies: + '@pixi/core': 7.4.0 + dev: false + + /@pixi/filter-twist@5.1.1(@pixi/core@7.4.0): + resolution: {integrity: sha512-ZUxLmSHu7ZcP1OYmO9EsKgWDV/Ophf622N7YVei4opBrj/gBMuQZNvFIfnsm4l8yhqAwwzndSTVLNehq1A2ONw==} + peerDependencies: + '@pixi/core': ^7.0.0-X + dependencies: + '@pixi/core': 7.4.0 + dev: false + /@pixi/graphics@7.4.0(@pixi/core@7.4.0)(@pixi/display@7.4.0)(@pixi/sprite@7.4.0): resolution: {integrity: sha512-9GcXbP/iTFEA5xwXx6sSwGyIYPd6XVhFJR7ALqqnlYC+FvvvHPoh7cN3HPa1Aw9dWpNRKUKuNcoOYPmd0O0aJA==} peerDependencies: @@ -2975,7 +3016,7 @@ packages: '@pixi/text': 7.4.0(@pixi/core@7.4.0)(@pixi/sprite@7.4.0) dev: false - /@pixi/react@7.1.1(@babel/runtime@7.22.5)(@pixi/app@7.4.0)(@pixi/constants@7.4.0)(@pixi/core@7.4.0)(@pixi/display@7.4.0)(@pixi/extensions@7.4.0)(@pixi/graphics@7.4.0)(@pixi/math@7.4.0)(@pixi/mesh-extras@7.4.0)(@pixi/mesh@7.4.0)(@pixi/particle-container@7.4.0)(@pixi/sprite-animated@7.4.0)(@pixi/sprite-tiling@7.4.0)(@pixi/sprite@7.4.0)(@pixi/text-bitmap@7.4.0)(@pixi/text@7.4.0)(@pixi/ticker@7.4.0)(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): + /@pixi/react@7.1.1(@babel/runtime@7.23.9)(@pixi/app@7.4.0)(@pixi/constants@7.4.0)(@pixi/core@7.4.0)(@pixi/display@7.4.0)(@pixi/extensions@7.4.0)(@pixi/graphics@7.4.0)(@pixi/math@7.4.0)(@pixi/mesh-extras@7.4.0)(@pixi/mesh@7.4.0)(@pixi/particle-container@7.4.0)(@pixi/sprite-animated@7.4.0)(@pixi/sprite-tiling@7.4.0)(@pixi/sprite@7.4.0)(@pixi/text-bitmap@7.4.0)(@pixi/text@7.4.0)(@pixi/ticker@7.4.0)(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-W3LILsYiUxavrLoDGiIuQneFgSzsUuHkt6VVuAaqUPEGjMBzicgA5v5R2dPDmu3B+5BRwAHcJZttUKH7zFjbGw==} peerDependencies: '@babel/runtime': ^7.14.8 @@ -2999,7 +3040,7 @@ packages: react: '>=17.0.0' react-dom: '>=17.0.0' dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.9 '@pixi/app': 7.4.0(@pixi/core@7.4.0)(@pixi/display@7.4.0) '@pixi/constants': 7.4.0 '@pixi/core': 7.4.0 @@ -11238,6 +11279,11 @@ packages: /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} diff --git a/src/components/icons/filters/BlurIcon.tsx b/src/components/icons/filters/BlurIcon.tsx new file mode 100644 index 0000000..df1cffd --- /dev/null +++ b/src/components/icons/filters/BlurIcon.tsx @@ -0,0 +1,10 @@ +import type { ReactElement } from "react"; + +export function BlurIcon(): ReactElement { + return ( + + + + + ); +} diff --git a/src/components/icons/filters/ContrastIcon.tsx b/src/components/icons/filters/ContrastIcon.tsx new file mode 100644 index 0000000..8a1a5b5 --- /dev/null +++ b/src/components/icons/filters/ContrastIcon.tsx @@ -0,0 +1,21 @@ +import type { ReactElement } from "react"; + +export function ContrastIcon(): ReactElement { + return ( + + + + + + + + + ); +} diff --git a/src/components/icons/filters/DropletIcon.tsx b/src/components/icons/filters/DropletIcon.tsx new file mode 100644 index 0000000..49c9bfb --- /dev/null +++ b/src/components/icons/filters/DropletIcon.tsx @@ -0,0 +1,21 @@ +import type { ReactElement } from "react"; + +export function DropletIcon(): ReactElement { + return ( + + + + + + + + + ); +} diff --git a/src/components/icons/filters/PixelateIcon.tsx b/src/components/icons/filters/PixelateIcon.tsx new file mode 100644 index 0000000..94e6d13 --- /dev/null +++ b/src/components/icons/filters/PixelateIcon.tsx @@ -0,0 +1,10 @@ +import type { ReactElement } from "react"; + +export function PixelateIcon(): ReactElement { + return ( + + + + + ); +} diff --git a/src/components/icons/SparklesIcon.tsx b/src/components/icons/filters/SparklesIcon.tsx similarity index 100% rename from src/components/icons/SparklesIcon.tsx rename to src/components/icons/filters/SparklesIcon.tsx diff --git a/src/components/icons/filters/SunDimIcon.tsx b/src/components/icons/filters/SunDimIcon.tsx new file mode 100644 index 0000000..994741e --- /dev/null +++ b/src/components/icons/filters/SunDimIcon.tsx @@ -0,0 +1,28 @@ +import type { ReactElement } from "react"; + +export function SunDimIcon(): ReactElement { + return ( + + + + + + + + + + + + ); +} diff --git a/src/components/icons/filters/SunHighIcon.tsx b/src/components/icons/filters/SunHighIcon.tsx new file mode 100644 index 0000000..b024a88 --- /dev/null +++ b/src/components/icons/filters/SunHighIcon.tsx @@ -0,0 +1,28 @@ +import type { ReactElement } from "react"; + +export function SunHighIcon(): ReactElement { + return ( + + + + + + + + + + + + ); +} diff --git a/src/components/icons/GithubIcon.tsx b/src/components/icons/social/GithubIcon.tsx similarity index 100% rename from src/components/icons/GithubIcon.tsx rename to src/components/icons/social/GithubIcon.tsx diff --git a/src/components/icons/LinkedInIcon.tsx b/src/components/icons/social/LinkedInIcon.tsx similarity index 100% rename from src/components/icons/LinkedInIcon.tsx rename to src/components/icons/social/LinkedInIcon.tsx diff --git a/src/components/icons/FitViewIcon.tsx b/src/components/icons/tools/FitViewIcon.tsx similarity index 100% rename from src/components/icons/FitViewIcon.tsx rename to src/components/icons/tools/FitViewIcon.tsx diff --git a/src/components/icons/FlipHorizontalIcon.tsx b/src/components/icons/tools/FlipHorizontalIcon.tsx similarity index 100% rename from src/components/icons/FlipHorizontalIcon.tsx rename to src/components/icons/tools/FlipHorizontalIcon.tsx diff --git a/src/components/icons/FlipVerticalIcon.tsx b/src/components/icons/tools/FlipVerticalIcon.tsx similarity index 100% rename from src/components/icons/FlipVerticalIcon.tsx rename to src/components/icons/tools/FlipVerticalIcon.tsx diff --git a/src/components/icons/FullscreenIcon.tsx b/src/components/icons/tools/FullscreenIcon.tsx similarity index 100% rename from src/components/icons/FullscreenIcon.tsx rename to src/components/icons/tools/FullscreenIcon.tsx diff --git a/src/components/icons/RotateCcwIcon.tsx b/src/components/icons/tools/RotateCcwIcon.tsx similarity index 100% rename from src/components/icons/RotateCcwIcon.tsx rename to src/components/icons/tools/RotateCcwIcon.tsx diff --git a/src/components/icons/RotateCwIcon.tsx b/src/components/icons/tools/RotateCwIcon.tsx similarity index 100% rename from src/components/icons/RotateCwIcon.tsx rename to src/components/icons/tools/RotateCwIcon.tsx diff --git a/src/components/layout/BasicLayout.tsx b/src/components/layout/BasicLayout.tsx index 6d8163e..91ffeeb 100644 --- a/src/components/layout/BasicLayout.tsx +++ b/src/components/layout/BasicLayout.tsx @@ -1,7 +1,7 @@ import type { ReactElement, ReactNode } from "react"; import clsx from "clsx"; -import { GithubIcon } from "~/components/icons/GithubIcon"; -import { LinkedInIcon } from "~/components/icons/LinkedInIcon"; +import { GithubIcon } from "~/components/icons/social/GithubIcon"; +import { LinkedInIcon } from "~/components/icons/social/LinkedInIcon"; export interface SocialLinkProps { onGithubClick?: () => void; diff --git a/src/components/library/editor/atoms/filters/FilterAtoms.ts b/src/components/library/editor/atoms/filters/FilterAtoms.ts index 21370a6..730e676 100644 --- a/src/components/library/editor/atoms/filters/FilterAtoms.ts +++ b/src/components/library/editor/atoms/filters/FilterAtoms.ts @@ -5,6 +5,10 @@ export const blurFilterAtom = atom(0); export const brightnessFilterAtom = atom(1); export const contrastFilterAtom = atom(1); export const saturationFilterAtom = atom(1); +export const pixelateFilterAtom = atom(0); +export const redFilterAtom = atom(1); +export const greenFilterAtom = atom(1); +export const blueFilterAtom = atom(1); // Derived export const controlFilterAtom = atom( @@ -13,12 +17,20 @@ export const controlFilterAtom = atom( const brightness = get(brightnessFilterAtom); const contrast = get(contrastFilterAtom); const saturation = get(saturationFilterAtom); + const pixelate = get(pixelateFilterAtom); + const red = get(redFilterAtom); + const green = get(greenFilterAtom); + const blue = get(blueFilterAtom); return { blur, brightness, contrast, saturation, + pixelate, + red, + green, + blue, }; }, (_get, set, update: Partial) => { @@ -34,5 +46,17 @@ export const controlFilterAtom = atom( if (update.saturation !== undefined) { set(saturationFilterAtom, update.saturation); } + if (update.pixelate !== undefined) { + set(pixelateFilterAtom, update.pixelate); + } + if (update.red !== undefined) { + set(redFilterAtom, update.red); + } + if (update.green !== undefined) { + set(greenFilterAtom, update.green); + } + if (update.blue !== undefined) { + set(blueFilterAtom, update.blue); + } } ); diff --git a/src/components/library/editor/drawer/FilterDrawer.stories.tsx b/src/components/library/editor/drawer/FilterDrawer.stories.tsx index 7e3626e..4d8594b 100644 --- a/src/components/library/editor/drawer/FilterDrawer.stories.tsx +++ b/src/components/library/editor/drawer/FilterDrawer.stories.tsx @@ -17,6 +17,7 @@ const commonProps = { brightness: 1, contrast: 1, saturation: 1, + pixelate: 0, onFilterChange: () => console.log("onFilterChange"), onClose: () => console.log("onClose"), } satisfies ComponentProps; diff --git a/src/components/library/editor/drawer/FilterDrawer.tsx b/src/components/library/editor/drawer/FilterDrawer.tsx index 5efe3d7..aa14938 100644 --- a/src/components/library/editor/drawer/FilterDrawer.tsx +++ b/src/components/library/editor/drawer/FilterDrawer.tsx @@ -2,6 +2,11 @@ import { useRef, type ReactElement } from "react"; import { XMarkIcon } from "@heroicons/react/24/solid"; import { useOnClickOutside } from "usehooks-ts"; import type { StagedFilter } from "../stage/StagedFilters"; +import { BlurIcon } from "~/components/icons/filters/BlurIcon"; +import { ContrastIcon } from "~/components/icons/filters/ContrastIcon"; +import { DropletIcon } from "~/components/icons/filters/DropletIcon"; +import { PixelateIcon } from "~/components/icons/filters/PixelateIcon"; +import { SunHighIcon } from "~/components/icons/filters/SunHighIcon"; export interface FilterDrawerProps { open: boolean; @@ -9,6 +14,10 @@ export interface FilterDrawerProps { brightness: number; contrast: number; saturation: number; + pixelate: number; + red: number; + green: number; + blue: number; onFilterChange: (filter: Partial) => void; onClose: () => void; } @@ -20,6 +29,10 @@ export function FilterDrawer({ brightness, contrast, saturation, + pixelate, + red, + green, + blue, onFilterChange, }: FilterDrawerProps): ReactElement { const menuRef = useRef(null); @@ -30,7 +43,7 @@ export function FilterDrawer({