liebling/src/js/post.js
Eduardo Gómez 15bc72e72a
Ghost 4 (#345)
Co-authored-by: Eduardo Gómez <this.eduardo@gmail.com>
Co-authored-by: Tim <mail@timscha.io>
2021-03-23 22:02:04 +01:00

195 lines
4.4 KiB
JavaScript

import $ from 'jquery'
import mediumZoom from 'medium-zoom'
import fitvids from 'fitvids'
import shave from 'shave'
import Glide, {
Controls,
Swipe,
Breakpoints
} from '@glidejs/glide/dist/glide.modular.esm'
import {
isRTL,
isMobile,
adjustImageGallery,
managePostImages,
makeImagesZoomable
} from './helpers'
let $aosWrapper = null
let $progressCircle = null
let lastScrollingY = window.pageYOffset
let lastWindowHeight = 0
let lastDocumentHeight = 0
let circumference = 0
let isTicking = false
const onScrolling = () => {
lastScrollingY = window.pageYOffset
requestTicking()
}
const adjustShare = (timeout) => {
if (!isMobile('1023px')) {
$('body').removeClass('share-menu-displayed')
} else {
$('body').addClass('share-menu-displayed')
setTimeout(() => {
$aosWrapper.removeAttr('data-aos')
}, timeout)
}
}
const onResizing = () => {
setHeights()
adjustShare(100)
setTimeout(() => {
setCircleStyles()
requestTicking()
}, 200)
}
const requestTicking = () => {
if (!isTicking) {
requestAnimationFrame(updating)
}
isTicking = true
}
const updating = () => {
const progressMax = lastDocumentHeight - lastWindowHeight
const percent = Math.ceil((lastScrollingY / progressMax) * 100)
if (percent <= 100) {
setProgress(percent)
}
isTicking = false
}
const setHeights = () => {
lastWindowHeight = window.innerHeight
lastDocumentHeight = $(document).height()
}
const setCircleStyles = () => {
const svgWidth = $progressCircle.parent().width();
const radiusCircle = svgWidth / 2
const borderWidth = isMobile() ? 2 : 3
$progressCircle.parent().attr('viewBox', `0 0 ${svgWidth} ${svgWidth}`)
$progressCircle.attr('stroke-width', borderWidth)
$progressCircle.attr('r', radiusCircle - (borderWidth - 1))
$progressCircle.attr('cx', radiusCircle)
$progressCircle.attr('cy', radiusCircle)
circumference = radiusCircle * 2 * Math.PI
$progressCircle[0].style.strokeDasharray = `${circumference} ${circumference}`
$progressCircle[0].style.strokeDashoffset = circumference
}
const setProgress = (percent) => {
if (percent <= 100) {
const offset = circumference - percent / 100 * circumference
$progressCircle[0].style.strokeDashoffset = offset
}
}
const prepareProgressCircle = () => {
$progressCircle = $('.js-progress')
setHeights()
setCircleStyles()
updating()
setTimeout(() => {
$progressCircle.parent().css('opacity', 1)
}, 300)
}
$(() => {
$aosWrapper = $('.js-aos-wrapper')
const $scrollButton = $('.js-scrolltop')
const $recommendedSlider = $('.js-recommended-slider')
fitvids('.js-post-content')
adjustImageGallery()
adjustShare(1000)
if ($recommendedSlider.length > 0) {
const recommendedSlider = new Glide('.js-recommended-slider', {
type: 'slider',
rewind: false,
perView: 3,
swipeThreshold: false,
dragThreshold: false,
gap: 0,
direction: isRTL() ? 'rtl' : 'ltr',
breakpoints: {
1023: {
type: 'carousel',
perView: 2,
swipeThreshold: 80,
dragThreshold: 120
},
720: {
type: 'carousel',
perView: 2,
swipeThreshold: 80,
dragThreshold: 120
},
568: {
type: 'carousel',
perView: 1,
swipeThreshold: 80,
dragThreshold: 120
}
}
})
const Length = (Glide, Components, Events) => {
return {
mount() {
Events.emit('length.change', Components.Sizes.length)
}
}
}
recommendedSlider.on('mount.after', () => {
shave('.js-article-card-title', 100)
shave('.js-article-card-title-no-image', 250)
})
recommendedSlider.on('length.change', (length) => {
if (length === 1) {
recommendedSlider.update({ type: 'slider' })
$recommendedSlider.find('.js-controls').remove()
}
})
recommendedSlider.mount({ Controls, Swipe, Breakpoints, Length })
}
shave('.js-article-card-title', 100)
shave('.js-article-card-title-no-image', 250)
$scrollButton.on('click', () => {
$('html, body').animate({
scrollTop: 0
}, 500)
})
managePostImages($)
makeImagesZoomable($, mediumZoom)
window.addEventListener('scroll', onScrolling, { passive: true })
window.addEventListener('resize', onResizing, { passive: true })
})
$(window).on('load', () => {
prepareProgressCircle()
})