最近想調整之前做的在有限空間內的選單內容切換元件
參考的項目來源則是Excel的下方頁籤選擇器
Excel這類廣泛使用的軟體,設計都還滿值得參考的
一方面是Microsoft將它做得滿直覺的
另一方面則是一般大眾也被訓練到能接受它的操作流程
實作的成果如下:
點擊下一項時,選單容器會自動往右邊捲動一個不定長度的子元件的距離
長按著下一項按鈕不放,則會持續往右捲動到底
程式碼如下
透過requestAnimationFrame避免動畫進行時碰到掉幀
這樣就是一段很流暢的移動效果了
參考的項目來源則是Excel的下方頁籤選擇器
Excel這類廣泛使用的軟體,設計都還滿值得參考的
一方面是Microsoft將它做得滿直覺的
另一方面則是一般大眾也被訓練到能接受它的操作流程
實作的成果如下:
點擊下一項時,選單容器會自動往右邊捲動一個不定長度的子元件的距離
長按著下一項按鈕不放,則會持續往右捲動到底
程式碼如下
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var longPressAct; | |
function moveElements(container, direction) { | |
var childElements = container.children, | |
maxScrollLeft = container.scrollWidth - container.clientWidth, | |
currentScrollLeft = container.scrollLeft, | |
moveRight = direction === 'R'; | |
//boarder line check | |
if (moveRight && currentScrollLeft === maxScrollLeft) return; | |
else if (!moveRight && currentScrollLeft === 0) return; | |
var accumulatedWidth = 0, | |
widthArray = [], | |
currentFrontTabIndex = 0; | |
for (var i = 0, max = childElements.length; i < max; i++) { | |
if(childElements[i].style.display==='none') continue; | |
accumulatedWidth += childElements[i].offsetWidth; | |
widthArray.push(accumulatedWidth); | |
if (currentScrollLeft >= accumulatedWidth) { | |
currentFrontTabIndex++; | |
} | |
} | |
var moveScale = 6; | |
var scrollRange, moveFunc, remainder; | |
if (moveRight) { | |
scrollRange = widthArray[currentFrontTabIndex] - (currentFrontTabIndex > 0 ? widthArray[currentFrontTabIndex-1] : 0); | |
remainder = scrollRange % moveScale; | |
moveFunc = function () { | |
if (scrollRange >= moveScale) { | |
scrollRange -= moveScale; | |
container.scrollLeft += moveScale; | |
requestAnimationFrame(moveFunc); | |
} else { | |
scrollRange -= remainder; | |
container.scrollLeft += remainder; | |
} | |
}; | |
} else { | |
scrollRange = currentScrollLeft - (currentFrontTabIndex >= 2 ? widthArray[currentFrontTabIndex-2] : 0); | |
remainder = scrollRange % moveScale; | |
moveFunc = function () { | |
if(remainder!==0){ | |
scrollRange -= remainder; | |
container.scrollLeft -= remainder; | |
remainder=0; //set remainder to zero to make the calculation easier. | |
requestAnimationFrame(moveFunc); | |
} | |
else if (scrollRange >= 0) { | |
scrollRange -= moveScale; | |
container.scrollLeft -= moveScale; | |
if (0 !== scrollRange){ | |
requestAnimationFrame(moveFunc); | |
} | |
} | |
}; | |
} | |
requestAnimationFrame(moveFunc); | |
longPressAct = setTimeout(function () { | |
moveElements(container, direction); | |
}, 150); | |
var mouseUpCtrl = function () { | |
clearTimeout(longPressAct); | |
window.removeEventListener('mouseup', mouseUpCtrl); | |
}; | |
window.addEventListener('mouseup', mouseUpCtrl); | |
} |
透過requestAnimationFrame避免動畫進行時碰到掉幀
這樣就是一段很流暢的移動效果了
留言
張貼留言