mirror of
https://github.com/web3privacy/web
synced 2024-10-15 18:26:27 +02:00
Fixed the text scramble errors, few changes, added animation, testimonial responsive fix.
This commit is contained in:
parent
0a751eb401
commit
af004075f2
6 changed files with 121 additions and 97 deletions
|
@ -1,99 +1,105 @@
|
||||||
function applyScrambleEffect() {
|
function applyScrambleEffect() {
|
||||||
const glitchTextOnceElements = document.querySelectorAll('.glitch-text');
|
const glitchTextOnceElements = document.querySelectorAll('.glitch-text');
|
||||||
const glitchTextRepeatElements = document.querySelectorAll('.glitch-text-interval');
|
const glitchTextRepeatElements = document.querySelectorAll('.glitch-text-interval');
|
||||||
|
const glitchTextHoverElements = document.querySelectorAll('.glitch-text-hover');
|
||||||
|
|
||||||
|
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
|
||||||
function animateScramble(element, text, duration = 1000) {
|
function animateScramble(element, text, duration = 1000) {
|
||||||
const chars = [];
|
const chars = [];
|
||||||
element.innerHTML = '';
|
element.innerHTML = '';
|
||||||
const preScrambleWidth = element.offsetWidth;
|
const preScrambleWidth = element.offsetWidth;
|
||||||
element.style.width = `${preScrambleWidth}px`;
|
element.style.width = `${preScrambleWidth}px`;
|
||||||
|
|
||||||
for (let t = 0; t < text.length; t++) {
|
for (let t = 0; t < text.length; t++) {
|
||||||
const span = document.createElement('span');
|
const span = document.createElement('span');
|
||||||
span.innerHTML = text[t] === ' ' ? ' ' : text[t];
|
span.innerHTML = text[t] === ' ' ? ' ' : text[t];
|
||||||
chars[t] = span;
|
chars[t] = span;
|
||||||
span.style.display = 'inline-block';
|
span.style.display = 'inline-block';
|
||||||
element.appendChild(span);
|
element.appendChild(span);
|
||||||
}
|
|
||||||
|
|
||||||
const rand = Math.random;
|
|
||||||
const SECONDS = 1000;
|
|
||||||
const FPS = 30;
|
|
||||||
const animationLength = duration;
|
|
||||||
|
|
||||||
function animate3(k) {
|
|
||||||
const kk = k * text.length;
|
|
||||||
for (let i = 0; i < text.length; i++) {
|
|
||||||
if (kk < i) {
|
|
||||||
chars[i].innerHTML = String.fromCharCode(~~(65 + rand() * 26));
|
|
||||||
} else {
|
|
||||||
chars[i].innerHTML = text[i] === ' ' ? ' ' : text[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
const rand = Math.random;
|
||||||
let start = Date.now();
|
const SECONDS = 1000;
|
||||||
function animate() {
|
const FPS = 30;
|
||||||
const current = Date.now();
|
const animationLength = duration;
|
||||||
const time = current - start;
|
|
||||||
const k = time / animationLength;
|
function animate3(k) {
|
||||||
|
const kk = k * text.length;
|
||||||
if (k < 1) {
|
for (let i = 0; i < text.length; i++) {
|
||||||
setTimeout(animate, SECONDS / FPS);
|
if (kk < i) {
|
||||||
animate3(k);
|
chars[i].innerHTML = charset[Math.floor(rand() * charset.length)];
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < text.length; i++) {
|
chars[i].innerHTML = text[i] === ' ' ? ' ' : text[i];
|
||||||
chars[i].innerHTML = text[i] === ' ' ? ' ' : text[i];
|
}
|
||||||
}
|
}
|
||||||
element.style.width = 'auto';
|
|
||||||
element.isAnimating = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
let start = Date.now();
|
||||||
animate();
|
function animate() {
|
||||||
|
const current = Date.now();
|
||||||
|
const time = current - start;
|
||||||
|
const k = time / animationLength;
|
||||||
|
|
||||||
|
if (k < 1) {
|
||||||
|
setTimeout(animate, SECONDS / FPS);
|
||||||
|
animate3(k);
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < text.length; i++) {
|
||||||
|
chars[i].innerHTML = text[i] === ' ' ? ' ' : text[i];
|
||||||
|
}
|
||||||
|
element.style.width = 'auto';
|
||||||
|
element.isAnimating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use IntersectionObserver for once-only animation
|
||||||
const observer = new IntersectionObserver((entries, observer) => {
|
const observer = new IntersectionObserver((entries, observer) => {
|
||||||
entries.forEach(entry => {
|
entries.forEach(entry => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
const element = entry.target;
|
const element = entry.target;
|
||||||
const text = element.innerText;
|
const text = element.innerText;
|
||||||
animateScramble(element, text);
|
animateScramble(element, text);
|
||||||
observer.unobserve(element);
|
observer.unobserve(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, {
|
}, {
|
||||||
threshold: 0.1
|
threshold: 0.1
|
||||||
});
|
});
|
||||||
|
|
||||||
glitchTextOnceElements.forEach((element) => {
|
glitchTextOnceElements.forEach((element) => {
|
||||||
observer.observe(element);
|
observer.observe(element);
|
||||||
});
|
});
|
||||||
|
|
||||||
glitchTextRepeatElements.forEach((element) => {
|
glitchTextRepeatElements.forEach((element) => {
|
||||||
const text = element.innerText;
|
const text = element.innerText;
|
||||||
|
|
||||||
animateScramble(element, text);
|
animateScramble(element, text);
|
||||||
|
|
||||||
const intervalId = setInterval(() => {
|
const intervalId = setInterval(() => {
|
||||||
if (!element.isAnimating) {
|
if (!element.isAnimating) {
|
||||||
animateScramble(element, text);
|
animateScramble(element, text);
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
element.addEventListener('mouseenter', () => {
|
|
||||||
if (!element.isAnimating) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
animateScramble(element, text, 800);
|
|
||||||
element.isAnimating = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
element.isAnimating = false;
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
// Hover functionality for `.glitch-text-hover` elements
|
||||||
document.addEventListener('DOMContentLoaded', applyScrambleEffect);
|
glitchTextHoverElements.forEach((element) => {
|
||||||
|
const text = element.innerText;
|
||||||
|
|
||||||
|
element.addEventListener('mouseenter', () => {
|
||||||
|
// Only start the animation if it isn't already in progress
|
||||||
|
if (!element.isAnimating) {
|
||||||
|
element.isAnimating = true;
|
||||||
|
animateScramble(element, text, 800);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// No need for 'mouseleave' as the animation will complete even if the mouse leaves
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', applyScrambleEffect);
|
||||||
|
|
|
@ -111,7 +111,7 @@ const sortedSections = sectionsConfig
|
||||||
{section.name === "contributors" && (
|
{section.name === "contributors" && (
|
||||||
<div class="middle-pane-medium">
|
<div class="middle-pane-medium">
|
||||||
<h1 class="my-6 glitch-text">Contributors</h1>
|
<h1 class="my-6 glitch-text">Contributors</h1>
|
||||||
<div class="flex gap-3 flex-wrap mb-4 items-center">
|
<div class="flex gap-3 flex-wrap mb-4 items-center justify-center md:justify-start">
|
||||||
{contributors.items.map((contrib) => (
|
{contributors.items.map((contrib) => (
|
||||||
<div>
|
<div>
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -21,8 +21,10 @@ let currentTestimonial = 0;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="w-full mx-auto px-8 border-2 border-[#202020]">
|
<div class="w-full mx-auto px-8 border-2 border-[#202020]">
|
||||||
<div class="relative testimonial-fade active" id="testimonial-container">
|
<div class="relative" id="testimonial-container">
|
||||||
<div class="flex items-center justify-center overflow-hidden">
|
<div
|
||||||
|
class="flex flex-col md:flex-row my-4 md:my-0 items-center justify-center testimonial-fade active overflow-hidden"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<img
|
<img
|
||||||
src={testimonials[currentTestimonial].imageUrl}
|
src={testimonials[currentTestimonial].imageUrl}
|
||||||
|
|
|
@ -28,7 +28,7 @@ function personLink(person) {
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-4"
|
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-4 place-items-center md:place-items-start"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
filteredPeople.map((person) => (
|
filteredPeople.map((person) => (
|
||||||
|
|
|
@ -58,7 +58,7 @@ for (const e of upcomingEvents) {
|
||||||
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 w3pn-hp-grid gap-2 mt-2"
|
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 w3pn-hp-grid gap-2 mt-2"
|
||||||
>
|
>
|
||||||
<div class="bg-events" data-url="/events">
|
<div class="bg-events" data-url="/events">
|
||||||
<div class="title">Events</div>
|
<div class="title glitch-text">Events</div>
|
||||||
<div class="numbers">
|
<div class="numbers">
|
||||||
<div>
|
<div>
|
||||||
<div class="big">{eventsUpcoming}</div>
|
<div class="big">{eventsUpcoming}</div>
|
||||||
|
@ -80,6 +80,7 @@ for (const e of upcomingEvents) {
|
||||||
<div class="text-white mt-1 ml-1.5">
|
<div class="text-white mt-1 ml-1.5">
|
||||||
<a
|
<a
|
||||||
href="https://github.com/web3privacy/web3privacy/blob/main/README.md#contents"
|
href="https://github.com/web3privacy/web3privacy/blob/main/README.md#contents"
|
||||||
|
class="glitch-text"
|
||||||
>Web3 Privacy Database</a
|
>Web3 Privacy Database</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,7 +105,7 @@ for (const e of upcomingEvents) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-talks" data-url="/research">
|
<div class="bg-talks" data-url="/research">
|
||||||
<div class="title">Research</div>
|
<div class="title glitch-text">Research</div>
|
||||||
<div class="numbers">
|
<div class="numbers">
|
||||||
<div>
|
<div>
|
||||||
<div class="big">{core.research.length} research projects →</div>
|
<div class="big">{core.research.length} research projects →</div>
|
||||||
|
@ -115,12 +116,9 @@ for (const e of upcomingEvents) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="middle-pane-medium mt-10">
|
<div class="middle-pane-medium mt-10">
|
||||||
<!--div class="mt-10">
|
|
||||||
<h1>Our Projects</h1>
|
|
||||||
</div-->
|
|
||||||
|
|
||||||
<div class="mt-16">
|
<div class="mt-16">
|
||||||
<h1>Featured Events</h1>
|
<h1 class="glitch-text">Featured Events</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-left">
|
<div class="text-left">
|
||||||
|
@ -149,7 +147,7 @@ for (const e of upcomingEvents) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-16">
|
<div class="mt-16">
|
||||||
<h1>Latest Articles</h1>
|
<h1 class="glitch-text">Latest Articles</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w3pn-articles grid md:grid-cols-2 gap-6">
|
<div class="w3pn-articles grid md:grid-cols-2 gap-6">
|
||||||
|
@ -180,7 +178,7 @@ for (const e of upcomingEvents) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-16">
|
<div class="mt-16">
|
||||||
<h1>Latest Talks</h1>
|
<h1 class="glitch-text">Latest Talks</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid md:grid-cols-2 gap-6">
|
<div class="grid md:grid-cols-2 gap-6">
|
||||||
|
|
|
@ -33,6 +33,25 @@
|
||||||
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.glitch-text {
|
||||||
|
font-family: Major Mono Display, ui-monospace, SFMono-Regular, Menlo, Monaco,
|
||||||
|
Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
|
transition-property: all;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 500ms;
|
||||||
|
text-transform: lowercase!important;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.testimonial-fade {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.testimonial-fade.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
|
@ -86,7 +105,6 @@
|
||||||
a.button button {
|
a.button button {
|
||||||
fill: #fff;
|
fill: #fff;
|
||||||
stroke: #fff;
|
stroke: #fff;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a.button button::after {
|
a.button button::after {
|
||||||
|
|
Loading…
Reference in a new issue