File: /var/www/fintechfuel/src/routes/[...lang=locale]/(app)/Devices.svelte
<script lang="ts">
import playCircle from '../../../assets/images/play-circle.svg';
import { browser } from '$app/environment';
import close from '../../../assets/images/close.svg';
import play from '../../../assets/images/play.svg';
import pause from '../../../assets/images/pause.svg';
import { loadEvent } from '../../../store';
import loadObserver from '../../../utils/loadObserver';
import { t } from '$lib/translations';
let showPopup = false;
let timeM = 0;
let timeB = 0;
let timeD = 0;
let durationM = 0;
let durationB = 0;
let durationD = 0;
let paused = false;
function format(seconds) {
if (isNaN(seconds)) return '...';
const minutes = Math.floor(seconds / 60);
seconds = Math.floor(seconds % 60);
if (seconds < 10) seconds = '0' + seconds;
return `${minutes}:${seconds}`;
}
const onMouse = () => {
const list = document.querySelector('.devicesList');
let cursor = document.querySelector('.devicesCursor');
if (list) {
list.addEventListener('mousemove', (e) => {
cursor = document.querySelector('.devicesCursor');
if (!cursor) return false;
cursor.style.opacity = 1;
cursor.style.position = 'fixed';
cursor.style.left = e.clientX + -75 + 'px';
cursor.style.top = e.clientY + -22 + 'px';
});
list.addEventListener('mouseleave', () => {
cursor = document.querySelector('.devicesCursor');
if (!cursor) return false;
cursor.style.opacity = 0;
});
}
const items = document.querySelectorAll('.devicesItem');
if (items.length) {
items.forEach((item) => {
if (!item) return false;
item.addEventListener('mousemove', () => {
items.forEach((item) => {
item.classList.add('opacity');
});
item.classList.add('hover');
});
item.addEventListener('mouseleave', () => {
items.forEach((item) => {
item.classList.remove('opacity');
});
item.classList.remove('hover');
});
});
}
};
if (browser) {
const matches = window.matchMedia('(min-width: 1024px)').matches;
window.addEventListener('resize', function () {
if (matches) {
onMouse();
}
});
if (matches) {
onMouse();
const items = document.querySelectorAll('.devicesItem');
if (items?.length) {
items.forEach((item) => {
const close = item.querySelector('.devicesPopupClose');
const controls = item.querySelector('.devicesPopupVideoControls');
const video = item.querySelector('.devicesPopupVideo video');
item.addEventListener('click', () => {
if (video && !showPopup) {
if (!video.src) {
video.src = item.dataset.src;
}
video.play();
paused = false;
}
item.classList.add('show');
item.style.zIndex = 2;
showPopup = true;
});
if (controls) {
controls.addEventListener('click', () => {
setTimeout(() => {
if (paused) {
video?.play();
paused = false;
} else {
video?.pause();
paused = true;
}
}, 1);
});
}
if (close) {
close.addEventListener('click', () => {
setTimeout(() => {
item.classList.remove('show');
showPopup = false;
if (video) {
video.pause();
paused = true;
}
}, 1);
setTimeout(() => {
item.style.zIndex = 'unset';
}, 300);
});
}
});
}
} else {
const items = document.querySelectorAll('.devicesItem');
if (items?.length) {
items.forEach((item) => {
setTimeout(() => {
const video = item.querySelector('.devicesPopupVideo video');
video.src = item.dataset.src;
}, 100);
});
}
}
}
const onload = loadObserver(() => {
loadEvent.set(true);
});
</script>
<div class="devices">
<div class="devicesContent">
<h2 class="devicesTitle">{$t('Available on all devices')}</h2>
<p class="devicesText">{$t('Enable your clients to trade on the go and never miss an opportunity.')}</p>
</div>
<div class="devicesList">
{#if !showPopup}
<div class="devicesCursor">
<p>{$t('How it works')}</p>
<img src={playCircle} alt="" />
</div>
{/if}
<div
class="devicesItem mobile"
data-src="../devices/mobile.MP4"
data-poster="../devices/iphone-poster.png"
data-name={$t('Mobile Apps')}
data-system="iOS · Android"
data-img="../devices/iphone.png"
data-mask="../devices/iphone-mask.svg"
data-type="mobile"
>
<div class="devicesPopup mobile">
<div class="devicesPopupClose">
<img src={close} alt="" />
</div>
<div class="devicesPopupVideoControls">
{#if paused}
<img src={play} alt="" />
{:else}
<img src={pause} alt="" />
{/if}
</div>
<div class="devicesPopupVideoTime">{format(durationM - timeM)}</div>
<div class="devicesPopupContainer">
<div class="devicesPopupVideo">
<video
style="-webkit-mask-image: url(../devices/iphone-mask.svg)"
poster="../devices/static/mobile.png"
loop
muted
autoplay
playsinline
bind:duration={durationM}
bind:currentTime={timeM}
/>
</div>
<div class="devicesPopupImg">
<img use:onload src="../devices/static/mobile.png" alt="" />
</div>
</div>
</div>
<div class="devicesItemContent">
<p class="devicesContentName">{$t('Mobile Apps')}</p>
<p class="devicesContentSystem">iOS · Android</p>
</div>
</div>
<div
class="devicesItem browser"
data-src="../devices/browser.mp4"
data-poster="../devices/browser-poster.png"
data-name={$t('All browsers')}
data-system="Safari · Chrome · Opera and etc."
data-chevron={$t('PWA version by request')}
data-img="../devices/browser.png"
data-mask="../devices/browser-mask.svg"
data-type="browser"
>
<div class="devicesPopup browser">
<div class="devicesPopupClose">
<img src={close} alt="" />
</div>
<div class="devicesPopupVideoControls">
{#if paused}
<img src={play} alt="" />
{:else}
<img src={pause} alt="" />
{/if}
</div>
<div class="devicesPopupVideoTime">{format(durationB - timeB)}</div>
<div class="devicesPopupContainer">
<div class="devicesPopupVideo">
<video
style="-webkit-mask-image: url(../devices/browser-mask.svg)"
poster="../devices/browser-poster.png"
loop
muted
autoplay
playsinline
bind:duration={durationB}
bind:currentTime={timeB}
/>
</div>
<div class="devicesPopupImg">
<img use:onload src="../devices/static/browser.png" alt="" />
</div>
</div>
</div>
<div class="devicesItemContent">
<p class="devicesContentName">{$t('All browsers')}</p>
<p class="devicesContentSystem">Safari · Chrome · Opera and etc.</p>
<p class="devicesContentChevron">{$t('PWA version by request')}</p>
</div>
</div>
<div
class="devicesItem desktop"
data-src="../devices/desktop-x2.mp4"
data-poster="../devices/desktop-poster.png"
data-name={$t('Standalone OS Apps')}
data-system="Windows · MacOS"
data-img="../devices/desktop.png"
data-mask="../devices/desktop-mask.svg"
data-type="desktop"
>
<div class="devicesPopup desktop">
<div class="devicesPopupClose">
<img src={close} alt="" />
</div>
<div class="devicesPopupVideoControls">
{#if paused}
<img src={play} alt="" />
{:else}
<img src={pause} alt="" />
{/if}
</div>
<div class="devicesPopupVideoTime">{format(durationD - timeD)}</div>
<div class="devicesPopupContainer">
<div class="devicesPopupVideo">
<video
style="-webkit-mask-image: url(../devices/desktop-mask.svg)"
poster="../devices/static/desktop.png"
loop
muted
autoplay
playsinline
bind:duration={durationD}
bind:currentTime={timeD}
/>
</div>
<div class="devicesPopupImg">
<img use:onload src="../devices/static/desktop.png" alt="" />
</div>
</div>
</div>
<div class="devicesItemContent">
<p class="devicesContentName">{$t('Standalone OS Apps')}</p>
<p class="devicesContentSystem">Windows · MacOS</p>
</div>
</div>
</div>
</div>
<style lang="scss">
@import '../../../scss/media';
.devices {
.devicesContent {
max-width: 790px;
margin-inline: auto;
margin-bottom: 72px;
@include breakpoint-down('tabM') {
max-width: 544px;
}
@include breakpoint-down('tabS') {
margin-bottom: 64px;
}
@include breakpoint-down('mobM') {
margin-bottom: 56px;
}
}
.devicesCursor {
position: absolute;
display: flex;
align-items: center;
gap: 8px;
z-index: 1;
background: #fe4d0d;
padding: 10px 20px;
border-radius: 16px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
@include breakpoint-down('tabM') {
display: none;
}
> p {
font-size: 16px;
font-weight: 500;
line-height: 24px;
letter-spacing: 0.005em;
color: #ffffff;
}
> img {
width: 20px;
height: 20px;
}
}
.devicesTitle {
text-align: center;
margin-bottom: 24px;
font-size: 72px;
font-weight: 600;
line-height: 94px;
@include breakpoint-down('tabM') {
font-size: 48px;
line-height: 58px;
}
@include breakpoint-down('mobM') {
font-size: 32px;
line-height: 42px;
}
}
.devicesText {
text-align: center;
font-size: 24px;
font-weight: 400;
line-height: 36px;
@include breakpoint-down('tabM') {
font-size: 22px;
line-height: 33px;
}
@include breakpoint-down('tabS') {
font-size: 20px;
line-height: 30px;
}
@include breakpoint-down('mobM') {
font-size: 18px;
line-height: 27px;
}
}
.devicesList {
display: flex;
position: relative;
min-height: 869px;
cursor: none !important;
@include breakpoint-down('deskS') {
min-height: 692px;
}
@include breakpoint-down('tabM') {
flex-direction: column;
width: 100%;
max-width: 544px;
margin-inline: auto;
cursor: auto !important;
}
}
.devicesItem {
position: absolute;
background: #faf9f8;
width: calc(100% / 3);
transition: 0.3s ease-in-out;
@include breakpoint-down('tabM') {
position: unset !important;
transform: none !important;
width: 100%;
display: flex;
flex-direction: column-reverse;
margin-bottom: 72px;
&:last-of-type {
margin-bottom: 0;
}
}
@include breakpoint-down('mobM') {
position: relative;
left: -16px;
right: -16px;
width: calc(100% + 16px + 16px);
margin-left: -16px;
margin-bottom: 56px;
}
&.mobile {
left: 0;
top: 0;
bottom: 0;
}
&.browser {
left: 50%;
transform: translateX(-50%);
top: 0;
bottom: 0;
}
&.desktop {
right: 0;
top: 0;
bottom: 0;
}
&.opacity {
.devicesPopup {
opacity: 0.6;
}
}
&.hover {
.devicesPopup {
opacity: 1;
}
}
}
.devicesPopup {
margin-bottom: 40px;
padding: 78px 73px 78px 73px;
overflow: hidden;
position: relative;
transition: 0.3s ease-in-out;
@include breakpoint-down('deskS') {
height: 550px;
padding: 60px 55px 60px 55px;
}
@include breakpoint-down('tabM') {
height: 730px;
margin-top: 40px;
margin-bottom: 0;
padding-top: 80px;
padding-bottom: 80px;
}
@include breakpoint-down('tabS') {
margin-top: 28px;
}
@include breakpoint-down('mobM') {
height: auto;
padding-top: 44px;
padding-bottom: 44px;
}
&.mobile {
border-radius: 24px 0 0 24px;
background: #caccc4;
@include breakpoint-down('tabM') {
border-radius: 20px;
padding-left: 133px;
padding-right: 133px;
}
@include breakpoint-down('tabS') {
padding-left: 75px;
padding-right: 75px;
}
@include breakpoint-down('mobM') {
border-radius: 0;
padding-left: 41px;
padding-right: 41px;
}
.devicesPopupContainer {
width: 278px;
height: 572px;
margin-inline: auto;
overflow: hidden;
position: relative;
@include breakpoint-down('deskS') {
height: 432px;
width: 210px;
}
@include breakpoint-down('tabM') {
height: 100%;
width: max-content;
}
@include breakpoint-down('mobM') {
width: 100%;
}
.devicesPopupVideo {
width: 278px;
height: 572px;
padding: 12px;
@include breakpoint-down('deskS') {
height: 432px;
width: 210px;
padding: 10px;
}
@include breakpoint-down('tabM') {
height: 100%;
width: max-content;
}
}
img,
video {
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
&.browser {
background: #d2d4cc;
@include breakpoint-down('tabM') {
border-radius: 20px;
padding-left: 78px;
}
@include breakpoint-down('mobM') {
border-radius: 0;
padding-left: 56px;
}
.devicesPopupContainer {
width: 982px;
height: 572px;
margin-inline: auto;
overflow: hidden;
position: relative;
@include breakpoint-down('deskS') {
height: 432px;
width: 741px;
}
@include breakpoint-down('tabM') {
height: 100%;
width: max-content;
}
.devicesPopupVideo {
width: 982px;
height: 572px;
padding-top: 52px;
@include breakpoint-down('deskS') {
height: 432px;
width: 741px;
padding-top: 39px;
}
@include breakpoint-down('tabM') {
height: 100%;
width: max-content;
padding-top: 52px;
}
}
img,
video {
width: 100%;
height: 100%;
display: block;
object-fit: contain;
}
}
}
&.desktop {
background: #dee0da;
border-radius: 0 24px 24px 0;
@include breakpoint-down('tabM') {
border-radius: 20px;
padding-left: 66px;
}
@include breakpoint-down('mobM') {
border-radius: 0;
padding-left: 44px;
}
.devicesPopupContainer {
width: 935px;
height: 572px;
margin-inline: auto;
overflow: hidden;
position: relative;
@include breakpoint-down('deskS') {
height: 432px;
width: 706px;
}
@include breakpoint-down('tabM') {
height: 100%;
width: max-content;
}
.devicesPopupVideo {
width: 935px;
height: 572px;
padding: 22px 74px 25px 74px;
@include breakpoint-down('deskS') {
height: 432px;
width: 706px;
padding: 18px 46px 18px 56px;
}
@include breakpoint-down('tabM') {
height: 100%;
width: max-content;
padding: 22px 74px 25px 74px;
}
}
img,
video {
width: 100%;
height: 100%;
display: block;
object-fit: contain;
}
}
}
}
.devicesPopupClose {
border-radius: 24px;
border: 1px solid #d9d7cc;
background: #faf9f8;
height: 44px;
width: 44px;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 32px;
right: 32px;
cursor: pointer;
z-index: 2;
opacity: 0;
pointer-events: none;
transition: 0s ease-in-out;
&:hover {
background: #f0ede8;
border: 1px solid #f0ede8;
}
&:active {
background: #d9d7cc;
border: 1px solid #d9d7cc;
}
}
.devicesPopupVideoControls {
cursor: pointer;
position: absolute;
right: 32px;
bottom: 32px;
opacity: 0;
pointer-events: none;
transition: 0s ease-in-out;
&:hover {
right: 30px;
bottom: 30px;
img {
width: 48px;
height: 48px;
}
}
}
.devicesPopupVideoTime {
position: absolute;
left: 32px;
bottom: 44px;
opacity: 0;
pointer-events: none;
transition: 0s ease-in-out;
}
.devicesPopupVideo {
position: absolute;
left: 0;
top: 0;
opacity: 0;
pointer-events: none;
transition: 0s ease-in-out;
@include breakpoint-down('tabM') {
opacity: 1;
}
video {
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-size: 100%;
mask-size: 100%;
}
}
.devicesItemContent {
display: flex;
flex-direction: column;
align-items: center;
}
.devicesContentName {
margin-bottom: 4px;
font-size: 18px;
font-weight: 600;
line-height: 27px;
letter-spacing: 0.005em;
text-align: center;
}
.devicesContentSystem {
color: #73726c;
}
.devicesContentChevron {
background: #dee0da;
border-radius: 8px;
padding: 6px 10px;
margin-top: 16px;
font-size: 14px;
font-weight: 400;
line-height: 18px;
}
}
:global(.devicesItem.show) {
width: 100% !important;
z-index: 3 !important;
cursor: auto !important;
.devicesPopup {
border-radius: 24px;
}
.devicesPopupClose,
.devicesPopupVideoControls,
.devicesPopupVideoTime,
.devicesPopupVideo {
opacity: 1;
pointer-events: all;
}
}
</style>