Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
sofijamitukevic committed Feb 18, 2025
2 parents 5ad5ba9 + 682e99e commit c4da960
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 156 deletions.
264 changes: 142 additions & 122 deletions src/apps/boards/components/FlipClock.scss
Original file line number Diff line number Diff line change
@@ -1,144 +1,164 @@
.flip-clock-container {
display: flex;
flex-direction: column;
justify-content: center;
height: 85%;
}

.flip-clock {
display: flex;
align-items: center;
justify-content: center;
perspective: 400px;
border-radius: 10px;

background-color: var(--color-surface-accent);
color: var(--color-surface-accent-on);

font-family: Termina;
font-size: 54px;
font-size: 50px;
font-style: normal;
font-weight: 700;
line-height: normal;
letter-spacing: -0.54px;

width: 90%;
height: 20rem;


width: 657px;
height: 257px;

*,
*:before,
*:after {
box-sizing: border-box;
}
}

time {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
text-align: center;
}

.flip-clock__colon {
display: inline-flex;
align-items: center;

& time,
& span {
display: inline-block;
}

&__digit {
display: inline-block;
padding: 2rem 1rem;
background-color: var(--color-surface-accent-bright);

margin: 0 0.2rem;
min-width: 6rem;
display: flex;
justify-content: center;
text-align: center;
position: relative;
// color: orange;
// overflow: hidden;

perspective: 40rem;

// height: 10rem;


&::before, &::after {
content: attr(data-value);
color: var(--color-surface-accent-on);
font-size: inherit;
// height: 50%;

// height: 5rem;
// line-height: 5rem;

position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;

display: flex;
justify-content: center;
align-items: center;
overflow: hidden;

transform: translateZ(0rem);
backface-visibility: hidden;
transform-style: preserve-3d;
animation-fill-mode: both;
}
&::before {
// color: green;
// clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
top: 0;
bottom: auto;
background-color: rgba(0, 0, 0, 0.3);

// margin-bottom: -15rem;


transform-origin: center;
// animation: flip-top 0.3s cubic-bezier(.37,.01,.94,.35);

}
&::after {
// color: blue;
clip-path: polygon(0 50%, 100% 50%, 100% 100%, 0 100%);
top: auto;
bottom: 0;

transform-origin: center top;
}


}

&.flip {
justify-content: center;
box-sizing: border-box;
height: 100%;
vertical-align: middle;
padding-bottom: 15px;
}

.flip-clock__digit::before {
animation: flip-top 1s cubic-bezier(.15,.45,.28,1);
}
.flip-clock__digit::after {
animation: flip-bottom 0.3s cubic-bezier(.15,.45,.28,1);
}
.flip-clock__piece {
padding-top: 30px;
display: inline-block;
margin: 0 5px;
}

}

$halfHeight: 0.72em;
$borderRadius: 0.15em;

.card {
display: block;
position: relative;
padding-bottom: $halfHeight;
font-size: 3vw;
line-height: 0.95;
}

@keyframes flip-top {
.card__top,
.card__bottom,
.card__back::before,
.card__back::after {
display: block;
height: $halfHeight;
color: #ccc;
background: #295258;
padding: 0.25em 0.25em;
border-radius: $borderRadius $borderRadius 0 0;
backface-visibility: hidden;
transform-style: preserve-3d;
width: 1.5em;
transform: translateZ(0);
}

.card__bottom {
color: #fff;
position: absolute;
top: 50%;
left: 0;
border-top: solid 1px #fff;
background: #295258;
border-radius: 0 0 $borderRadius $borderRadius;
pointer-events: none;
overflow: hidden;
}

.card__bottom::after {
display: block;
margin-top: -$halfHeight;
}

.card__back::before,
.card__bottom::after {
content: attr(data-value);
}

.card__back {
position: absolute;
top: 0;
height: 100%;
left: 0%;
pointer-events: none;
}

.card__back::before {
position: relative;
z-index: -1;
overflow: hidden;
}

.flip .card__back::before {
animation: flipTop 0.3s cubic-bezier(0.37, 0.01, 0.94, 0.35);
animation-fill-mode: both;
transform-origin: center bottom;
}

.flip .card__back .card__bottom {
transform-origin: center top;
animation-fill-mode: both;
animation: flipBottom 0.6s cubic-bezier(0.15, 0.45, 0.28, 1); // 0.3s;
}

@keyframes flipTop {
0% {
transform: rotateX(0deg);
z-index: 2;
}
0%,
99% {
opacity: 0.99;
}
100% {
transform: rotateX(-90deg);
opacity: 0;
}
// 0% {
// transform: rotateX(0deg);
// z-index: 2;
// }
// 0%, 99% {
// opacity: 0.99;
// }
// 100% {
// transform: rotateX(-90deg);
// opacity: 0;
// }
}


@keyframes flip-bottom {
// 0%, 50% {
// z-index: -1;
// transform: rotateX(90deg);
// opacity: 0;
// }
// 51% {
// opacity: 0.99;
// }
// 100% {
// opacity: 0.99;
// transform: rotateX(0deg);
// z-index: 5;
// }
}


@keyframes flipBottom {
0%,
50% {
z-index: -1;
transform: rotateX(90deg);
opacity: 0;
}
51% {
opacity: 0.99;
}
100% {
opacity: 0.99;
transform: rotateX(0deg);
z-index: 5;
}
}
78 changes: 44 additions & 34 deletions src/apps/boards/components/FlipClock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,64 @@
*/
import { useEffect, useState } from 'react'
import { useTime } from 'src/hooks'
import { sleep } from 'src/utils'
import './FlipClock.scss'

// ANIMATION IS WORK-IN-PROGRESS
export const FlipClock = () => {
const { date, hours: currentHours, minutes: currentMinutes } = useTime()
const [hours, setHours] = useState(currentHours)
const [minutes, setMinutes] = useState(currentMinutes)
const [flip, setFlip] = useState(false)
const [hour1, setHour1] = useState(currentHours[0])
const [minute1, setMinute1] = useState(currentMinutes[0])
const [hour2, setHour2] = useState(currentHours[1])
const [minute2, setMinute2] = useState(currentMinutes[1])

useEffect(() => {
// setFlip(true)
setMinutes(currentMinutes)
setHours(currentHours)
console.log(hour1, hour2, minute1, minute2)

// sleep(1000).then(() => setFlip(false))
if (currentMinutes[0] !== minute1) setMinute1(currentMinutes[0])
if (currentMinutes[1] !== minute2) setMinute2(currentMinutes[1])
if (currentHours[0] !== hour1) setHour1(currentHours[0])
if (currentHours[1] !== hour2) setHour2(currentHours[1])
}, [date])

// useEffect(() => {
// const interval = setInterval(() => {
// setFlip(true)
// sleep(1000).then(() => setFlip(false))
// }, 5000)
return (
<div className="flip-clock-container">
<div className={`flip-clock`}>
<time dateTime={date.toLocaleDateString()}>
<FlipPiece integer={+hour1} isFirst={false} />
<FlipPiece integer={+hour2} isFirst={true} />
<span className="flip-clock__colon">:</span>
<FlipPiece integer={+minute1} isFirst={false} />
<FlipPiece integer={+minute2} isFirst={true} />
</time>
</div>
</div>
)
}

// return () => clearInterval(interval)
// }, [])
const FlipPiece = (props: { integer: number; isFirst: boolean }) => {
const { integer, isFirst } = props
const [num, setNum] = useState(integer)
const [isFlip, setIsFlip] = useState(false)

useEffect(() => {
console.log(num)
setIsFlip(true)
setTimeout(() => {
setNum(integer)
setIsFlip(false)
}, 300)
}, [integer])
return (
<div className={`flip-clock${(flip && ' flip') || ''}`}>
<time dateTime={date.toLocaleDateString()}>
<span className="flip-clock__hour">
<span className="flip-clock__digit" data-value={hours[0]}>
{hours[0]}
</span>
<span className="flip-clock__digit" data-value={hours[1]}>
{hours[1]}
<>
<span className={`flip-clock__piece ${isFlip ? 'flip' : ''}`}>
<span className="flip-clock__card card">
<span className="card__top">{num}</span>
<span className="card__bottom" data-value={num}></span>
<span className="card__back" data-value={num}>
<span className="card__bottom" data-value={num}></span>
</span>
</span>
<span className="flip-clock__colon">:</span>
<span className="flip-clock__min">
<span className="flip-clock__digit" data-value={minutes[0]}>
{minutes[0]}
</span>
<span className="flip-clock__digit" data-value={minutes[1]}>
{minutes[1]}
</span>
</span>
</time>
</div>
</span>
</>
)
}
1 change: 1 addition & 0 deletions src/hooks/use-time.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const useTime = (interval: number = 1000) => {
date,
hours: String(date.getHours()).padStart(2, '0'),
minutes: String(date.getMinutes()).padStart(2, '0'),
seconds: String(date.getSeconds()).padStart(2, '0'),
amOrPm: date
.toLocaleTimeString([], {
hour: 'numeric',
Expand Down

0 comments on commit c4da960

Please sign in to comment.