const closest = function(target, selector){
if (!(target instanceof Element)) {
target = target.parentElement;
}
if (!(target instanceof Element)) {
return null;
}
return target.closest(selector);
};
const $ = function(selector, scope = document){
return scope.querySelector(selector);
};
const $$ = function(selector, scope = document){
return Array.from(scope.querySelectorAll(selector));
};
$$('.js-num').forEach(function(input){
input.addEventListener('focus', function(){
input.setAttribute('inputmode', 'tel');
});
});
$$('input').forEach(function(input){
input.addEventListener('keydown', function(e){
if (e.key === 'Enter') {
e.preventDefault();
}
});
});
function validation(target){
const formLists = closest(target, 'ul.form_lists');
if (!formLists) {
return;
}
const btn = $('.js-btn', formLists);
let isValid = true;
$$('.js-must', formLists).forEach(function(item){
if (!isValid) {
return;
}
if (item.classList.contains('js-radio')) {
const name = item.getAttribute('name');
if (!$('input[name="' + name + '"]:checked', formLists)) {
isValid = false;
}
} else if (item.classList.contains('js-check')) {
if (!item.checked) {
isValid = false;
}
} else if (item.classList.contains('js-text')) {
if (item.value.trim() === '') {
isValid = false;
}
}
});
if (btn) {
btn.classList.toggle('peni', !isValid);
btn.disabled = !isValid;
}
}
$$('.js-form').forEach(function(item){
['change', 'keyup', 'input'].forEach(function(eventName){
item.addEventListener(eventName, function(){
validation(item);
});
});
});
$$('ul.form_lists').forEach(function(formLists){
const firstFormItem = $('.js-form', formLists);
if (firstFormItem) {
validation(firstFormItem);
}
});
function scrollAction(){
const winH = window.innerHeight;
const actLine = winH * 7 / 8;
const doneLine = winH * 1 / 8;
$$('.js-scroll').forEach(function(item){
const top = item.getBoundingClientRect().top;
item.classList.toggle('act', top < actLine);
item.classList.toggle('done', top < doneLine);
});
}
function resetCardBg(){
$$('.card_bg').forEach(function(bg){
gsap.set(bg, {
clearProps: 'transform,boxShadow'
});
});
}
const categoryMap = {
strategy: 0,
management: 1,
technology: 2
};
const categoryKeys = Object.keys(categoryMap);
let categorySwiper = null;
if ($('.js-category-swiper')) {
categorySwiper = new Swiper('.js-category-swiper', {
speed: 400,
autoHeight: true,
allowTouchMove: false,
});
window.categorySwiper = categorySwiper;
}
function updateSwiper(){
if (categorySwiper) {
categorySwiper.update();
categorySwiper.updateAutoHeight(0);
}
scrollAction();
}
window.addEventListener('scroll', scrollAction);
window.addEventListener('resize', function(){
resetCardBg();
updateSwiper();
});
scrollAction();
document.addEventListener('change', function(e){
const input = closest(e.target, 'input[name="category"]');
if (!input) {
return;
}
const category = input.value;
if (categorySwiper && categoryMap[category] !== undefined) {
categorySwiper.slideTo(categoryMap[category]);
setTimeout(function(){
updateSwiper();
}, 0);
}
});
if (categorySwiper) {
categorySwiper.on('slideChange', function(){
const activeIndex = categorySwiper.activeIndex;
const category = categoryKeys.find(function(key){
return categoryMap[key] === activeIndex;
});
if (category) {
const input = $('input[name="category"][value="' + category + '"]');
if (input) {
input.checked = true;
}
}
});
}
if (window.matchMedia('(hover: hover) and (pointer: fine)').matches) {
document.addEventListener('mousemove', function(e){
const card = closest(e.target, '.card');
if (!card || !card.classList.contains('act')) {
return;
}
const bg = $('.card_bg', card);
if (!bg) {
return;
}
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateY = ((x - centerX) / centerX) * 8;
const rotateX = ((centerY - y) / centerY) * 8;
gsap.to(bg, {
rotateX: rotateX,
rotateY: rotateY,
z: 12,
scale: 1.02,
boxShadow: '0 16px 32px 0 hsla(222, 22%, 4%, .4)',
duration: .32,
ease: 'power3.out',
overwrite: true
});
});
document.addEventListener('mouseleave', function(e){
const card = closest(e.target, '.card');
if (!card) {
return;
}
const bg = $('.card_bg', card);
if (!bg) {
return;
}
gsap.to(bg, {
rotateX: 0,
rotateY: 0,
z: 0,
scale: 1,
boxShadow: '0 0 0 0 hsla(222, 22%, 4%, 0)',
duration: .8,
ease: 'elastic.out(1, .45)'
});
}, true);
}
function filterWords(){
const favoriteInput = $('.js-filter-favorite');
const displayInput = $('.js-filter-display');
const searchInput = $('.js-search-word');
const favoriteOnly = favoriteInput ? favoriteInput.checked : false;
const displayOnly = displayInput ? displayInput.checked : false;
const keyword = searchInput ? searchInput.value.trim().toLowerCase() : '';
$$('.js-word').forEach(function(word){
const favorite = word.getAttribute('data-favorite');
const display = word.getAttribute('data-display');
const searchText = (word.getAttribute('data-search') || '').toLowerCase();
let show = true;
if (favoriteOnly && favorite !== 'on') {
show = false;
}
if (displayOnly && display !== 'on') {
show = false;
}
if (keyword && !searchText.includes(keyword)) {
show = false;
}
word.style.display = show ? '' : 'none';
});
updateSwiper();
}
document.addEventListener('change', function(e){
if (
closest(e.target, '.js-filter-favorite') ||
closest(e.target, '.js-filter-display')
) {
filterWords();
}
});
document.addEventListener('input', function(e){
if (closest(e.target, '.js-search-word')) {
filterWords();
}
});
document.addEventListener('change', function(e){
const checkbox = closest(e.target, '.js-favorite, .js-display');
if (!checkbox) {
return;
}
const card = closest(checkbox, '.js-word');
if (!card) {
return;
}
const field = checkbox.classList.contains('js-favorite') ? 'favorite' : 'display';
const value = checkbox.checked ? 'on' : 'off';
const formData = new FormData();
formData.append('action', 'vocab_update_word');
formData.append('post_id', card.getAttribute('data-id'));
formData.append('field', field);
formData.append('value', value);
fetch(vocab.ajax_url, {
method: 'POST',
body: formData,
credentials: 'same-origin'
})
.then(function(response){
return response.json();
})
.then(function(res){
if (res.success) {
card.setAttribute('data-' + field, value);
filterWords();
}
});
});
function sortWords(section){
const list = $('.js-word-list', section);
if (!list) {
return;
}
const checkedSort = $('input[type="radio"][name^="sort_"]:checked', section);
const sort = checkedSort ? checkedSort.value : 'new';
const words = $$('.js-word', list);
words.sort(function(a, b){
const dateA = Number(a.getAttribute('data-date'));
const dateB = Number(b.getAttribute('data-date'));
if (sort === 'old') {
return dateA - dateB;
}
if (sort === 'random') {
return Math.random() - 0.5;
}
return dateB - dateA;
});
words.forEach(function(word){
list.appendChild(word);
});
updateSwiper();
}
document.addEventListener('change', function(e){
const input = closest(e.target, 'input[type="radio"][name^="sort_"]');
if (!input) {
return;
}
const section = closest(input, 'section.cards');
if (section) {
sortWords(section);
}
});
document.addEventListener('change', function(e){
const radio = closest(e.target, '.js-format');
if (!radio) {
return;
}
const formData = new FormData();
formData.append('action', 'vocab_update_setting');
formData.append('post_id', radio.getAttribute('data-post-id'));
formData.append('field', 'format');
formData.append('value', radio.value);
fetch(vocab.ajax_url, {
method: 'POST',
body: formData,
credentials: 'same-origin'
});
});
function initLogoAnimation(){
const logo = $('header .logo a');
const parts = $$('header .logo svg polygon, header .logo svg path');
if (!logo || !parts.length) {
return;
}
gsap.set(parts, {
transformOrigin: '50% 50%',
transformBox: 'fill-box',
fill: 'var(--white)',
opacity: 1
});
const bounceTl = gsap.timeline({
repeat: -1,
repeatDelay: 1.2
});
parts.forEach(function(part, index){
bounceTl.to(part, {
y: -5,
scaleX: 0.94,
scaleY: 1.1,
rotation: index % 2 === 0 ? -3 : 3,
duration: 0.32,
ease: 'power2.out'
}, index * 0.16);
bounceTl.to(part, {
y: 2,
scaleX: 1.08,
scaleY: 0.92,
rotation: 0,
duration: 0.28,
ease: 'power2.inOut'
}, index * 0.16 + 0.32);
bounceTl.to(part, {
y: 0,
scaleX: 1,
scaleY: 1,
rotation: 0,
duration: 0.7,
ease: 'elastic.out(1, .45)'
}, index * 0.16 + 0.6);
});
gsap.to(parts, {
fill: 'var(--lightblue)',
duration: 2,
stagger: {
each: 0.12,
yoyo: true,
repeat: -1
},
ease: 'sine.inOut'
});
gsap.to(parts, {
fill: 'var(--lightpurple)',
duration: 2,
stagger: {
each: 0.12,
from: 'end',
yoyo: true,
repeat: -1
},
ease: 'sine.inOut',
delay: 2
});
logo.addEventListener('mouseenter', function(){
gsap.to(parts, {
y: -4,
scale: 1.04,
duration: 0.45,
stagger: 0.05,
ease: 'power3.out'
});
});
logo.addEventListener('mouseleave', function(){
gsap.to(parts, {
y: 0,
scale: 1,
rotation: 0,
duration: 0.8,
stagger: 0.05,
ease: 'elastic.out(1, .45)'
});
});
}