Skip to content

Instantly share code, notes, and snippets.

@yuezk
Last active August 29, 2015 14:11
Show Gist options
  • Save yuezk/215867271e9c564ea4ab to your computer and use it in GitHub Desktop.
Save yuezk/215867271e9c564ea4ab to your computer and use it in GitHub Desktop.
A Circular Date Picker
<div id="date-picker">
</div>
<p style="font-size: 22px; text-align: center;">难点在于圆环的实现,请参见<a href="http://codepen.io/yuezk/pen/gbMEwy" target="_blank">http://codepen.io/yuezk/pen/gbMEwy</a></p>
var years = [2009, 2010, 2011, 2012];
var datePicker = $('#date-picker');
function buildWheel(items, cls) {
var wheel = $('<div class="wheel"></div>');
var group = $('<div class="sector-group"></div>');
items.forEach(function (item, i) {
var sector = $('<div class="sector" data-value="' + item + '"></div>');
//var sector = $('<div class="sector" data-value="' + item + '"><div class="text">' + item + '</div></div>');
group.append(sector);
});
wheel.append(group).addClass('wheel-' + cls);
return wheel;
}
function buildYears() {
datePicker.append(buildWheel(years, 'year'));
}
function buildMonths() {
var month = [];
while (month.length < 12) {
month[month.length] = month.length + 1;
}
datePicker.append(buildWheel(month, 'month'));
}
function buildWeek() {
var week = 'Mon,Tue,Wes,Thu,Fri,Sat,Sun'.split(',');
datePicker.append(buildWheel(week, 'week'));
}
function buildDays() {
var days = [];
while(days.length < 31) {
days[days.length] = days.length + 1;
}
datePicker.append(buildWheel(days, 'day'));
}
function bindEvents() {
datePicker.on('click', '.sector', function (e) {
e.preventDefault();
var $this = $(this);
$this.addClass('selected').siblings().removeClass('selected');
var value = datePicker.find('.selected').map(function () {
return $(this).attr('data-value');
}).get().join('-');
alert(value);
});
}
function init () {
buildYears();
buildMonths();
buildWeek();
buildDays();
bindEvents();
}
init();
@import "compass/css3";
@charset "utf-8";
// Depends on SASS and Compass
body { font-size: 14px; font-family: arial; }
@mixin pos($number) {
top: $number;
right: $number;
bottom: $number;
left: $number;
}
// 圆盘外围宽度
$main-width: 600px;
// 圆环宽度
$ring-width: 35px;
// 开始颜色
$color: rgb(147, 112, 219);
// 圆盘的配置列表
$wheels: (year, 4), (month, 12), (week, 7), (day, 31);
#date-picker {
position: relative;
width: $main-width;
height: $main-width;
margin: 0 auto;
}
.wheel {
position: absolute;
border-radius: 50%;
overflow: hidden;
box-sizing: border-box;
border: 1px solid #eee;
&:after {
/*display: none;*/
@include pos($ring-width);
content: '\20';
position: absolute;
border-radius: 50%;
background: #fff;
}
&:last-child:after {
z-index: 1;
}
}
.sector-group {
@include pos(0);
position: absolute;
border-radius: 50%;
}
.sector {
position: absolute;
left: 50%;
// 防止层重叠影响点击事件,这样做可以少加一个标签,用`:after`就够了
// IE9/10不支持该属性
// @see http://caniuse.com/#search=pointer-event
pointer-events: none;
&:before {
@include pos(0);
position: absolute;
content: '\20';
box-sizing: border-box;
transform-origin: 50% 100%;
border-style: solid;
border-color: transparent;
}
&:after {
content: attr(data-value);
position: absolute;
z-index: 1;
top: 0;
bottom: 0;
left: 50%;
width: 62%;
padding-top: 8px;
transform-origin: 50% 100%;
text-align: center;
cursor: pointer;
pointer-events: all;
}
}
@each $wheel, $count in $wheels {
$i: index($wheels, ($wheel, $count));
// 单个圆盘的宽度
$wheel-width: $main-width - ($i - 1) * $ring-width * 2;
// 圆盘的半径
$r: $wheel-width / 2;
// 扇形的圆心角
$angle: 360deg / $count;
// 弦长,`tan()`是 Compass 提供的一个函数,依赖 Compass
$sector-width: tan($angle / 2) * $r * 2;
.wheel-#{$wheel} {
top: $ring-width * ($i - 1);
left: $ring-width * ($i - 1);
width: $wheel-width;
height: $wheel-width;
.sector {
width: $sector-width;
height: $r;
margin-left: -$sector-width / 2;
&:before {
border-width: $r ($sector-width / 2) 0;
}
// 循环每一个扇形
@for $j from 1 through $count {
// 偏转角度
$rotate-angle: -$angle * ($j - 1) - $angle / 2;
&:nth-child(#{$j}):before {
transform: rotate($rotate-angle);
border-top-color: scale-color($color, $lightness: percentage(0.8 * ($j - 1) / $count));
}
&:nth-child(#{$j}):after {
// 精确计算宽度,以扩大点击的有效区域,sin()函数依赖 Compass
width: ($r - $ring-width) * sin($angle / 2) * 2;
transform: translateX(-50%) rotate($rotate-angle);
}
} // end @for
} // end .sector
} // end .wheel-#{}
} // end @each
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment