diff --git a/Gemfile.lock b/Gemfile.lock
index 7b89849..74ad026 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -75,7 +75,7 @@ GEM
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
- acts_as_list (1.2.0)
+ acts_as_list (1.2.1)
activerecord (>= 6.1)
activesupport (>= 6.1)
addressable (2.8.6)
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 36991b6..1fa0bb5 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -84,6 +84,10 @@
--fs-xl: 2.8rem;
--fs-2xl: 3.4rem;
--fs-3xl: 5.6rem;
+
+ --flip-deg: 0deg;
+ --flip-scale: 1;
+ --flip-rotate: 0deg;
font: 10px/1.3 var(--ff-ikea);
}
@@ -132,6 +136,14 @@ header {
main {
margin: 0 1rem;
+ flex-grow: 1;
+}
+
+footer {
+ font-size: 1.2rem;
+ line-height: 1.2;
+ margin: 1rem;
+ font-family: var(--ff-ikea);
}
.msg__container {
@@ -362,7 +374,6 @@ input[type=range] {
.link__branding {
-
& svg {
width: 70px;
height: auto;
@@ -379,27 +390,48 @@ ul.card__stack {
& a {
text-decoration: none;
color: var(--clr-black);
+ cursor: default;
+
}
+
}
-.card, .link {
- background-color: var(--clr-white);
- box-shadow: var(--shadow);
+.card-front, .card-back, .link {
+ background-color: var(--clr-white);
border-radius: 12px;
box-sizing: border-box;
}
-.card {
+.card-front, .card-back, .link {
+ box-shadow: var(--shadow);
+}
+
+.card__container {
position: absolute;
inset: 0 0 0 0;
+ transition: transform 0.3s ease-in-out 0s;
+ perspective: 500px;
+}
+
+.card {
+ position: absolute;
+ inset: 0 0 0 0;
+ transform-style: preserve-3d;
+}
+
+.card__container.active .card {
+ transform: rotateY(var(--flip-deg)) rotateX(var(--flip-rotate)) scale(var(--flip-scale));
+
+}
+
+.card-front {
+
font-size: var(--fs-xl);
font-weight: 700;
display: grid;
padding: 1.142857142857143em 1em;
grid-template-rows: 1fr 4fr 1fr;
justify-items: center;
-
- transition: transform 0.3s ease-in-out 0s;
& div {
text-align: center;
@@ -421,6 +453,27 @@ ul.card__stack {
}
}
+.card-back {
+ background-color: var(--clr-white);
+ transform: rotateY(180deg);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ & svg {
+ width: 60%;
+
+ }
+}
+
+.card-back, .card-front {
+ position: absolute;
+ inset: 0 0 0 0;
+ backface-visibility: hidden;
+}
+
+
+
.link {
@@ -599,6 +652,10 @@ ul.card__stack {
}
}
+ footer {
+ margin: 2rem;
+ }
+
.icon__container img:nth-child(4) {
display: block;
}
diff --git a/app/javascript/application.js b/app/javascript/application.js
index 9a721b7..29d1ef4 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -9,7 +9,7 @@ function rand_in_range(from, to) {
function shuffle_cards() {
- const cards = document.querySelectorAll('.card')
+ const cards = document.querySelectorAll('.card__container')
const card_ids = Array.from(cards).map(card => card.getAttribute('data-id'))
let shown_cards = JSON.parse(localStorage.getItem('shown_cards')) || [];
let cards_not_shown = card_ids.filter(id => !shown_cards.includes(id));
@@ -21,10 +21,10 @@ function shuffle_cards() {
const random_id = cards_not_shown[Math.floor(Math.random() * cards_not_shown.length)];
cards.forEach((card) => {
- if (card.getAttribute('data-id') == random_id) {
- card.classList.add('active')
+ if (card.getAttribute('data-id') == random_id) {
card.style.zIndex = '1'
- card.style.transform = `none`
+ card.style.transform = ''
+ card.classList.add('active')
} else {
card.classList.remove('active')
card.style.zIndex = 'auto'
@@ -74,6 +74,13 @@ document.querySelectorAll('[data-share-title]').forEach((share_btn) => {
})
})
+document.querySelectorAll('.card__stack a').forEach((card_link) => {
+ card_link.addEventListener('click', (e) => {
+ e.preventDefault()
+ })
+})
+
+
// Open all external links in ny tab
for (const link of document.links) {
if (link.hostname.replace(/^www\./i, "") != window.location.hostname.replace(/^www\./i, "") && (link.protocol == 'https:' || link.protocol == 'http:'))
@@ -82,7 +89,7 @@ for (const link of document.links) {
const input_range = document.getElementsByClassName('reveal')[0]
-const max_value = 200
+const max_value = 180
const speed = 12
var curr_value
@@ -103,7 +110,7 @@ function unlockEndHandler() {
if (curr_value >= this.max) {
- const card = document.querySelector('.card.active')
+ const card = document.querySelector('.card__container.active')
window.location.href = card.parentNode.getAttribute('href')
// reset
@@ -118,7 +125,8 @@ function unlockEndHandler() {
function animateHandler() {
input_range.value = curr_value;
- input_range.closest('.reveal__container').style.setProperty('--opacity', 1 - (input_range.value/input_range.max));
+ input_range.closest('.reveal__container').style.setProperty('--opacity', 1 - (input_range.value/input_range.max));
+ updateRotation(input_range.value)
// continue?
if (curr_value > -1) {
@@ -135,7 +143,35 @@ if (input_range) {
input_range.addEventListener('mouseup', unlockEndHandler, false)
input_range.addEventListener('touchend', unlockEndHandler, false)
- input_range.addEventListener("input", (e) => {
+ input_range.addEventListener("input", (e) => {
e.currentTarget.closest('.reveal__container').style.setProperty('--opacity', 1 - (e.currentTarget.value/e.currentTarget.max))
+
+ updateRotation(e.currentTarget.value)
})
+}
+
+function updateRotation(angle) {
+ document.documentElement.style.setProperty('--flip-deg', angle + 'deg')
+
+ document.documentElement.style.setProperty('--flip-scale', calculateScaleFactor(angle))
+
+ document.documentElement.style.setProperty('--flip-rotate', calculateRotateFactor(angle) + 'deg')
+
+}
+
+const random_salt = Math.random()
+
+function calculateScaleFactor(angle) {
+ const radians = angle * (Math.PI / 180)
+ return 1 + (0.1 * Math.sin(radians))
+
+ // return 1 + (0.2 * (angle / 180))
+}
+
+
+
+function calculateRotateFactor(angle) {
+ const radians = angle * (Math.PI / 180)
+ return (4 * Math.sin(radians)) + (random_salt * 2)
+
}
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 78d9a22..decf451 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -25,5 +25,7 @@
<%= yield %>
+
+