.page
.spinner
.item.item_1
.item__inner
.item.item_2
.item__inner
.item.item_3
.item__inner
.item.item_4
.item__inner
.item.item_5
.item__inner
.overlay
View Compiled
@use postcss-nested;
html {
height: 100%;
}
body {
background: #20242D;
min-height: 100%;
* {
box-sizing: border-box;
}
}
.page {
background: #333A4A;
user-select: none;
overflow: hidden;
width: 280px;
height: 480px;
border-radius: 3px;
position: absolute;
top: 50%;
left: 50%;
margin: -240px 0 0 -140px;
box-shadow: 1px 2px 4px rgba(0, 0, 0, .35),
-1px 0 0 rgba(255, 255, 255, .2);
&_active {
.item__inner {
transition: opacity .15s ease-in-out,
transform .15s ease-in-out .1s;
opacity: 0;
}
.item__inner_active {
opacity: 1;
transform: scale(1);
}
.overlay {
top: 100%;
left: 100%;
}
}
&_moving {
.overlay {
top: 0;
left: 0;
}
}
&_touch {
}
}
.overlay {
position: absolute;
top: 0;
left: 70%;
width: 100%;
height: 100%;
z-index: 100;
}
.spinner {
transition: transform .1s linear;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: rotate(0);
transform-origin: 50% 100%;
user-select: none;
}
.item {
width: 100%;
height: 100%;
user-select: none;
position: absolute;
top: 0;
left: 0;
transform-origin: 50% 100%;
&_1 {
.item__inner {
background: #9966FF;
}
}
&_2 {;
.item__inner {
background: #FF6699;
}
}
&_3 {
.item__inner {
background: #00FFCC;
}
}
&_4 {
.item__inner {
background: #FEED30;
}
}
&_5 {
.item__inner {
background: #6666FF;
}
}
&__inner {
transition: opacity .15s ease-in-out .1s,
transform .15s ease-in-out;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
border-radius: 3px;
background: #00FFCC;
transform: scale(.33);
transform-origin: 50%;
&:after {
content: '';
position: absolute;
width: 50%;
left: 25%;
top: 100%;
margin-top: 40px;
height: 10px;
border-radius: 10px;
background: inherit;
}
}
}
View Compiled
startPosX = 0
lastPos = 0
angle = 0
itemsOffset = 45
angleCoef = 3.5
maxCount = 2
innerPagesTemplate = [-2, -1, 0, 1, 2]
isClicked = false
page = document.querySelector('.page')
overlay = document.querySelector('.overlay')
innerPages = document.querySelectorAll('.item__inner')
spinner = document.querySelector('.spinner')
oldX = 0
oldY = 0
isTouchDevice = (e) ->
window.ontouchstart || navigator.maxTouchPoints
if isTouchDevice()
eventMove = 'touchmove'
eventStart = 'touchstart'
eventEnd = 'touchend'
else
eventMove = 'mousemove'
eventStart = 'mousedown'
eventEnd = 'mouseup'
startHanding = (e) ->
oldX = e.clientX
oldY = e.clientY
if isTouchDevice()
page.classList.add('page_touch')
startPosX = e.touches[0].clientX
else
startPosX = e.clientX
page.addEventListener(eventMove, moveHanding, true)
moveHanding = (e)->
if !isTouchDevice() && oldX == e.clientX && oldY == e.clientY
return
oldX = e.clientX
oldY = e.clientY
if isTouchDevice()
angle = lastPos + e.touches[0].clientX - startPosX
else
angle = lastPos + e.clientX - startPosX
page.classList.add('page_moving')
setAngle(angle)
finishHanding = (e)->
page.removeEventListener(eventMove, moveHanding, true)
page.classList.remove('page_moving')
page.classList.remove('page_touch')
if angle%(itemsOffset *angleCoef) <= (itemsOffset * angleCoef) / 2
rotateAngle = angle - angle%(itemsOffset * angleCoef)
else
rotateAngle = angle + ((itemsOffset * angleCoef) - angle%(itemsOffset * angleCoef))
if rotateAngle / angleCoef > itemsOffset * maxCount
lastPos = angleCoef * itemsOffset * maxCount
rotateAngle = itemsOffset * maxCount
else if rotateAngle / angleCoef < -itemsOffset * maxCount
lastPos = -angleCoef * itemsOffset * maxCount
rotateAngle = -itemsOffset * maxCount
else
lastPos = rotateAngle
rotateAngle = rotateAngle / angleCoef
spinner.style.webkitTransform = "rotate(#{rotateAngle}deg)"
spinner.style.transform = "rotate(#{rotateAngle}deg)"
innerHanding = (e)->
e.stopPropagation()
for innerPage in innerPages
innerPage.classList.remove('item__inner_active')
page.classList.toggle('page_active')
if page.classList.contains('page_active')
page.removeEventListener(eventStart, startHanding, true)
e.target.classList.add('item__inner_active')
else
page.addEventListener(eventStart, startHanding, true)
setAngle = (angleVal)->
offset = angleVal / angleCoef
spinner.style.webkitTransform = "rotate(#{offset}deg)"
spinner.style.transform = "rotate(#{offset}deg)"
page = document.querySelector('.page')
page.addEventListener(eventStart, startHanding, true)
document.addEventListener(eventEnd, finishHanding, true)
for innerPage, i in innerPages
innerPage.parentNode.style.webkitTransform = "rotate(#{itemsOffset * innerPagesTemplate[i]}deg)"
innerPage.parentNode.style.transform = "rotate(#{itemsOffset * innerPagesTemplate[i]}deg)"
innerPage.addEventListener('click', innerHanding, true)
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.