feat: add an aura animation from under finger
This commit is contained in:
parent
1832036710
commit
06dee86f57
@ -1,10 +1,12 @@
|
|||||||
import { useState } from "react"
|
import { useEffect, useRef, useState } from "react"
|
||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
import { CircularProgressbar, buildStyles } from 'react-circular-progressbar'
|
import { CircularProgressbar, buildStyles } from 'react-circular-progressbar'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import ProcessFlow from "./ProcessFlow"
|
import ProcessFlow from "./ProcessFlow"
|
||||||
import routes from "../../routes"
|
import routes from "../../routes"
|
||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
|
import { useSelector } from "react-redux"
|
||||||
|
import { selectors } from "../../store"
|
||||||
|
|
||||||
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
|
|
||||||
@ -12,6 +14,25 @@ function CreateProfilePage(): JSX.Element {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [progress, setProgress] = useState(0)
|
const [progress, setProgress] = useState(0)
|
||||||
|
const auraCoordinates = useSelector(selectors.selectAuraCoordinates)
|
||||||
|
const progressbarRef = useRef<HTMLDivElement>(null);
|
||||||
|
const pageRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [auraCoordinatesCounted, setAuraCoordinatesCounted] = useState({
|
||||||
|
x: auraCoordinates.X - 125,
|
||||||
|
y: auraCoordinates.Y - 125
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setAuraCoordinatesCounted(
|
||||||
|
{
|
||||||
|
x: (progressbarRef?.current?.offsetLeft || 0) + (pageRef?.current?.parentElement?.parentElement?.offsetLeft || 0),
|
||||||
|
y: (progressbarRef?.current?.offsetTop || 0) + 50
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}, 1000);
|
||||||
|
}, [progressbarRef])
|
||||||
|
|
||||||
const processItems = [
|
const processItems = [
|
||||||
{ task: () => sleep(3300).then(() => setProgress(23)), label: t('money_energy') },
|
{ task: () => sleep(3300).then(() => setProgress(23)), label: t('money_energy') },
|
||||||
{ task: () => sleep(2550).then(() => setProgress(48)), label: t('sexual_energy') },
|
{ task: () => sleep(2550).then(() => setProgress(48)), label: t('sexual_energy') },
|
||||||
@ -24,9 +45,9 @@ function CreateProfilePage(): JSX.Element {
|
|||||||
.then(() => navigate(routes.client.attention()))
|
.then(() => navigate(routes.client.attention()))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`${styles.page} page`}>
|
<section className={`${styles.page} page`} ref={pageRef}>
|
||||||
<div className={styles.progressbar}>
|
<div className={styles.progressbar} ref={progressbarRef}>
|
||||||
<div className={styles.aura}></div>
|
<div style={{ top: `${auraCoordinatesCounted.y}px`, left: `${auraCoordinatesCounted.x}px` }} className={styles.aura}></div>
|
||||||
<CircularProgressbar
|
<CircularProgressbar
|
||||||
value={progress}
|
value={progress}
|
||||||
text={`${progress}%`}
|
text={`${progress}%`}
|
||||||
|
|||||||
@ -19,11 +19,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.aura {
|
.aura {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
max-width: 250px;
|
||||||
|
max-height: 250px;
|
||||||
|
transition: top 3s, left 3s;
|
||||||
|
|
||||||
background-image: url("/goosebumps-aura.png");
|
background-image: url("/goosebumps-aura.png");
|
||||||
background-size: 130%;
|
background-size: 130%;
|
||||||
@ -60,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.circular-progressbar {
|
.circular-progressbar {
|
||||||
animation: appearance-progressbar 3s;
|
animation: appearance-progressbar 4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,28 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import Title from '../Title'
|
import Title from '../Title'
|
||||||
import routes from '../../routes'
|
import routes from '../../routes'
|
||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
|
import { useCallback } from 'react'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
import { actions } from '../../store'
|
||||||
|
|
||||||
function FreePeriodInfoPage(): JSX.Element {
|
function FreePeriodInfoPage(): JSX.Element {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const handleNext = () => navigate(routes.client.createProfile())
|
const dispatch = useDispatch()
|
||||||
|
const updateCoordinates = useCallback((X: number, Y: number) => {
|
||||||
|
dispatch(actions.aura.update({
|
||||||
|
coordinates: {
|
||||||
|
X,
|
||||||
|
Y
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}, [dispatch])
|
||||||
|
const handleNext = (e: any) => {
|
||||||
|
const X = e.clientX || Math.round(e.touches[0].clientX)
|
||||||
|
const Y = e.clientY || Math.round(e.touches[0].clientY)
|
||||||
|
updateCoordinates(X, Y)
|
||||||
|
navigate(routes.client.createProfile())
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`${styles.page} page`} onMouseDown={handleNext} onTouchStart={handleNext}>
|
<section className={`${styles.page} page`} onMouseDown={handleNext} onTouchStart={handleNext}>
|
||||||
|
|||||||
38
src/store/aura.ts
Normal file
38
src/store/aura.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { createSlice, createSelector } from '@reduxjs/toolkit'
|
||||||
|
import type { PayloadAction } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
interface IAura {
|
||||||
|
coordinates: {
|
||||||
|
X: number
|
||||||
|
Y: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: IAura = {
|
||||||
|
coordinates: {
|
||||||
|
X: 0,
|
||||||
|
Y: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auraSlice = createSlice({
|
||||||
|
name: 'aura',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
update(state, action: PayloadAction<Partial<IAura>>) {
|
||||||
|
if (action.payload.coordinates?.X) {
|
||||||
|
return { ...state, ...action.payload }
|
||||||
|
} else {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraReducers: (builder) => builder.addCase('reset', () => initialState),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const { actions } = auraSlice
|
||||||
|
export const selectAuraCoordinates = createSelector(
|
||||||
|
(state: { aura: IAura }) => state.aura.coordinates,
|
||||||
|
(aura) => aura
|
||||||
|
)
|
||||||
|
export default auraSlice.reducer
|
||||||
Loading…
Reference in New Issue
Block a user