Skip to content
Snippets Groups Projects
Commit 74645d1f authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

finish animated arrow

parent de3df93c
Branches
No related tags found
1 merge request!22Feat/redesign
Showing
with 142 additions and 293 deletions
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="{% if width %}{{ width }}{% else %}20{% endif %}" height="{% if height %}{{ height }}{% else %}21{% endif %}" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon / Placeholder">
<path id="Vector" d="M0 16.5H4.40178L11 10.0002L4.40228 3.5H0L6.60069 10.0002L0 16.5Z" fill="#FEC900"/>
<path
id="{% block id %}{{ id }}{% endblock %}"
d="M0 16.5H4.40178L11 10.0002L4.40228 3.5H0L6.60069 10.0002L0 16.5Z"
fill="{% if fill %}{{ fill }}{% else %}#FEC900{% endif %}"
class="duration-300 arrow-icon"
/>
</g>
</svg>
<div class="flex gap-8 flex-col xl:flex-row grow bg-grey-180">
<div class="flex gap-8 flex-col xl:flex-row grow">
<div class="xl:shrink-0">
<a href="#">
<img
class="h-full w-30 xl:w-60 object-cover"
class="h-full w-16 xl:w-36 object-cover rounded-full"
src="../../../../static/images/person-table.png"
alt=" {{ name }}"
>
......@@ -12,29 +12,25 @@
<div class="flex flex-col justify-between py-4 pr-4 h-full">
<div class="flex flex-col">
<a
class="hover:no-underline block font-bold mb-2 text-xl xl:text-3xl"
class="hover:no-underline block font-bold font-alt leading-8 text-xl xl:text-3xl"
href="#"
><h4>{{ person_big_name }}</h4></a>
<span class="leading-6 mb-4 xl:mb-6 w-10/12">
<span class="leading-6 mb-4 xl:mb-6 w-10/12 text-grey-200">
{{ person_big_function }}
</span>
</div>
<div class="flex flex-col">
<a
class="font-bold mb-2"
class="mb-2"
href="tel:{{ person_big_telephone }}"
>{{ person_big_telephone }}</a>
<a
class="font-bold"
class="text-pirati-yellow"
href="mailto:{{ person_big_mail }}"
>{{ person_big_mail }}</a>
<div class="flex mt-5">
{% include 'patterns/atoms/buttons/round_button_small.html' with button_text='Zjisti více' %}
</div>
</div>
</div>
</div>
......
context:
person_big_name: 'Veronika Šmídová'
person_big_function: 'Tisková mluvčí'
person_big_telephone: '+420 778 111 466'
person_big_mail: 'veronika.smidova@pirati.cz'
<footer class="footer bg-black text-white __js-root">
<footer class="footer bg-black text-white __js-root py-4 lg:py-24 pb-8 lg:pb-24">
<ui-app inline-template>
<div class="py-4 lg:py-24 container--wide grid grid-cols-2">
<!--<section class="footer__social mb-5 mt-16 lg:text-right lg:mb-16 lg:mt-32">
<div class="font-alt text-2xl mb-4">
{{ footer_title }}
</div>
<div
class="flex flex-col space-y-2 lg:flex-row lg:justify-end lg:space-y-0 lg:space-x-4">
<a href="" class="flex items-center hover:no-underline">
<i class="ico--facebook mr-1"></i>
<span class="text-sm">{{ footer_facebook }}</span>
</a>
<a href="" class="flex items-center hover:no-underline">
<i class="ico--twitter mr-1"></i>
<span class="text-sm">{{ footer_twitter }}</span>
</a>
<a href="" class="flex items-center hover:no-underline">
<i class="ico--instagram mr-1"></i>
<span class="text-sm">{{ footer_instagram }}</span>
</a>
<a href="" class="flex items-center hover:no-underline">
<i class="ico--youtube mr-1"></i>
<span class="text-sm">{{ footer_youtube }}</span>
</a>
</div>
</section>-->
<div class="container--wide grid grid-cols-2">
<section class="text-white lg:flex lg:flex-col lg:justify-between gap-8">
{% for item in collapsible_items %}
<div class="py-4 lg:py-0">
......@@ -41,12 +17,51 @@
{% endfor %}
</section>
<section class="flex flex-col">
<div class="mb-10 flex flex-col lg:flex-row lg:flex-wrap lg:order-2 lg:mb-0">
<section class="flex flex-col items-end">
<div class="flex flex-col gap-12">
{% include 'patterns/molecules/contact/contact_footer_box.html' %}
{% include 'patterns/molecules/contact/contact_footer_box.html' %}
</div>
</section>
</div>
</ui-app>
<div class="container--wide flex flex-col gap-8 pt-8">
<section>
<div class="flex items-center gap-x-8">
<a href="#" class="flex gap-2 items-center hover:no-underline">
<i class="ico--facebook"></i>
<span class="text-sm">{{ footer_facebook }}</span>
</a>
<a href="#" class="flex gap-2 items-center hover:no-underline">
<i class="ico--instagram text-lg"></i>
<span class="text-sm">{{ footer_instagram }}</span>
</a>
<a href="#" class="flex gap-2 items-center hover:no-underline">
<i class="ico--feed text-lg"></i>
<span class="text-sm">{{ footer_feed }}</span>
</a>
<a href="#" class="flex gap-2 items-center hover:no-underline">
<i class="ico--twitter text-lg"></i>
<span class="text-sm">{{ footer_twitter }}</span>
</a>
<a href="#" class="flex gap-2 items-center hover:no-underline">
<i class="ico--youtube text-xl"></i>
<span class="text-sm">{{ footer_youtube }}</span>
</a>
</div>
</section>
<section>
<span class="text-xs text-grey-350">
<span class="-scale-x-100 inline-block">{{ copyleft_sign }}</span>
{{ copyleft_text|safe }}
<a href="#" class="underline">{{ privacy_text }}</a>
</span>
</section>
</div>
</footer>
context:
footer_title: 'Zůstaňte s námi v konaktu'
footer_facebook: '@ceska.piratska.strana'
footer_twitter: '#piratskastrana'
footer_twitter: '@piratskastrana'
footer_feed: 'RSS'
footer_instagram: '@pirati.cz'
footer_youtube: 'pirati.cz'
collapsible_1: 'NAVIGACE'
......@@ -10,10 +11,10 @@ context:
collapsible_4: 'DALŠÍ PROJEKTY'
collapsible_5: 'MÉDIA'
copyleft_sign: '©'
copyleft_text: 'Piráti, 2022. Všechna práva vyhlazena. Sdílejte a nechte ostatní sdílet za stejných podmínek'
copyleft_text: 'Piráti, 2023. Všechna práva vyhlazena.<br>Sdílejte a nechte ostatní sdílet za stejných podmínek.'
privacy_text: 'Zásady ochrany osobních údajů'
collapsible_items:
- label: 'NAVIGACE'
menu_items:
- Jak pracujeme
......
......@@ -43,6 +43,21 @@
<div
class="flex text-2xl gap-8 font-alt items-center justify-end"
>
{% if important_item %}
<a
href="#"
class="__js-root flex items-center decoration-1 underline-offset-4 {% if selected_item == important_item %}navbar-menu-item-selected{% endif %}"
>
{% if not is_in_homepage %}
{% include 'patterns/atoms/icons/arrow.html' with width='27' height='28.35' fill='#fff' %}
{% else %}
<ui-animated-arrow></ui-animated-arrow>
{% endif %}
{{ important_item }}
</a>
{% endif %}
{% for item in menu_items %}
<a
href="#"
......
......@@ -8,3 +8,5 @@ context:
- Program
- Kdo jsme
- Kontakty
important_item: 'Evropské volby'
<template>
<div class="flip-clock">
<template v-for="data in timeData" v-show="show">
<span v-bind:key="data.label" class="flip-clock__piece" :id="data.elementId" v-show="data.show">
<span :class="['flip-clock__card', 'flip-card', clockClasses ]">
<b class="flip-card__top">{{ data.current | twoDigits }}</b>
<b class="flip-card__bottom" v-bind:data-value="data.current | twoDigits"></b>
<b class="flip-card__back" v-bind:data-value="data.previous | twoDigits"></b>
<b class="flip-card__back-bottom" v-bind:data-value="data.previous | twoDigits"></b>
</span>
<span :class="['flip-clock__slot', 'font-alt', slotClasses]">{{ data.label }}</span>
</span>
</template>
</div>
</template>
<script>
import Vue from "vue";
import { forEachNode } from "../utils";
export default {
name: 'flipCountdown',
props: {
deadline: {
type: String,
},
stop: {
type: Boolean,
},
units: {
type: String,
default: 'days,hours,minutes,seconds'
},
clockClasses: {
type: String,
default: 'text-6xl'
},
slotClasses: {
type: String,
default: 'text-3xl'
}
},
data() {
const uuid = Math.floor(Math.random() * 100);
return {
now: Math.trunc(new Date().getTime() / 1000),
date: null,
interval: null,
diff: 0,
show: false,
timeData: [
{
current: 0,
previous: 0,
label: "Dní",
elementId: 'flip-card-days-' + uuid,
show: this.units.indexOf("days") !== -1,
},
{
current: 0,
previous: 0,
label: "Hod",
elementId: 'flip-card-hours-' + uuid,
show: this.units.indexOf("hours") !== -1,
},
{
current: 0,
previous: 0,
label: "Min",
elementId: 'flip-card-minutes-' + uuid,
show: this.units.indexOf("minutes") !== -1,
},
{
current: 0,
previous: 0,
label: "Sek",
elementId: 'flip-card-seconds-' + uuid,
show: this.units.indexOf("seconds") !== -1,
},
],
};
},
created() {
if (!this.deadline) {
throw new Error("Missing props 'deadline'");
}
const endTime = this.deadline;
this.date = Math.trunc(Date.parse(endTime.replace(/-/g, '/')) / 1000);
if (!this.date) {
throw new Error("Invalid props value, correct the 'deadline'");
}
this.interval = setInterval(() => {
this.now = Math.trunc(new Date().getTime() / 1000);
}, 1000);
},
mounted() {
if (this.diff !== 0) {
this.show = true;
}
},
watch: {
deadline(newVal, oldVal) {
const endTime = this.deadline;
this.date = Math.trunc(Date.parse(endTime.replace(/-/g, '/')) / 1000);
if (!this.date) {
throw new Error("Invalid props value, correct the 'deadline'");
}
},
now(value) {
this.diff = this.date - value;
if (this.diff <= 0 || this.stop) {
this.diff = 0;
this.updateTime(3, 0);
} else {
this.updateTime(0, Math.trunc(this.diff / 60 / 60 / 24));
this.updateTime(1, Math.trunc(this.diff / 60 / 60) % 24);
this.updateTime(2, Math.trunc(this.diff / 60) % 60);
this.updateTime(3, Math.trunc(this.diff) % 60);
}
},
},
filters: {
twoDigits(value) {
if (value.toString().length <= 1) {
return '0' + value.toString();
}
return value.toString();
},
},
methods: {
updateTime(idx, newValue) {
if (idx >= this.timeData.length || newValue === undefined) {
return;
}
const applyUpdate = () => {
const d = this.timeData[idx];
const val = newValue < 0 ? 0 : newValue;
const el = document.querySelector(`#${d.elementId}`);
if (val !== d.current) {
d.previous = d.current;
d.current = val;
if (el) {
el.classList.remove('flip');
void el.offsetWidth;
el.classList.add('flip');
}
if (idx === 0) {
const els = el.querySelectorAll('span b');
if (els) {
forEachNode(els, e => {
const cls = e.classList[0];
if (newValue / 1000 >= 1) {
if (!cls.includes('-4digits')) {
const newCls = cls + '-4digits';
e.classList.add(newCls);
e.classList.remove(cls);
}
} else {
if (cls.includes('-4digits')) {
const newCls = cls.replace('-4digits', '');
e.classList.add(newCls);
e.classList.remove(cls);
}
}
});
}
}
}
};
if (window['requestAnimationFrame']) {
this.frame = requestAnimationFrame(applyUpdate);
} else {
applyUpdate();
}
},
},
beforeDestroy() {
if (window['cancelAnimationFrame']) {
cancelAnimationFrame(this.frame);
}
},
destroyed() {
clearInterval(interval);
}
}
</script>
<script>
export default {
name: 'AnimatedArrow',
mounted: function () {
let isWhite = false
const invertColors = () => {
isWhite = !isWhite
if (isWhite) {
this.$refs.arrow.style.fill = "#fff"
} else {
this.$refs.arrow.style.fill = "#fec900"
}
}
window.setInterval(invertColors, 750)
}
}
</script>
<template>
<svg width="27" height="28.35" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon / Placeholder">
<path
ref="arrow"
style="transition: fill 0.75s"
class="arrow-icon"
d="M0 16.5H4.40178L11 10.0002L4.40228 3.5H0L6.60069 10.0002L0 16.5Z"
fill="#FEC900"
/>
</g>
</svg>
</template>
<template>
<vue-slick-carousel v-bind="settings" class="article-carousel">
<slot></slot>
</vue-slick-carousel>
</template>
<script>
import VueSlickCarousel from 'vue-slick-carousel'
export default {
components: {VueSlickCarousel},
name: 'ArticleCarousel',
data: () => ({
settings: {
"dots": false,
"infinite": false,
"slidesToShow": 3,
"slidesToScroll": 1,
"responsive": [
{
"breakpoint": 1200,
"settings": {
"slidesToShow": 1
}
}
]
}
})
}
</script>
......@@ -3,7 +3,7 @@ import "../css/style.pcss";
import Vue from "vue";
import { forEachNode } from "./utils";
import ArticleCarousel from "./components/articles/ArticleCarousel";
import AnimatedArrow from "./components/arrows/AnimatedArrow";
import Renderer from "./components/calendar/Renderer";
import DummyProvider from "./components/calendar/DummyProvider";
import GoogleProvider from "./components/calendar/GoogleProvider";
......@@ -15,13 +15,12 @@ import PopoutContent from "./components/popout/PopoutContent";
import PopoutItem from "./components/popout/PopoutItem";
import Navbar from "./components/navbar/Navbar";
import FooterCollapsible from "./components/footer/FooterCollapsible";
import FlipClock from "./components/FlipClock";
import HorizontalScrollable from "./components/HorizontalScrollable";
import SlideUpDown from 'vue-slide-up-down';
Vue.component("ui-article-carousel", ArticleCarousel);
Vue.component("ui-animated-arrow", AnimatedArrow);
Vue.component("ui-calendar-renderer", Renderer);
Vue.component("ui-calendar-dummy-provider", DummyProvider);
Vue.component("ui-calendar-google-provider", GoogleProvider);
......@@ -33,7 +32,6 @@ Vue.component("ui-popout-content", PopoutContent);
Vue.component("ui-popout-item", PopoutItem);
Vue.component("ui-navbar", Navbar);
Vue.component("ui-footer-collapsible", FooterCollapsible);
Vue.component("ui-flip-clock", FlipClock);
Vue.component("ui-horizontal-scrollable", HorizontalScrollable);
Vue.component("ui-slide-up-down", SlideUpDown);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment