ゼロ、
彼らはあなたに簡単な仕事を課しませんでしたが、幸いなことに、これは私が解決することを本当に楽しんでいるものです. 1 日の大部分を費やしましたが、作業は非常に迅速です。
これは、CSS、HTML、および JavaScript で完成した私のテスト ページです。3 つすべてが元の の変更されたバージョンです。
<!DOCTYPE html>
<html>
<head>
<style>
#box {
position: absolute;
width: 400px;
height: 400px;
background-color: #e0e0c0;
top: 100px;
overflow: hidden;
}
#holder {
position: absolute;
width: auto;
height: 400px;
}
.boxes {
position: relative;
width: 398px;
height: 400px;
border-right: 2px solid blue;
float: left;
}
.year {
position: relative;
float: left;
border-right: 1px solid blue;
height: 13px;
min-width: 8px;
}
.year:first-child {
border-left: 1px solid blue;
}
#trackWrapper {
position: relative;
top: 10px;
width: auto;
}
#trackWrapper .track {
position: absolute;
margin: 0;
padding: 0;
list-style-type: none;
top: 21px;
width: auto;
}
#trackWrapper .slider1, #trackWrapper .slider2 {
position:absolute;
}
#trackWrapper .slider1 {
background-color: green;
width: 8px;
height: 20px;
top: 0px;
left: 0px;
}
#trackWrapper .slider2 {
background-color: orange;
width: 12px;
height: 10px;
top: 37px;
left: 220px;
/*
display: none;
*/
}
#msg {
position: absolute;
left: 480px;
top: 80px;
height: 1.0em;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
function log(x){
var logSwitch = false;
if(logSwitch) { console.log(x); }
}
//Put numbers in the boxes for testing
$(".boxes").each(function(i) {
$(this).text(i);
});
function courseFineSlider($trackWrapper, $holder, sensitivityDivider) {
var $slider1 = $trackWrapper.find(".slider1"),
$slider2 = $trackWrapper.find(".slider2"),
$track = $trackWrapper.find(".track"),
$boxes = $(".boxes"),
$year = $(".year");
var $slider = null;
var trackLength = $track.width();// - $year.width() / 2;
var startX = null;
var sliderOffSet = null;
var _pos1 = 0;
var ePos = 0;
sensitivityDivider = (!sensitivityDivider) ? 10 : sensitivityDivider;
$holder.width($boxes.outerWidth() * $boxes.length);
var holderScale = $boxes.outerWidth() * ($boxes.length - 1);
function hold(e) {
log('hold');
e.preventDefault();
$slider = $(e.target);
$(window).on('mousemove', $slider, move);
startX = e.clientX;
sliderOffSet = parseInt($slider.css('left'));
_pos1 = getPos($slider1);
e.returnValue = false;
}
function release(e) {
if(!$slider) return;
log('release');
if($slider.get(0) === $slider2.get(0)) {//if it's the orange slider
setPos($slider1, ePos);//adjust green according to any movement in orange
setPos($slider2, 0.5, true);//recenter the orange slider
}
$slider = null;
$(window).off('mousemove');
}
function move(e) {
//console.log('move');
e.preventDefault();
var trueSliderX = e.pageX - $trackWrapper.get(0).offsetLeft;
setPos($slider, applyLimits(0, trueSliderX / trackLength, 1));
//$holder.css('left', shape(sliderPos()) + 'px'); // *** totally linear ***
$holder.css('left', -holderScale * shape2(sliderPos()) + 'px'); // *** non-linear - slows down at the decade boundaries ***
}
// *** Equations ***
function sliderPos() {
var pos1 = getPos($slider1);//green position (0 to 1)
var pos2 = getPos($slider2);//orange position (0 to 1)
if($slider.get(0) === $slider1.get(0)) {//if it's the green slider
ePos = applyLimits(0, (pos1 + (pos2 - 0.5) / sensitivityDivider), 1);
}
else {
ePos = applyLimits(0, (_pos1 + (pos2 - 0.5) / sensitivityDivider), 1);
}
return ePos;//effective position of green, taking orange into account
}
var LINEAR = function(x1, y1) {//Namespace pattern to keep the $(function(){...}) closure uncluttered
function Line(m, c) {//Constructor
this.calc = function(x) {
return m * x + c;
};
}
var m1 = y1/x1;
var m2 = (1-y1)/(1-x1);
var c1 = 0;
var c2 = y1 - m2 * x1;
return {
x1: x1,
y1: y1,
line_1: new Line(m1, c1),
line_2: new Line(m2, c2)
};
}(0.7, 0.90);// change these params as required.
/*
* First param: Determines the leading edge of the "sluggish zone". 0.7 is about right for the test data.
* Second param: Determines the height of the two slopes at their intersection. ie. where steep changes to shallow.
* Try playing with the second param in the range 0.7 (completely linear) to 0.999999 (comatose).
* If the value of the 2nd param is set to something less than the first param, then the "zone" will be more sensitive rather than more sluggish.
*/
// *** Shaping functions ***
function shape(x) {
return x;
}
function shape2(x) { //0...1
var c = 4, //The number of cycles (decades)
n = x * c,//0...4
d = Math.floor(n),//"decade" //0, 1, 2, 3, 4
r = n - d,//remainder //0
y = (r < LINEAR.x1) ? LINEAR.line_1.calc(r) : LINEAR.line_2.calc(r),
rtn = (y + d) / c;//unscaled return value
/*
inspect([
'x: ' + x.toFixed(2),
'<br>n: ' + n.toFixed(5),
'<br>d: ' + d,
'<br>r: ' + r.toFixed(2),
'<br>y: ' + y.toFixed(2),
'<br>rtn: ' + rtn.toFixed(2)]);
*/
return rtn;
}
// *** Utilitiy functions ***
function applyLimits(min, x, max) {
return Math.max(min, Math.min(max, x));
}
function getPos($sl) {
return (parseInt($sl.css('left')) + $sl.width() / 2) / trackLength;
}
function setPos($sl, val, animate) {
val = (val * trackLength) - ($sl.width() / 2);
if(animate) { $sl.animate({left: val}, 'fast'); }
else { $sl.css({left: val}); }
}
function inspect(arr){ //for debugging
$("#msg").html(arr.join(', '));
}
setPos($slider1, 0);//center the green slider
setPos($slider2, 0.5);//center the orange slider
$slider1.on('mousedown', hold);
$slider2.on('mousedown', hold);
$(window).on('mouseup', release);
}
var x = new courseFineSlider($("#trackWrapper"), $('#holder'), 5);
});
</script>
</head>
<body>
<div id="msg"></div>
<div id="trackWrapper">
<div class='slider1'></div>
<div class='slider2'></div>
<ul class='track'>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'>2000</li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'>2010</li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'>2020</li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'></li>
<li class='year'>2030</li>
</ul>
</div>
<div id='box'>
<div id="holder">
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
</div>
</div>
</body>
</html>
デモ
あなたのデザインブリーフから「スラグゾーン」を実装し、オレンジ色のセカンダリスライダーを実装したことがわかります。これは、私の元のコンセプトとは少し異なります (算術および変数のスコープがかなり強くなりました)。オレンジ色のスライダーなしで実行するには、スタイル シートで#slider2
スタイルを設定するだけです。display:none
JavaScript を変更する必要はありません。ある日、デザイナーが大失敗をしたことに気付いたときに、オレンジ氏を明らかにすることができます.
どのように機能するかを詳しく説明する時間はありませんが、コードにはたくさんのコメントがあります。
スクリプトの下部にある名前空間の下を見LINEAR
て、「低迷ゾーン」の位置と感度を制御する方法を確認してください。
他に説明が必要な場合はお知らせください。