ScrollList Module2

À̹øÀå¿¡¼­´Â ScrollList Module1¿¡ ½ºÅ©·Ñ ¸®½ºÆ® ±â´ÉºÐ¸®, Áï½ÃÇÔ¼ö ÇÁ·¹ÀÓ Ãß°¡, °ÔÀÓÆеå Ãß°¡¸¦ ÇÏ¿´´Ù.

1. ½ºÅ©·Ñ ¸®½ºÆ® ±â´É ºÐ¸®

scroll_list.js ÆÄÀÏ
function clamp(value, min, max) {
    if(value < min)
        value = min;
    else if(value > max)
        value = max;
        return value;
}


function ScrollList(viewName, focusClassName, selectClassName) {
    this.index = -1;
    this.viewName = viewName;
    this.focusClassName = focusClassName;
    if(selectClassName)
        this.selectClassName = selectClassName;
    else
        this.selectClassName = focusClassName;
    this.view = null;
    this.index = 0;
}

ScrollList.prototype.init = function() {
    this.view = document.getElementById(this.viewName);
    if(this.view.children.length > 0)
        this.view.children[0].classList.add(this.selectClassName);
}

ScrollList.prototype.isFocus = function() {
    let index = this.index;
    if(index < 0)
        return false;
    return this.view.children[index].classList.contains(this.focusClassName);
}

ScrollList.prototype.focus = function(flag) {
    let index = this.index;
    if(flag) {
        this.view.children[index].classList.remove(this.selectClassName);
        this.view.children[index].classList.add(this.focusClassName);
    }
    else {
        this.view.children[index].classList.remove(this.focusClassName);
        this.view.children[index].classList.add(this.selectClassName);
    }
}

ScrollList.prototype.upDownInput = function(delta) {
    let oldIndex = this.index;
    this.index += delta;
    this.index = clamp(this.index, 0, this.view.children.length - 1);
    this.scroll(oldIndex, this.index);
}

ScrollList.prototype.scroll = function(oldIndex, curIndex) {
    let view = this.view;
    let index = this.index;
    if(view.children.length < 2)
        return;
        
    view.children[oldIndex].classList.remove(this.focusClassName);
    view.children[index].classList.add(this.focusClassName);

    var h1 = view.children[0].offsetTop;
    var h2 = view.children[1].offsetTop;
    var itemHeight = h2 - h1;     
    
    var gap = (curIndex+1)*itemHeight - view.scrollTop;
    var move = curIndex - oldIndex;

    if(move > 0 && gap > view.offsetHeight) {
        view.scrollTop = (curIndex+1)*itemHeight - view.offsetHeight;
    }
    
    if  (move < 0 && gap - itemHeight < 0) {
        view.scrollTop = itemHeight*index;
    }
}

2. Áï½ÃÇÔ¼ö ÇÁ·¹ÀÓ Ãß°¡

simpleMain ÇÁ·¹ÀÓ¿÷Àº ½Ì±ÛÅæ ÇÁ·¹ÀÓ°ú ºñ½ÁÇÏ´Ù.
ÀÌ ÇÁ·¹ÀÓ¿÷Àº requestAnimationFrame ·çÇÁ¸¦ ¹«ÇÑÇÏ°Ô µ¹¸é¼­ onIdle, updateGamepad ÇÔ¼ö¸¦ ½ÇÇàÇÑ´Ù.
simple_main.js¸¦ Á÷Á¢ ¼öÁ¤ÇÏ´Â ÀÏÀº ¾øÀ» °ÍÀÌ´Ù.

ÇÁ·¹ÀÓ¿÷À» »ç¿ë ÇÒ·Á¸é ´ÙÀ½ÀÇ ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù.

init: ÇÁ·¹ÀÓ¿÷À» ÃʱâÈ­ ÇÑ´Ù.
setCallbackUpdateGamepad : °ÔÀÓÆеå À̺¥Æ® ó¸® Äݹé ÇÔ¼ö¸¦ µî·ÏÇÑ´Ù.
setCallbackOnIdle : ·çÇÁ Äݹé ÇÔ¼ö¸¦ µî·ÏÇÑ´Ù. °ÔÀÓÆеå À̺¥Æ® ó¸® Äݹé ÇÔ¼ö Àü¿¡ ºÒ¸°´Ù.

simple_main.js
var simpleMain = (function () {
    var updateGamepad = function(){
        //Add logic
        if(Gamepad.click(GamepadKey.A)) {
            console.log('Click "A" key');
        }
        if(Gamepad.click(GamepadKey.B)) {
            console.log('Click "B" key');
        }
    }
    var onIdle = function () {
        //Add logic
    }  
   
    var CallbackUpdateGamepad = updateGamepad;
    function setCallbackUpdateGamepad(callback) {
        CallbackUpdateGamepad = callback;
    }
   
    var CallbackOnIdle = onIdle;
    function setCallbackOnIdle(callback) {
        CallbackOnIdle = callback;
    } 
   
    var onKeyDown = function(e) {
        //Add logic
        if(e.keyCode === '1'.charCodeAt(0)) {
            console.log('Click "1" key');
        }
        else if(e.keyCode === 'A'.charCodeAt(0)) {
            console.log('Click "a" key');
        }
    }     
      
    var listenForGamepad = function () {
        updateLoop = function () {
            CallbackOnIdle();
            if(Gamepad.isActivate()) {
                Gamepad.preUpdate();
                CallbackUpdateGamepad();
                Gamepad.postUpdate();
            }
            requestAnimationFrame(updateLoop);
        };
        updateLoop();
    };

    function addGamepadEvent() {
        window.addEventListener("gamepadconnected", function (e) {
            Gamepad.init();
        });
    }
       
    var addKeyboardEvent = function() {
        document.addEventListener("keydown", onKeyDown);   
    }
   
    function init() {
        //Add logic
        addGamepadEvent();
        addKeyboardEvent();
        listenForGamepad();
    }

    return {
        init: init,
        setCallbackUpdateGamepad: setCallbackUpdateGamepad,
        setCallbackOnIdle: setCallbackOnIdle
    };
})();

3. °ÔÀÓÆеå Ãß°¡, simpleMain ÇÁ·¹ÀÓ¿÷ »ç¿ëÇϱâ

init ÇÔ¼ö¿¡¼­ simpleMainÀ» ÃʱâÈ­ ÇÑ´Ù.
updateGamepad ÇÔ¼ö·Î °ÔÀÓÆеå Äݹé ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù.
onIdle ¹é ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù.

        simpleMain.init();
        simpleMain.setCallbackUpdateGamepad(updateGamepad);   
        simpleMain.setCallbackOnIdle(onIdle);

food_order.js
window.addEventListener('DOMContentLoaded', function(){
    orderMain.init();
});   

var orderMain = (function () {
    let scrollList = new ScrollList('scrolltest', 'focusElement', 'selectElement');
    let scrollListTwo = new ScrollList('scrolltest_two', 'focusElement', 'selectElement');
   
    function updateGamepad() {
        if(Gamepad.click(GamepadKey.A)) {
            toggleScrollList();
            return;           
        }
        let move = Gamepad.moveClick();
        if(move.y) {
            let list = getFocusScrollList();
            if(list)
                list.upDownInput(move.y);
        }
    }

    var getFocusScrollList = function() {
        if(scrollList.isFocus())
            return scrollList;
        if(scrollListTwo.isFocus())
            return scrollListTwo;
        return null;
    }
   
    var toggleScrollList = function() {
        if(scrollList.isFocus()) {
           scrollList.focus(false);
           scrollListTwo.focus(true);
        }
        else {
           scrollList.focus(true);
           scrollListTwo.focus(false);       
        }   
    }
   
    function onKeyDown (e) {   
        if(e.keyCode === 13) {
            toggleScrollList();
            return;
        }   
   
        let move = 0;
        if (e.which == 38) { // up arrow
            move = -1;
        }
        else if (e.which == 40) { // down arrow
            move = 1;
        }
       
        let list = getFocusScrollList();
        if(list)
            list.upDownInput(move);
    }
   
    function onIdle() {
        //console.log("orderMain onIdle");
    }

    var initGui = function() {
        scrollList.init();
        scrollList.focus(true);
        scrollListTwo.init();       
        document.addEventListener("keydown", onKeyDown);       
    }
   
    function init() {
        simpleMain.init();
        simpleMain.setCallbackUpdateGamepad(updateGamepad);   
        simpleMain.setCallbackOnIdle(onIdle);
        initGui();
    }
       
    return {
        init: init,
        onKeyDown: onKeyDown
    };
})();

updateGamepad¿¡¼­ °ÔÀÓÆеå À̺¥Æ® 󸮸¦ ÇÑ´Ù.
Gamepad.click ÇÔ¼ö´Â °ÔÀÓÆеå Å°°¡ ´­·È´ÂÁö °Ë»çÇÑ´Ù.
Gamepad.moveClick ÇÔ¼ö´Â °ÔÀÓÆÐµå ¿ÞÂÊ ½ºÆ½°ú µðÁöÅÐÆе忡 ÀÇÇØ x, yÃàÀ¸·Î À̵¿ÇÑ °ªÀ» Á¤¼ö·Î ¹ÝȯÇÑ´Ù.

    function updateGamepad() {
        if(Gamepad.click(GamepadKey.A)) {
            toggleScrollList();
            return;           
        }
        let move = Gamepad.moveClick();
        if(move.y) {
            let list = getFocusScrollList();
            if(list)
                list.upDownInput(move.y);
        }
    }

food_order.js
gamepad.js
scroll_list.js
simple_main.js
ui_statePattern3.html

Âü°í)
tutorial09.html: ScrollList Module1