Last active
June 12, 2023 21:45
-
-
Save eurocat2k/8c0ce08ca26a6ba458258bc482533405 to your computer and use it in GitHub Desktop.
VSCROLL SELECTION MENU
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
$(function(){ | |
console.log(`ready....`); | |
$vscroll = $('.vscroll_container'); | |
$vscroll.vScrolled({ | |
visible: 7 // number of visible list items in the scrolled menu | |
}); | |
$(document).on('onVSelect', {selected: 0}, function (ev, fl) { ev.data.selected = fl; console.log(`FL${fl} [${$vscroll.selected()}]`, ev) }); | |
}); |
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>VSCROLL</title> | |
<link rel="shortcut icon" href="#" type="image/x-icon"> | |
<link rel="stylesheet" href="css/style.css"> | |
</head> | |
<body> | |
<div class="wrapper"> | |
<!-- FIELD CONTAINS STATIC AND VSCROLLED SELECTION WINDOWS --> | |
<div class="cfl_value_container"> | |
<div class="cfl_static_value">000</div> | |
<div class="vscroll_container"> | |
<div class="vscroll_strip"> | |
<div class="vscroll_item">400</div> | |
<div class="vscroll_item">395</div> | |
<div class="vscroll_item">390</div> | |
<div class="vscroll_item">385</div> | |
<div class="vscroll_item">380</div> | |
<div class="vscroll_item">375</div> | |
<div class="vscroll_item">370</div> | |
<div class="vscroll_item">365</div> | |
<div class="vscroll_item">360</div> | |
<div class="vscroll_item">355</div> | |
<div class="vscroll_item">350</div> | |
<div class="vscroll_item">345</div> | |
<div class="vscroll_item">340</div> | |
<div class="vscroll_item">335</div> | |
<div class="vscroll_item">330</div> | |
<div class="vscroll_item vs_selected">325</div> | |
<div class="vscroll_item">320</div> | |
<div class="vscroll_item">315</div> | |
<div class="vscroll_item">310</div> | |
<div class="vscroll_item">305</div> | |
<div class="vscroll_item">300</div> | |
<div class="vscroll_item">295</div> | |
<div class="vscroll_item">290</div> | |
</div> | |
</div> | |
</div> | |
<!-- END --> | |
</div> | |
</body> | |
<script defer src="js/jquery.min.js"></script> | |
<script defer src="js/jquery-ui.min.js"></script> | |
<script defer src="js/vscroll-cfl.min.js"></script> | |
<script defer src="js/app.min.js"></script> | |
</html> |
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
/* | |
* html5resetcss | |
*/ | |
html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent} | |
body{line-height:1} | |
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block} | |
nav ul{list-style:none} | |
blockquote,q{quotes:none} | |
blockquote:before,blockquote:after,q:before,q:after{content:none} | |
a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent} | |
ins{background-color:#ff9;color:#000;text-decoration:none} | |
mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold} | |
del{text-decoration:line-through} | |
abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help} | |
table{border-collapse:collapse;border-spacing:0} | |
hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0} | |
input,select{vertical-align:middle} | |
/* end */ | |
:root { | |
--vscrollVisible: 7; /* default visible for vscrolled list */ | |
--vscrollWidth: "40px"; /* default width of vscrolled window list and static value container */ | |
--vscrollHeight: "16px"; /* default height of vscrolled window static value container and list item */ | |
--vscrollFontSize: "14px"; /* default font size of vscrolled window items */ | |
--vscrollFontWeight: 500; /* default font weight of vscrolled window text items */ | |
} | |
body { | |
min-height: 100vh; | |
min-width: 100vw; | |
overflow: hidden; | |
font-size: 16px; | |
font-weight: 400; | |
font-family: Arial, Helvetica, sans-serif; | |
} | |
.wrapper { | |
position: absolute; | |
top: 0; | |
left: 0; | |
bottom: 0; | |
right: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
/* active element with static and vertical scrollable selection window */ | |
.cfl_value_container { | |
width: var(--vscrollWidth); | |
height: var(--vscrollHeight); | |
background-color: #ccc; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
cursor: default; | |
} | |
.cfl_static_value { | |
flex: 1; | |
width: var(--vscrollWidth); | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
height: var(--vscrollHeight); | |
} | |
.vscroll_container { | |
position: absolute; | |
width: var(--vscrollWidth); | |
height: calc(var(--vscrollVisible) * 17px); | |
background-color: rgba(0,0,0,.21); | |
overflow: hidden; | |
} | |
.vscroll_container::-webkit-scrollbar {display:none;} | |
.vscroll_container::-moz-scrollbar {display:none;} | |
.vscroll_container::-o-scrollbar {display:none;} | |
.vscroll_container::-google-ms-scrollbar {display:none;} | |
.vscroll_container::-khtml-scrollbar {display:none;} | |
.vscroll_strip { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
row-gap: 1px; | |
} | |
.vscroll_item { | |
background-color: rgba(10, 20, 40, .13); | |
} | |
.vscroll_item:first-child { | |
margin-top: 1px; | |
} | |
.vscroll_item:last-child { | |
margin-bottom: 1px; | |
} | |
.vscroll_item.vs_selected { | |
background-color: rgba(51, 114, 241, 0.63); | |
color: white; | |
} | |
.vscroll_item.vs_selected:hover { | |
background-color: rgba(64, 238, 73, 0.63); | |
color: white; | |
} | |
.vscroll_item:hover { | |
background-color: rgba(241, 209, 51, 0.63); | |
color: rgb(0, 0, 0); | |
} | |
/* end */ |
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
(function (factory) { | |
if (typeof define === 'function' && define.amd) { | |
// AMD. Register as an anonymous module. | |
define(['jquery'], factory); | |
} else if (typeof module === 'object' && module.exports) { | |
// Node/CommonJS | |
module.exports = function( root, jQuery ) { | |
if ( jQuery === undefined ) { | |
// require('jQuery') returns a factory that requires window to | |
// build a jQuery instance, we normalize how we use modules | |
// that require this pattern but the window provided is a noop | |
// if it's defined (how jquery works) | |
if ( typeof window !== 'undefined' ) { | |
jQuery = require('jquery'); | |
} | |
else { | |
jQuery = require('jquery')(root); | |
} | |
} | |
factory(jQuery); | |
return jQuery; | |
}; | |
} else { | |
// Browser globals | |
factory(jQuery); | |
} | |
}(function ($) { | |
$.fn.vScrolled = function (params) { | |
// | |
let self = this; | |
let main_container = $('.cfl_value_container'); | |
let static_value = $('.cfl_static_value'); | |
let selected = $(".vs_selected"); | |
let listElems = $(".vscroll_strip").children(); | |
// handle context menu event on vscroll DOM elements | |
$(main_container).on('contextmenu', function(ev) { | |
ev.preventDefault(); | |
$(self).hide(); | |
$(static_value).show(); | |
return false; | |
}); | |
// data | |
let options = { | |
animate: false, | |
visible: 5, | |
min: 290, | |
max: 400, | |
step: 5 | |
}; | |
let tmp; | |
$.extend(options, params); | |
// make corrections of options | |
tmp = parseInt(options.visible); | |
options.visible = tmp; | |
// - if visible < 5 | |
if (options.visible < 5) { | |
options.visible = 5; | |
} | |
tmp = parseInt(options.step); | |
options.step = tmp; | |
// make corrections: | |
// - if step is 5 or 10 | |
if (options.step >= 10) { | |
options.step = 10; | |
} else if (options.step < 10) { | |
options.step = 5; | |
} | |
// - if max-min / step < visible, extend list toward max to reach the minimum criteria of visible items | |
tmp = Math.min(parseInt(options.min), parseInt(options.max)); | |
options.max = Math.max(parseInt(options.min), parseInt(options.max)); | |
options.min = tmp; | |
if (((options.max - options.min) / options.step) < options.visible) { | |
if (options.visible === 10) { | |
options.step = 5; | |
if (((options.max - options.min) / options.step) < options.visible) { | |
console.log(`Too few elements in the list after reducing step value to ${options.step}: visible = ${options.visible}, number of elements = ${(options.max - options.min) / options.step}`); | |
} | |
} | |
} | |
// private methods | |
function focus() { | |
let scrollTo = $(".vs_selected"); | |
let container = $(".vscroll_container"); | |
let centerPos = $(container).height() / 2 - $(".vscroll_strip").children(1).height() / 2; | |
var position = scrollTo.offset().top - container.offset().top + container.scrollTop(); | |
if (options.animate) { | |
self.animate({ | |
scrollTop: position - centerPos | |
},500); | |
} else { | |
self.scrollTop(position - centerPos); | |
} | |
} | |
function init() { | |
$(static_value).click((e,o) => { | |
$vscroll.show(); | |
}); | |
focus(); | |
// interfaces | |
self.show = _show; | |
self.hide = _hide; | |
self.selected = _selected; | |
// Set new selected | |
function _setSelected(v) { | |
$(listElems).each((e, o) => { | |
let txt = $(o).text(); | |
if (txt === v) { | |
$(o).addClass('vs_selected'); | |
} else { | |
$(o).removeClass('vs_selected'); | |
} | |
}) | |
} | |
// | |
let tmp = 0, mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel"; | |
let container = $(".vscroll_container"); | |
let centerPos = $(container).height() / 2 - $(".vscroll_strip").children(1).height() / 2; | |
$(listElems).each((e, o) => { | |
let v = $(o).text(); | |
$(o).click((evt) => { | |
_setSelected(v); | |
$('.cfl_static_value').text(v); | |
$(document).trigger('onVSelect', [v]); | |
self.hide(); | |
}); | |
}); | |
let divT = selected; | |
let min = $(listElems).last().text(), max = $(listElems).first().text(); | |
$(container).bind(mousewheelevt, function(e){ | |
var evt = window.event || e; | |
evt = evt.originalEvent ? evt.originalEvent : evt; | |
var delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta; | |
let level = $(divT).text(); | |
if(delta<0){ | |
if (level > min) { | |
divT = $(divT).next(); | |
let scrollTo = $(divT); | |
var position = scrollTo.offset().top - container.offset().top + container.scrollTop(); | |
if (options.animate) { | |
self.animate({ | |
scrollTop: position - centerPos | |
}, 5); | |
} else { | |
self.scrollTop(position - centerPos); | |
} | |
} | |
// end new way | |
} else if(delta>0){ | |
if (level < max) { | |
divT = $(divT).prev(); | |
let scrollTo = $(divT); | |
var position = scrollTo.offset().top - container.offset().top + container.scrollTop(); | |
self.animate({ | |
scrollTop: position - centerPos | |
},5); | |
} | |
} | |
return false; | |
}); | |
self.hide(); | |
} | |
// public methods | |
function _show() { | |
$(".cfl_static_value").hide(); | |
$(self).show(); | |
focus(); | |
} | |
function _hide() { | |
$(self).hide(); | |
$(".cfl_static_value").show(); | |
} | |
function _selected(v) { | |
if (typeof v !== 'undefined' && Number.isInteger(v)) { | |
$(".cfl_static_value").text(v); | |
return parseInt(v); | |
} else { | |
let _v = $(".vs_selected").text(); | |
return parseInt(_v); | |
} | |
} | |
// | |
init(); | |
return self; | |
}; | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
VSCROLLED MENU jQuery plugin
For Altitude selection menu in the track label
As you can see the scripts are minified and you need to have jquery and jquery-ui available before use this plugin.