• First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  • First
  • Second
  • Third
  • Fourth
  •             
            
    <div class="common-picker-container">
      <cylinder-picker class="common-picker">
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" infinite>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" disabled>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" curvature="15" value="2">
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" curvature="20" value="2">
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" curvature="25" value="2">
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" curvature="30" value="2">
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
      <cylinder-picker class="common-picker" curvature="35" value="2">
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Fourth</li>
      </cylinder-picker>
    </div>
            
    
                
            
    <div class="input-date-picker-container">
      <input type="date" class="input-date-picker">
    </div>
    <div class="date-picker-box">
      <div class="date-picker-container">
        <cylinder-picker class="month-picker">
        </cylinder-picker>
        <cylinder-picker class="date-picker" infinite>
        </cylinder-picker>
        <cylinder-picker class="year-picker">
        </cylinder-picker>
      </div>
      <div class="date-picker-button-container">
        <button class="date-picker-today-button">오늘</button>
        <div>
          <button class="date-picker-select-button">선택</button>
          <button class="date-picker-cancel-button">취소</button>
        </div>
      </div>
    </div>
            
            
                
            
    const monthPicker = document.querySelector('.month-picker');
    const datePicker = document.querySelector('.date-picker');
    const yearPicker = document.querySelector('.year-picker');
    
    const yearPickerPadSize = 7;
    
    const current = new Date();
    const currentMonth = current.getMonth() + 1;
    const currentDate = current.getDate();
    const currentYear = current.getFullYear();
    
    const customDatePicker = document.querySelector('.date-picker-box');
    const inputDate = document.querySelector('.input-date-picker');
    const todayButton = document.querySelector('.date-picker-today-button');
    const selectButton = document.querySelector('.date-picker-select-button');
    const cancelButton = document.querySelector('.date-picker-cancel-button');
    
    let month = currentMonth;
    let date = currentDate;
    let year = currentYear;
    
    const langFull = navigator.language || navigator.userLanguage;
    const langComponents = langFull.split('-');
    const langLong = [langComponents[0], langComponents[1]].filter(component => component).join('_');
    const langShort = langComponents[0];
    
    function initMonthPicker() {
        monthPicker.list = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
        monthPicker.value = currentMonth - 1;
        monthPicker.addEventListener('change', onMonthPickerChange);
    }
    
    function initDatePicker() {
        datePicker.list = Array.from({length: getNumberOfDate()}, (_, index) => String(index + 1));
        datePicker.value = currentDate - 1;
        datePicker.addEventListener('change', onDatePickerChange);
    }
    
    function initYearPicker(year = currentYear) {
        yearPicker.list = Array.from({length: 1 + 2 * yearPickerPadSize}, (e, i) => String(year - yearPickerPadSize + i));
        yearPicker.value = yearPickerPadSize;
        yearPicker.addEventListener('change', onYearPickerChange);
    }
    
    function initInputDate() {
        inputDate.onchange = inputDate.oninput = inputDate.onclick = (event) => {
            event.preventDefault();
    
            const dateValue = inputDate.valueAsDate;
            const inputRect = inputDate.getBoundingClientRect();
            const x = inputRect.x + window.scrollX;
            const y = inputRect.y + inputRect.height + window.scrollY;
    
            if (dateValue) {
                setMonth(dateValue.getMonth() + 1);
                setDate(dateValue.getDate());
                setYear(dateValue.getFullYear());
            }
    
            customDatePicker.style.transform = 'translate(' + x + 'px,' + y + 'px)';
            customDatePicker.style.display = 'flex';
        }
    
        todayButton.onclick = () => {
            setMonth(currentMonth);
            setDate(currentDate);
            setYear(currentYear);
        }
    
        selectButton.onclick = () => {
            monthPicker.stopInertia()
            datePicker.stopInertia()
            yearPicker.stopInertia()
            inputDate.value = `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(date).padStart(2, '0')}`
            customDatePicker.style.display = 'none';
        }
    
        cancelButton.onclick = () => {
            monthPicker.stopInertia()
            datePicker.stopInertia()
            yearPicker.stopInertia()
            customDatePicker.style.display = 'none';
        }
    
        switch (langShort) {
            case 'ko':
                todayButton.innerHTML = '오늘';
                selectButton.innerHTML = '선택';
                cancelButton.innerHTML = '취소';
                break;
            case 'ja':
                todayButton.innerHTML = '今日';
                selectButton.innerHTML = '選択';
                cancelButton.innerHTML = 'キャンセル';
                break;
            case 'vi':
                todayButton.innerHTML = 'hôm nay';
                selectButton.innerHTML = 'lựa chọn';
                cancelButton.innerHTML = 'hủy';
                break;
            case 'es':
                todayButton.innerHTML = 'Plantilla:Hoy';
                selectButton.innerHTML = 'Selección';
                cancelButton.innerHTML = 'Cancelar';
                break;
            case 'fr':
                todayButton.innerHTML = 'Aujourd\'hui';
                selectButton.innerHTML = 'Sélection';
                cancelButton.innerHTML = 'Annuler';
                break;
            case 'de':
            case 'gsw':
                todayButton.innerHTML = 'Heute';
                selectButton.innerHTML = 'Auswahl';
                cancelButton.innerHTML = 'Abbrechen';
                break;
            case 'ru':
                todayButton.innerHTML = 'Сегодня';
                selectButton.innerHTML = 'Выбрать';
                cancelButton.innerHTML = 'Отменить';
                break;
            case 'zh':
                switch (langLong) {
                    case 'zh-Hans':
                        todayButton.innerHTML = '今天';
                        selectButton.innerHTML = '选择';
                        cancelButton.innerHTML = '取消';
                        break;
                    case 'zh-Hant':
                        todayButton.innerHTML = '今兒個';
                        selectButton.innerHTML = '選擇';
                        cancelButton.innerHTML = '取消';
                        break;
                }
                break;
            default:
                todayButton.innerHTML = 'Today';
                selectButton.innerHTML = 'Select';
                cancelButton.innerHTML = 'Cancel';
        }
    }
    
    function setMonth(value) {
        monthPicker.stopInertia().then(() => {
            monthPicker.value = value - 1;
            month = value;
            updateDatePicker();
        });
    }
    
    function setDate(value) {
        datePicker.stopInertia().then(() => {
            datePicker.value = value - 1;
            date = value;
        });
    }
    
    function setYear(value) {
        yearPicker.stopInertia().then(() => {
            const index = Array.from(document.querySelector('.year-picker').children).findIndex(child => child.innerText === String(value));
            if (yearPicker.childElementCount - 3 < index || index < 3) {
                initYearPicker(value);
            } else {
                yearPicker.value = index;
            }
            year = value;
            updateDatePicker();
        });
    }
    
    function isLeapYear() {
        return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
    }
    
    function getNumberOfDate() {
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            case 2:
                return isLeapYear() ? 29 : 28;
            default:
                return 30;
        }
    }
    
    function updateDatePicker() {
        datePicker.stopInertia().then(() => {
            const previous = datePicker.value;
            const numberOfDate = getNumberOfDate();
    
            datePicker.list = Array.from({length: numberOfDate}, (_, index) => String(index + 1));
            datePicker.value = Math.min(previous, numberOfDate - 1);
    
            date = Math.min(previous, numberOfDate - 1) + 1;
        });
    }
    
    function onMonthPickerChange(event) {
        month = event.value + 1;
        updateDatePicker();
    }
    
    function onDatePickerChange(event) {
        date = Number(event.elementValue.innerText);
    }
    
    function onYearPickerChange(event) {
        let html = '';
        if (event.value < yearPickerPadSize) {
            const firstChild = yearPicker.firstElementChild;
    
            if (firstChild) {
                const minYear = Number(firstChild.textContent);
                const delta = yearPickerPadSize - event.value;
                for (let i = delta; i > 0; i--) {
                    html += `<li>${minYear - i}</li>`
                }
                yearPicker.innerHTML = html + yearPicker.innerHTML;
                yearPicker.value = yearPicker.value + delta;
            }
        }
    
        if (event.value > yearPicker.length - yearPickerPadSize - 1) {
            const lastChild = yearPicker.lastElementChild;
    
            if (lastChild) {
                const maxYear = Number(lastChild.textContent);
                const delta = event.value - yearPicker.length + yearPickerPadSize + 1;
                for (let i = 1; i < delta; i++) {
                    html += `<li>${maxYear + i}</li>`
                }
                yearPicker.innerHTML += html;
            }
        }
    
        year = Number(event.elementValue.innerText);
        updateDatePicker();
    }
    
    function stopAllInertia() {
        return Promise.all([
            monthPicker.stopInertia(),
            datePicker.stopInertia(),
            yearPicker.stopInertia()
        ]);
    }
    
    initMonthPicker();
    initDatePicker();
    initYearPicker();
    initInputDate();
            
    
  • 7
  • 🍉
  • 💰
  • 7
  • 🍑
  • 🏆
  • 7
  • 🍋
  • 💰
  •             
            
    <cylinder-picker id="slot-machine-3" infinite disabled>
      <li class="seven">7</li>
      <li>🍉</li>
      <li>💰</li>
    </cylinder-picker>
    
    <cylinder-picker id="slot-machine-3" infinite disabled>
      <li class="seven">7</li>
      <li>🍑</li>
      <li>🏆</li>
    </cylinder-picker>
    
    <cylinder-picker id="slot-machine-3" infinite disabled>
      <li class="seven">7</li>
      <li>🍋</li>
      <li>💰</li>
    </cylinder-picker>
    
    <div class="coin"></div>
    <div class="coin"></div>
    <div class="coin"></div>
    <div class="coin"></div>
    <div class="coin"></div>
            
            
                
            
    function throwCoin(
        element,
        forceX = (Math.random() - 0.5) * 600,
        forceY = -500 + (Math.random() - 0.5) * 400,
        gravity = 900 - (Math.random() - 0.5) * 200,
        rotateX = (Math.random() - 0.5) * 60,
        rotateY = (Math.random() - 0.5) * 60
    ) {
        let posX = 0;
        let posY = 0;
        let velocityX = forceX;
        let velocityY = forceY;
        const interval = 16;
        const groundLevel = window.innerHeight - element.clientHeight;
    
        let rotateXEvent = Math.random();
        let rotateYEvent = Math.random();
    
        element.style.opacity = '1';
        element.style.scale = String(Math.random() + 1);
    
        function updatePosition() {
            velocityY += gravity * (interval / 1000);
            posX += velocityX * (interval / 1000);
            posY += velocityY * (interval / 1000);
    
            if (posY > groundLevel) {
                posY = groundLevel;
                velocityY = 0;
                clearInterval(timer);
                element.style.opacity = '0';
                setTimeout(() => {
                    element.style.transform = ``;
                }, 1000);
                return;
            }
    
            rotateX = rotateX - rotateXEvent;
            rotateX = rotateX - rotateYEvent;
            element.style.transform = `translate(${posX}px, ${posY}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
    
            timer = setTimeout(updatePosition, interval);
        }
    
        let timer = setTimeout(updatePosition, interval);
    }
    
    function roll() {
        setTimeout(() => {
            Promise.all(
                [...document.querySelectorAll('[id^=slot-machine]')]
                    .map(slotMachine => {
                        const length = slotMachine.childElementCount;
    
                        if (slotMachine instanceof HTMLCylinderPicker) {
                            return slotMachine.next(Math.floor((Math.random() - 0.5) * 2 * length));
                        }
    
                        return undefined;
                    })
            ).then(slotMachines => {
                const goal = slotMachines
                    .map(slotMachine => {
                        if (slotMachine) {
                            return slotMachine.value;
                        }
                        return undefined;
                    })
                    .every((slotMachine, i, slotMachines) => {
                        return slotMachine !== undefined
                            && slotMachines[0] !== undefined
                            && slotMachine === 0
                            && slotMachine === slotMachines[0];
                    });
    
                if (goal) {
                    document.querySelectorAll('.coin').forEach(coin => {
                        throwCoin(coin);
                    })
                }
            });
    
            roll();
        }, 1000);
    }
    
    roll();