A circular date picker with pure CSS
Last active
August 29, 2015 14:11
-
-
Save yuezk/215867271e9c564ea4ab to your computer and use it in GitHub Desktop.
A Circular Date Picker
This file contains hidden or 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
<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> |
This file contains hidden or 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 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(); |
This file contains hidden or 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
@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