Skip to content

Commit

Permalink
feat(background): implement changing background graphics factors (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
async3619 authored Oct 27, 2024
1 parent ffed3fd commit f9db5a9
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 7 deletions.
7 changes: 3 additions & 4 deletions src/components/BackgroundCanvas.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const Image = styled.img`
object-fit: cover;
`

export const Overlay = styled.div<{ isReady: boolean }>`
export const Overlay = styled.div<{ isReady: boolean; isChanging: boolean }>`
width: 100%;
height: 100%;
Expand All @@ -50,7 +50,6 @@ export const Overlay = styled.div<{ isReady: boolean }>`
left: 0;
z-index: 2;
backdrop-filter: brightness(${({ isReady }) => (isReady ? 0.5 : 1)});
transition: backdrop-filter 1s;
transition: ${({ isChanging }) =>
isChanging ? 'none' : 'backdrop-filter 1s'};
`
25 changes: 24 additions & 1 deletion src/components/BackgroundCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,27 @@ import * as Styled from './BackgroundCanvas.styled'
function BackgroundCanvas() {
const [isReady, setIsReady] = useState(false)

const isPropertyChanging = useAppStore((store) => store.isPropertyChanging)
const dimmingAmount = useAppStore((store) => store.dimmingAmount)
const blurAmount = useAppStore((store) => store.blurAmount)
const backgroundImage =
useAppStore((store) => store.backgroundImage) ?? '/img.png'

const viewportRef = useRef<HTMLCanvasElement>(null)
const raindropsRef = useRef<RaindropFX | null>(null)

const initialBlurAmount = useRef(blurAmount)

useEffect(() => {
if (!raindropsRef.current) {
return
}

raindropsRef.current.options.backgroundBlurSteps = blurAmount
raindropsRef.current.options.mistBlurStep = blurAmount + 1
raindropsRef.current.renderer.reloadBackground()
}, [blurAmount])

useEffect(() => {
const viewport = viewportRef.current
if (!viewport) {
Expand All @@ -26,6 +41,8 @@ function BackgroundCanvas() {

raindropsRef.current = new RaindropFX({
canvas: viewport,
backgroundBlurSteps: initialBlurAmount.current,
mistBlurStep: initialBlurAmount.current + 1,
})

raindropsRef.current.start()
Expand Down Expand Up @@ -64,7 +81,13 @@ function BackgroundCanvas() {
ref={viewportRef}
isReady={isReady}
/>
<Styled.Overlay isReady={isReady} />
<Styled.Overlay
isChanging={isPropertyChanging}
isReady={isReady}
style={{
backdropFilter: `brightness(${isReady ? 1 - dimmingAmount : 1})`,
}}
/>
</Styled.Root>
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Settings.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export const FileInput = styled.input`
display: none;
`

export const RangeInput = styled.input`
width: 100%;
`

export const UploadButton = styled.button`
width: 100%;
Expand Down
58 changes: 58 additions & 0 deletions src/components/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,32 @@ const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB
function Settings() {
const [open, setOpen] = useState(false)
const fileInputRef = useRef<HTMLInputElement>(null)
const changingTimeout = useRef<number | null>(null)

const dimmingAmount = useAppStore((store) => store.dimmingAmount)
const blurAmount = useAppStore((store) => store.blurAmount)

const setPropertyChanging = useAppStore((store) => store.setPropertyChanging)
const setDimmingAmount = useAppStore((store) => store.setDimmingAmount)
const setBlurAmount = useAppStore((store) => store.setBlurAmount)
const setBackgroundImage = useAppStore((store) => store.setBackgroundImage)

const doChange = (callback: () => void) => {
if (changingTimeout.current) {
clearTimeout(changingTimeout.current)
changingTimeout.current = null
}

setPropertyChanging(true)

callback()

changingTimeout.current = setTimeout(() => {
setPropertyChanging(false)
changingTimeout.current = null
}, 500)
}

const handleButtonClick = () => {
setOpen((prev) => !prev)
}
Expand All @@ -41,6 +65,20 @@ function Settings() {
setBackgroundImage(base64)
}

const handleDimmingAmountChange = (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const value = parseFloat(event.target.value)
doChange(() => setDimmingAmount(value))
}

const handleBlurAmountChange = (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const value = parseFloat(event.target.value)
doChange(() => setBlurAmount(value))
}

return (
<Styled.Root>
<Panel open={open}>
Expand All @@ -61,6 +99,26 @@ function Settings() {
Upload Image
</Styled.UploadButton>
</FormSection>
<FormSection title="Dimming">
<Styled.RangeInput
type="range"
min={0}
max={1}
value={dimmingAmount}
step={0.01}
onChange={handleDimmingAmountChange}
/>
</FormSection>
<FormSection title="Blur">
<Styled.RangeInput
type="range"
min={1}
max={5}
value={blurAmount}
step={1}
onChange={handleBlurAmountChange}
/>
</FormSection>
</Styled.Content>
</Panel>
<Styled.Button onClick={handleButtonClick}>
Expand Down
21 changes: 19 additions & 2 deletions src/stores/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,35 @@ import { createJSONStorage, persist } from 'zustand/middleware'

interface AppStore {
backgroundImage: string | null

setBackgroundImage: (backgroundImage: string) => void
clearBackgroundImage: () => void

dimmingAmount: number
setDimmingAmount: (dimmingAmount: number) => void

blurAmount: number
setBlurAmount: (blurAmount: number) => void

isPropertyChanging: boolean
setPropertyChanging: (isPropertyChanging: boolean) => void
}

const useAppStore = create(
persist<AppStore>(
(set) => ({
backgroundImage: null,

setBackgroundImage: (backgroundImage: string) => set({ backgroundImage }),
clearBackgroundImage: () => set({ backgroundImage: null }),

dimmingAmount: 0.5,
setDimmingAmount: (dimmingAmount: number) => set({ dimmingAmount }),

blurAmount: 4,
setBlurAmount: (blurAmount: number) => set({ blurAmount }),

isPropertyChanging: false,
setPropertyChanging: (isPropertyChanging: boolean) =>
set({ isPropertyChanging }),
}),
{
name: 'app-store',
Expand Down

0 comments on commit f9db5a9

Please sign in to comment.