This commit is contained in:
2020-02-13 22:24:28 +01:00
parent 9b0c154f61
commit ef23d90eb6
60 changed files with 1665 additions and 930 deletions

View File

@@ -69,8 +69,9 @@
$locations.forEach(loc => loc.country = $countries.find(cont => cont.id === loc.country.id))
</script>
<!-- <style src="../style/style.scss" global></style> -->
<style lang="scss" global>
@import "style/style.scss";
@import "./style/style.scss";
</style>
<slot></slot>

View File

@@ -1,7 +1,11 @@
<script>
import { onMount } from 'svelte'
import { site, currentLocation } from '../store'
import * as fn from '../functions'
import AOS from 'aos'
// Components
import IconArrow from '../atoms/IconArrow'
import Globe from '../molecules/InteractiveGlobe'
import Footer from '../molecules/Footer'
import Locations from '../organisms/Locations'
@@ -10,6 +14,20 @@
$: if ($currentLocation) {
currentLocation.set()
}
/*
** Run code on browser only
*/
onMount(() => {
const titleHouses = document.getElementById('title-houses')
const titleWorld = document.getElementById('title-world')
// Scroll apparitions
if (process.browser) {
AOS.init()
}
})
</script>
<svelte:head>
@@ -19,45 +37,36 @@
<section class="explore">
<div class="wrap">
<div class="explore__top">
<a href="/" class="button-control button-control--pink">
<img src="/img/icons/arrow-white.svg" alt="">
<a href="/" class="button-control button-control--pink dir-left">
<IconArrow direction="left" color="#fff" className="icon" />
<IconArrow direction="left" color="#fff" className="icon" hidden="true" />
</a>
<h1 class="title-location">Houses <em>of the</em> World</h1>
<div class="title-location title-location--inline">
<div aria-label="Houses" data-aos="letters-translate-bottom">
<div class="anim-mask">
{@html fn.lettersToSpan('Houses')}
</div>
</div>
<em>of the</em>
<div aria-label="World" data-aos="letters-translate-bottom">
<div class="anim-mask">
{@html fn.lettersToSpan('World')}
</div>
</div>
</div>
</div>
<div class="description">
<div class="explore__description style-description">
<p>{$site.explore_globe}</p>
</div>
</div>
<Globe />
<Locations />
<Locations />
</section>
<Footer />
<!-- <section class="hero is-medium is-danger has-text-centered">
<div class="hero-body">
<div class="container">
<h1 class="title">Houses Of The World</h1>
</div>
</div>
</section>
<div class="container">
<section class="section">
<h2 class="title is-4">Choose on globe</h2>
<div class="content">
<p>{$site.explore_globe}</p>
<p>[globe]</p>
</div>
<h2 class="title is-4">Choose from list</h2>
<div class="content">
<p>{$site.explore_list}</p>
</div>
<Locations />
</section>
</div> -->

View File

@@ -1,11 +1,27 @@
<script context="module">
import { apiEndpoints } from '../store'
// Preload data
export async function preload (page, session) {
// Load random photos
const limit = 5
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,image.*,location.*,location.country.name&sort=?&limit=${limit}`)
const photos = await req.json()
if (req.status === 200) {
return { photos: photos.data }
}
this.error(404, 'Not found')
}
</script>
<script>
// Svelte
import { fade, slide } from 'svelte/transition'
import { onMount } from 'svelte'
import { site, currentLocation } from '../store'
import * as fn from '../functions'
// Dependencies
// import anime from 'animejs/lib/anime.es.js'
// import * as basicScroll from 'basicscroll'
import * as basicScroll from 'basicscroll'
import AOS from 'aos'
// Components
import Button from '../atoms/Button'
@@ -20,6 +36,50 @@
$: if ($currentLocation) {
currentLocation.set()
}
// Props and variables
export let photos
let appearing
/*
** Run code on browser only
*/
onMount(() => {
// Scroll apparitions
if (process.browser) {
AOS.init()
}
// Parallax titles
const titleHouses = document.getElementById('title-houses')
const scrollTitleHouses = basicScroll.default.create({
elem: titleHouses,
direct: true,
from: '0',
to: window.innerHeight * 0.6,
props: {
'--translateX': {
from: '-7vw',
to: '-20vw'
}
}
}).start()
const titleWorld = document.getElementById('title-world')
const scrollTitleWorld = basicScroll.default.create({
elem: titleWorld,
direct: true,
from: document.querySelector('.explore__description').getBoundingClientRect().top,
to: document.querySelector('#title-world').getBoundingClientRect().bottom * 1.1,
props: {
'--translateX': {
from: '-1vw',
to: '-14vw'
}
}
}).start()
})
</script>
<svelte:head>
@@ -27,75 +87,47 @@
</svelte:head>
<section class="intro">
<h1 class="title-massive title-parallax">Houses</h1>
<!-- <MassiveTitle
text="Houses"
scrollFrom="0" scrollTo={window.innerHeight * 0.6}
effectFrom="-5vw" effectTo="-20vw"
/> -->
<div class="anim-mask">
<div class="anim title-parallax" id="title-houses" data-aos="letters-translate-top">
<h1 class="title-massive" aria-label="Houses">
{@html fn.lettersToSpan('Houses')}
</h1>
</div>
</div>
<div class="wrap">
<div class="description">
<div class="intro__description style-description">
<p>{$site.description}</p>
<Button href="/choose" type="button" text="Explore locations">
<Button href="#choose" type="a" className="button" text="Explore locations">
<IconGlobeSmall width="22" color="#666" />
</Button>
</div>
</div>
<Carousel />
<Carousel {photos} />
</section>
<section class="explore explore--homepage">
<p class="of">of</p>
<div class="of" aria-label="of" data-aos="letters-translate-bottom">
<div class="anim-mask">
{@html fn.lettersToSpan('of')}
</div>
</div>
<div class="description">
<p>{$site.explore_list}</p>
<div class="explore__description style-description" id="choose">
<p>{$site.explore_globe}</p>
</div>
<InteractiveGlobe />
<!-- <MassiveTitle
text="World"
scrollFrom="0" scrollTo={window.innerHeight * 0.6}
effectFrom="-5vw" effectTo="-20vw"
/> -->
<h1 class="title-massive title-parallax">World</h1>
<div class="anim-mask anim-title">
<h1 class="title-massive title-parallax" id="title-world" aria-label="World" data-aos="letters-translate-bottom">
{@html fn.lettersToSpan('World')}
</h1>
</div>
<Locations />
</section>
<Footer />
<!-- <section class="hero is-medium is-danger has-text-centered">
<div class="hero-body">
<div class="container">
<h1 class="title">Houses Of</h1>
<h2 class="subtitle">{$site.description}</h2>
</div>
</div>
</section>
<div class="section">
<div class="container">
<h2 class="title is-4">Choose on globe</h2>
<IconGlobeSmall width="14" color="red" />
<IconGlobe />
<div class="content">
<p>{$site.explore_globe}</p>
<p>[globe]</p>
</div>
<h2 class="title is-4">Choose from list</h2>
<div class="content">
<p>{$site.explore_list}</p>
</div>
<Locations />
</div>
</div>
<!-- <Footer /> -->

View File

@@ -6,7 +6,7 @@
// Preload data
export async function preload (page, session) {
// Load photos
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,date,slug,image.data,created_on,modified_on&filter[location.slug][rlike]=%${page.params.location}%&sort=-created_on,name`)
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,date,slug,image.*,created_on,modified_on&filter[location.slug][rlike]=%${page.params.location}%&limit=-1&sort=-created_on,name`)
const photos = await req.json()
if (req.status === 200) {
return { photos: photos.data }
@@ -16,26 +16,29 @@
</script>
<script>
import { onMount } from 'svelte'
// Dependencies
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.extend(advancedFormat)
dayjs.extend(relativeTime)
// Components
import IconGlobe from '../../../atoms/iconGlobe'
import IconGlobeSmall from '../../../atoms/iconGlobeSmall'
import Cursor from '../../../atoms/Cursor'
import LinkChange from '../../../atoms/LinkChange'
import ToggleLayout from '../../../atoms/ToggleLayout'
import Photo from '../../../molecules/Photo'
import Switcher from '../../../molecules/Switcher'
import Footer from '../../../molecules/Footer'
// Props
// Props and variables
export let photos
// Setup
const { page } = stores()
dayjs.extend(advancedFormat)
dayjs.extend(relativeTime)
let layoutSetting
let pagesTotal = 3
// Update current location
const location = $locations.find(loc => loc.slug === $page.params.location)
@@ -46,8 +49,18 @@
// Define dates
const dateUpdatedFull = photos.length ? dayjs(photos[0].modified_on).format('MMM Do, YYYY') : ''
const dateUpdatedDatetime = photos.length ? dayjs(photos[0].modified_on).format('YYYY-MM-DDThh:mm:ss') : ''
const dateUpdatedRelative = photos.length ? dayjs().to(dayjs(photos[0].modified_on)) : ''
const lastUpdated = photos.length ? (dayjs(photos[0].modified_on).isBefore(dayjs().subtract(1, 'M'))) ? dateUpdatedFull : dateUpdatedRelative : ''
/*
** Run code on browser only
*/
onMount(() => {
// Get layout setting from storage
layoutSetting = localStorage.getItem('photosLayout')
})
</script>
<svelte:head>
@@ -67,7 +80,7 @@
<span>Change</span>
</span>
<svg>
<circle cx="50%" cy="50%" r="43%"></circle>
<circle cx="50%" cy="50%" r="43%" />
</svg>
</a>
</div>
@@ -77,101 +90,56 @@
<div class="wrapper">
<p>{$site.description}</p>
<p>
Houses Of
<a href="/choose" class="link-change">
{location.name}
<span class="icon">
<IconGlobeSmall width="14" color="#999" />
</span>
</a>
Houses on:eventname
<LinkChange href="/choose" text={location.name}>
<IconGlobeSmall width="14" color="#999" />
</LinkChange>
{location.description}
</p>
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedFull} title={dateUpdatedFull}>{lastUpdated}</time>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
</p>
<div class="toggle">
<button on:click class="active">
<svg xmlns="http://www.w3.org/2000/svg" width="19" height="17" viewBox="0 0 19 17">
<path fill="#FF6C89" fillRule="evenodd" d="M39,30 L39,33 L24,33 L24,30 L39,30 Z M43,23 L43,26 L28,26 L28,23 L43,23 Z M39,16 L39,19 L24,19 L24,16 L39,16 Z" transform="translate(-24 -16)" />
</svg>
<span>List</span>
</button>
<button on:click>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20">
<path fill="#FF6C89" fillRule="evenodd" d="M63,27 L63,34 L56,34 L56,27 L63,27 Z M52,25 L52,32 L45,32 L45,25 L52,25 Z M63,16 L63,23 L56,23 L56,16 L63,16 Z M52,14 L52,21 L45,21 L45,14 L52,14 Z" transform="translate(-45 -14)"/>
</svg>
<span>Grid</span>
</button>
</div>
<ToggleLayout />
</div>
</div>
</div>
</section>
<section class="photos photos--list">
<aside class="photos__side">
<div class="sticky">
<section class="photos photos--{layoutSetting || 'list'}">
<div class="photos__side--wrap wrap">
<aside class="photos__side">
<Switcher type="switcher--side" />
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedFull} title={dateUpdatedFull}>{lastUpdated}</time>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
</p>
</div>
</aside>
</aside>
</div>
<Cursor type="zoom" />
<div class="wrap">
<div class="photos__view wrap">
{#each photos as photo, index}
<Photo {photo} index={index + 1} />
{/each}
</div>
{#if photos.length}
<section class="pagination">
<button>
<div class="pagination__page">
<p><span>page</span> 1/3</p>
<div class="pagination__page">
<div class="pagination__page--info">page</div>
<div class="pagination__page--numbers">
<div class="scroll">
<span>3</span>
<span>2</span>
<span>1</span>
</div>
</div>
<p class="style-caps pagination__caption">See more photos</p>
</button>
/{pagesTotal}
</div>
<p class="style-caps pagination__caption">See more photos</p>
</section>
<Footer />
{/if}
</section>
<!-- <div class="section container">
<div class="nav content">
<Switcher />
</div>
<div class="content">
<h1 class="title is-2">{locationFull}</h1>
{#if location && location.description}
<p>
{$site.description}<br>
Houses Of <a href="/choose">{location.name}</a> {location.description}
</p>
{/if}
{#if photos.length}
<p><strong>Updated</strong> <time datetime={dateUpdatedFull} title={dateUpdatedFull}>{lastUpdated}</time></p>
{/if}
</div>
{#if photos.length}
<div class="columns is-multiline">
{#each photos as photo, index}
<div class="column is-one-third">
<Photo {photo} index={index + 1} />
</div>
{/each}
</div>
{:else}
<div class="message is-danger">
<div class="message-body">
<p>No photos for {locationFull}</p>
</div>
</div>
{/if}
</div> -->
<Footer />

View File

@@ -10,7 +10,7 @@
export async function preload (page, session) {
// Load the photos if not loaded
if (!preloaded) {
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,slug,image.data,created_on&filter[location.slug][rlike]=%${page.params.location}%`)
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,slug,image.*,image.data,location.*,location.country.*,created_on&filter[location.slug][rlike]=%${page.params.location}%`)
const photos = await req.json()
return {
photos: photos.data
@@ -24,23 +24,36 @@
</script>
<script>
const { page, session, preloading } = stores()
import { onMount } from 'svelte'
import * as fn from '../../../../functions'
// Dependencies
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
dayjs.extend(advancedFormat)
// Components
import IconGlobe from '../../../../atoms/IconGlobe'
import IconCross from '../../../../atoms/IconCross'
import Carousel from '../../../../organisms/Carousel'
// Props and variables
const { page } = stores()
export let photos
let currentIndex
let indexFormated
let viewerPhotos
let windowWidth
let changeWindowWidth
// Define current location
const location = $locations.find(loc => loc.slug === $page.params.location)
const locationFull = `${location.name}, ${location.country.name}`
$currentLocation == undefined && currentLocation.set({ location, photos })
// Define path
const path = `/viewer/${location.country.slug}/${location.slug}/`
// Set current photo, index and siblings
const setCurrentPhotos = () => {
// Define index and prev/next photos
@@ -62,18 +75,6 @@
}
})
// Define values
const locationFull = `${location.name}, ${location.country.name}`
const path = `/viewer/${location.country.slug}/${location.slug}/`
// Get thumbnail
const getThumb = (photo, size) => {
if (photo) {
const thumbnail = photo.image.data.thumbnails.find(thumb => thumb.url.includes(`key=${size}`))
return thumbnail.url
}
}
// Keyboard navigation
const keyboardNav = event => {
const keyCode = event.keyCode
@@ -85,13 +86,48 @@
// Close
else if ([27,67].includes(keyCode)) document.getElementById('photo_close').click()
}
/*
** Run code on browser only
*/
onMount(() => {
changeWindowWidth = () => {
windowWidth = window.innerWidth
}
changeWindowWidth()
})
</script>
<!-- <pre>{JSON.stringify(viewerPhotos, null, 2)}</pre> -->
<svelte:head>
<title>Houses Of - photoName photoCountryName</title>
</svelte:head>
<svelte:window on:keydown={keyboardNav} />
<svelte:window on:keydown={keyboardNav} on:resize={changeWindowWidth} />
<div class="container">
<section class="viewer">
<div class="viewer__top">
<p class="tip">Tap for fullscreen</p>
<div class="buttons">
<a href="/choose" class="button-control button-control--dashed">
<IconGlobe color="#fff" width="18" />
<svg>
<circle cx="50%" cy="50%" r="{windowWidth >= 768 ? 32 : 24}px"></circle>
</svg>
</a>
<a href="/location/{location.country.slug}/{location.slug}" class="button-control button-control--pink dir-bottom" aria-label="Close">
<IconCross color="#fff" width="18" className="icon" />
<IconCross color="#fff" width="18" className="icon" hidden="true" />
</a>
</div>
</div>
<Carousel viewer={true} {photos} />
</section>
<!-- <div class="container">
<div class="nav content">
<a href="/choose" class="button is-info" id="photo_close">Change location</a>
<a href="/location/{location.country.slug}/{location.slug}" class="button is-dark" id="photo_close">Close</a>
@@ -140,4 +176,4 @@
</div>
</div>
</div>
</div>
</div> -->