ok
This commit is contained in:
193
css/animations.css
Normal file
193
css/animations.css
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/* Animation Styles for Homepage Components */
|
||||||
|
|
||||||
|
/* Base animation classes */
|
||||||
|
.animate-fade-in {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Slide in from left */
|
||||||
|
.animate-slide-left {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50px);
|
||||||
|
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-left.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Slide in from right */
|
||||||
|
.animate-slide-right {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(50px);
|
||||||
|
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-right.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale up animation */
|
||||||
|
.animate-scale-up {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9);
|
||||||
|
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-scale-up.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Staggered animations for multiple elements */
|
||||||
|
.animate-stagger-1 {
|
||||||
|
transition-delay: 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-stagger-2 {
|
||||||
|
transition-delay: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-stagger-3 {
|
||||||
|
transition-delay: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-stagger-4 {
|
||||||
|
transition-delay: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-stagger-5 {
|
||||||
|
transition-delay: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero section specific animations */
|
||||||
|
.hero-title {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(40px);
|
||||||
|
transition: opacity 1s ease-out, transform 1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
transition: opacity 1s ease-out 0.3s, transform 1s ease-out 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-subtitle.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-button {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
transition: opacity 0.8s ease-out 0.6s, transform 0.8s ease-out 0.6s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-button.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Image animations */
|
||||||
|
.animate-image {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(1.1);
|
||||||
|
transition: opacity 1s ease-out, transform 1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-image.animate-visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text content animations */
|
||||||
|
.animate-text-content h1,
|
||||||
|
.animate-text-content h2,
|
||||||
|
.animate-text-content h3,
|
||||||
|
.animate-text-content h4 {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-text-content.animate-visible h1,
|
||||||
|
.animate-text-content.animate-visible h2,
|
||||||
|
.animate-text-content.animate-visible h3,
|
||||||
|
.animate-text-content.animate-visible h4 {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-text-content p {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(15px);
|
||||||
|
transition: opacity 0.8s ease-out 0.2s, transform 0.8s ease-out 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-text-content.animate-visible p {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-text-content button,
|
||||||
|
.animate-text-content a[href] {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
transition: opacity 0.8s ease-out 0.4s, transform 0.8s ease-out 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-text-content.animate-visible button,
|
||||||
|
.animate-text-content.animate-visible a[href] {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduced motion for accessibility */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.animate-fade-in,
|
||||||
|
.animate-slide-left,
|
||||||
|
.animate-slide-right,
|
||||||
|
.animate-scale-up,
|
||||||
|
.hero-title,
|
||||||
|
.hero-subtitle,
|
||||||
|
.hero-button,
|
||||||
|
.animate-image,
|
||||||
|
.animate-text-content h1,
|
||||||
|
.animate-text-content h2,
|
||||||
|
.animate-text-content h3,
|
||||||
|
.animate-text-content h4,
|
||||||
|
.animate-text-content p,
|
||||||
|
.animate-text-content button,
|
||||||
|
.animate-text-content a[href] {
|
||||||
|
transition: none;
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading animation for initial page load */
|
||||||
|
.page-loading .animate-on-load {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-loaded .animate-on-load {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
|
||||||
|
}
|
@@ -144,6 +144,8 @@ window.onload = function () {
|
|||||||
'www.ourworld.tf',
|
'www.ourworld.tf',
|
||||||
'ourworld.tf',
|
'ourworld.tf',
|
||||||
'www2.ourworld.tf',
|
'www2.ourworld.tf',
|
||||||
|
'www2.freezone.ourworld.tf',
|
||||||
|
'freezone.ourworld.tf',
|
||||||
'localhost',
|
'localhost',
|
||||||
'127.0.0.1'
|
'127.0.0.1'
|
||||||
]
|
]
|
||||||
@@ -169,3 +171,160 @@ window.onload = function () {
|
|||||||
function openInNewTab(url) {
|
function openInNewTab(url) {
|
||||||
window.open(url, '_blank').focus()
|
window.open(url, '_blank').focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Animation System for Homepage Components
|
||||||
|
class AnimationController {
|
||||||
|
constructor() {
|
||||||
|
this.observer = null;
|
||||||
|
this.isPageLoaded = false;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
// Set up intersection observer for scroll animations
|
||||||
|
this.setupIntersectionObserver();
|
||||||
|
|
||||||
|
// Handle initial page load animations
|
||||||
|
this.handlePageLoad();
|
||||||
|
|
||||||
|
// Initialize animations when DOM is ready
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', () => this.initializeAnimations());
|
||||||
|
} else {
|
||||||
|
this.initializeAnimations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupIntersectionObserver() {
|
||||||
|
const options = {
|
||||||
|
root: null,
|
||||||
|
rootMargin: '0px 0px -10% 0px', // Trigger when element is 10% visible
|
||||||
|
threshold: 0.1
|
||||||
|
};
|
||||||
|
|
||||||
|
this.observer = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
this.animateElement(entry.target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
animateElement(element) {
|
||||||
|
// Add visible class to trigger CSS animations
|
||||||
|
element.classList.add('animate-visible');
|
||||||
|
|
||||||
|
// Animate child elements with stagger effect
|
||||||
|
const children = element.querySelectorAll('.animate-stagger-1, .animate-stagger-2, .animate-stagger-3, .animate-stagger-4, .animate-stagger-5');
|
||||||
|
children.forEach((child, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
child.classList.add('animate-visible');
|
||||||
|
}, index * 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stop observing this element once animated
|
||||||
|
this.observer.unobserve(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePageLoad() {
|
||||||
|
// Add loading class initially
|
||||||
|
document.body.classList.add('page-loading');
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
this.isPageLoaded = true;
|
||||||
|
document.body.classList.remove('page-loading');
|
||||||
|
document.body.classList.add('page-loaded');
|
||||||
|
|
||||||
|
// Animate hero section immediately on load
|
||||||
|
this.animateHeroSection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
animateHeroSection() {
|
||||||
|
const heroElements = document.querySelectorAll('.hero-title, .hero-subtitle, .hero-button');
|
||||||
|
heroElements.forEach(element => {
|
||||||
|
element.classList.add('animate-visible');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeAnimations() {
|
||||||
|
// Find all elements that should be animated
|
||||||
|
const animatedElements = document.querySelectorAll(
|
||||||
|
'.animate-fade-in, .animate-slide-left, .animate-slide-right, .animate-scale-up, .animate-text-content, .animate-image'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Start observing each element
|
||||||
|
animatedElements.forEach(element => {
|
||||||
|
this.observer.observe(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add animation classes to row containers
|
||||||
|
this.addAnimationClassesToRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
addAnimationClassesToRows() {
|
||||||
|
// Get all row containers from the homepage
|
||||||
|
const rows = document.querySelectorAll('[id*="row"], .relative.justify-center.flex.overflow-hidden');
|
||||||
|
|
||||||
|
rows.forEach((row, index) => {
|
||||||
|
// Add different animation types based on position
|
||||||
|
const animationType = this.getAnimationTypeForRow(index);
|
||||||
|
row.classList.add(animationType);
|
||||||
|
|
||||||
|
// Add text content animation to text columns
|
||||||
|
const textColumns = row.querySelectorAll('div[class*="flex-1"]');
|
||||||
|
textColumns.forEach(column => {
|
||||||
|
if (this.hasTextContent(column)) {
|
||||||
|
column.classList.add('animate-text-content');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add image animation to image containers
|
||||||
|
const images = column.querySelectorAll('img');
|
||||||
|
images.forEach(img => {
|
||||||
|
img.parentElement.classList.add('animate-image');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnimationTypeForRow(index) {
|
||||||
|
const animations = ['animate-fade-in', 'animate-slide-left', 'animate-slide-right', 'animate-scale-up'];
|
||||||
|
return animations[index % animations.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
hasTextContent(element) {
|
||||||
|
const textElements = element.querySelectorAll('h1, h2, h3, h4, p, button, a');
|
||||||
|
return textElements.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to trigger animations on scroll direction change
|
||||||
|
handleScrollDirection() {
|
||||||
|
let lastScrollTop = 0;
|
||||||
|
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
const scrollDirection = scrollTop > lastScrollTop ? 'down' : 'up';
|
||||||
|
|
||||||
|
// You can add specific animations based on scroll direction here
|
||||||
|
document.body.setAttribute('data-scroll-direction', scrollDirection);
|
||||||
|
|
||||||
|
lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize animation system
|
||||||
|
let animationController;
|
||||||
|
|
||||||
|
// Enhanced window.onload to include animations
|
||||||
|
const originalWindowOnload = window.onload;
|
||||||
|
window.onload = function() {
|
||||||
|
// Call original onload function
|
||||||
|
if (originalWindowOnload) {
|
||||||
|
originalWindowOnload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize animation controller
|
||||||
|
animationController = new AnimationController();
|
||||||
|
}
|
||||||
|
@@ -5,13 +5,8 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<div class="max-w-screen-2xl mx-auto lg:py-5 py-2 sm:px-6 lg:px-8">
|
<div class="max-w-screen-2xl mx-auto lg:py-5 py-2 sm:px-6 lg:px-8">
|
||||||
<div class="flex flex-col xl:flex-row xl:gap-4 items-center">
|
<div class="flex flex-col xl:flex-row xl:gap-4 items-center">
|
||||||
<div class="space-y-8 lg:max-w-sm xl:max-w-sm lg:mr-8 mb-4 xl:col-span-1 text-center xl:text-left">
|
|
||||||
<a href="/">
|
|
||||||
<img class="lg:w-60 h-auto w-20 mx-auto" src="./images/zdfz.svg" alt="logo" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<p data-v-14efe4a7="" class="text-base leading-6 text-gray-400 mb-4">
|
<p data-v-14efe4a7="" class="text-base leading-6 text-gray-400 mb-4">
|
||||||
© 2024 OurWorld Holdings, All rights reserved.
|
© 2025 OurWorld Holdings, All rights reserved.
|
||||||
<a target="_blank" href="https://docs.threefold.io/docs/legal/terms_and_conditions" class="leading-6 text-gray-500 hover:text-gray-900">Terms & Conditions |
|
<a target="_blank" href="https://docs.threefold.io/docs/legal/terms_and_conditions" class="leading-6 text-gray-500 hover:text-gray-900">Terms & Conditions |
|
||||||
</a><a target="_blank" href="https://docs.threefold.io/docs/legal/privacy_policy" class="leading-6 text-gray-500 hover:text-gray-900">Privacy Policy
|
</a><a target="_blank" href="https://docs.threefold.io/docs/legal/privacy_policy" class="leading-6 text-gray-500 hover:text-gray-900">Privacy Policy
|
||||||
</a>
|
</a>
|
||||||
|
@@ -66,6 +66,7 @@
|
|||||||
|
|
||||||
<!-- CSS/SCSS -->
|
<!-- CSS/SCSS -->
|
||||||
<link rel="stylesheet" href="{{ get_url(path="css/index.css", trailing_slash=false, cachebust=true) | safe }}" />
|
<link rel="stylesheet" href="{{ get_url(path="css/index.css", trailing_slash=false, cachebust=true) | safe }}" />
|
||||||
|
<link rel="stylesheet" href="{{ get_url(path="css/animations.css", trailing_slash=false, cachebust=true) | safe }}" />
|
||||||
<style>
|
<style>
|
||||||
.space-x-10>:not([hidden])~:not([hidden]){
|
.space-x-10>:not([hidden])~:not([hidden]){
|
||||||
margin-left: calc(1.5rem*calc(1 - var(--tw-space-x-reverse)))!important;
|
margin-left: calc(1.5rem*calc(1 - var(--tw-space-x-reverse)))!important;
|
||||||
|
@@ -13,11 +13,6 @@
|
|||||||
<div class="{{'z-10 bg-white fixed w-screen ' ~ header_class}}">
|
<div class="{{'z-10 bg-white fixed w-screen ' ~ header_class}}">
|
||||||
<div class="relative z-50 shadow">
|
<div class="relative z-50 shadow">
|
||||||
<div class="mx-auto flex z-50 shadow justify-between items-center pl-6 pr-2 md:pr-0 lg:py-5 md:px-12 py-2 lg:px-20 lg:justify-start lg:space-x-20">
|
<div class="mx-auto flex z-50 shadow justify-between items-center pl-6 pr-2 md:pr-0 lg:py-5 md:px-12 py-2 lg:px-20 lg:justify-start lg:space-x-20">
|
||||||
<div>
|
|
||||||
<a href="/" class="flex">
|
|
||||||
<img class="w-56 h-auto sm:w-15" src="{{logo_path}}" alt="FreeFlow Logo" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="-mr-2 -my-2 lg:hidden">
|
<div class="-mr-2 -my-2 lg:hidden">
|
||||||
<button id="hamburger-btn" class="menu-mobile inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out my-2">
|
<button id="hamburger-btn" class="menu-mobile inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out my-2">
|
||||||
<!-- Heroicon name: menu -->
|
<!-- Heroicon name: menu -->
|
||||||
|
@@ -5,15 +5,15 @@
|
|||||||
alt="Hero Image"
|
alt="Hero Image"
|
||||||
width="210"
|
width="210"
|
||||||
height="210"
|
height="210"
|
||||||
class="mx-auto rounded-md">
|
class="mx-auto rounded-md animate-scale-up">
|
||||||
|
|
||||||
<p class="text-base font-semibold leading-7 text-blue-600">WELCOME TO</p>
|
<p class="text-base font-semibold leading-7 text-blue-600 hero-subtitle">WELCOME TO</p>
|
||||||
<div class="max-w-4xl">
|
<div class="max-w-4xl">
|
||||||
<h1 class="mt-4 text-3xl lg:text-5xl font-bold leading-8 tracking-tight text-black mb-4">Zanzibar Digital Free Zone</h1>
|
<h1 class="mt-4 text-3xl lg:text-5xl font-bold leading-8 tracking-tight text-black mb-4 hero-title">Zanzibar Digital Free Zone</h1>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-6 text-lg sm:text-xl leading-7 sm:leading-8 text-gray-600 font-light mx-4 sm:mx-0">Zanzibar Digital Free Zone is a collaboration between the Government of Zanzibar and OurWorld Venture Creator. We are the world's first 100% digital free zone, accessible and affordable for all. Removing complexity from doing business.</p>
|
<p class="mt-6 text-lg sm:text-xl leading-7 sm:leading-8 text-gray-600 font-light mx-4 sm:mx-0 hero-subtitle">Zanzibar Digital Free Zone is a collaboration between the Government of Zanzibar and OurWorld Venture Creator. We are the world's first 100% digital free zone, accessible and affordable for all. Removing complexity from doing business.</p>
|
||||||
<div class="mt-10 flex items-center justify-center">
|
<div class="mt-10 flex items-center justify-center">
|
||||||
<a href="#contact" class="rounded-xl bg-blue-700 px-4 py-2.5 font-semibold text-white shadow-sm hover:bg-blue-800 hover:text-blue-200 transition-colors duration-300">
|
<a href="#contact" class="rounded-xl bg-blue-700 px-4 py-2.5 font-semibold text-white shadow-sm hover:bg-blue-800 hover:text-blue-200 transition-colors duration-300 hero-button">
|
||||||
Get Started
|
Get Started
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -228,7 +228,7 @@ Parameters:
|
|||||||
{% set no_margins = " -mx-8 md:-mx-12 lg:-mx-16 xl:-mx-20" %}
|
{% set no_margins = " -mx-8 md:-mx-12 lg:-mx-16 xl:-mx-20" %}
|
||||||
|
|
||||||
|
|
||||||
<div id="{{anchor_link}}" class="{{'relative justify-center flex overflow-hidden ' ~ div_class }}" style="{{styles}}">
|
<div id="{{anchor_link}}" class="{{'relative justify-center flex overflow-hidden animate-fade-in ' ~ div_class }}" style="{{styles}}">
|
||||||
<div id="{{row_id}}" class="{{row_class}}" style="min-width: -webkit-fill-available; min-width: -moz-available">
|
<div id="{{row_id}}" class="{{row_class}}" style="min-width: -webkit-fill-available; min-width: -moz-available">
|
||||||
|
|
||||||
{% for column in columns%}
|
{% for column in columns%}
|
||||||
|
Reference in New Issue
Block a user