首先呢,我要感谢一下和我配合的设计师同学,给了我一份如此漂亮的时间线设计稿。拿到设计稿后,我们首先要做的是去分析整个作品的结构,及设计意图。当然这些工作我们可以提前完成,在设计师设计的时候进行充分沟通,而当我们动手去实现的时候就更为得心应手了。开始之前,我们还是先看看最终的交互效果:
第一步,分析控件结构,说多了反而容易引起误导,直接看图吧,直观明了:
接下来,我来说说我为什么要这么去划分。简单的说,在我看来分析一个控件的结构,其实就是尝试去发现一些规律性的东西。如上图,在月份栏很明显是在每月第一日的位置上方显示当月标签,因此第一行自然可以独立成一个在特定位置显示月份信息的独立区域。而第二行更明显,将时间线上的每一天从左往右挨个儿显示就行了,很显然这一行上只会出现具体天的数据,所以我也将它独立成一个区域。再往下,我们先看最下面的刻度区域,这里存在一定的迷惑性,由于每月第一天的那条线高度刚好填充满,而两个月的第一天刚好将整条刻度划分成一个一个的小区间,但事实上,我觉得它们其实就是一条横向连通的刻度线,所以应该整个一行是一个整体。最后再来说说灰色、蓝色重叠的那条区域,我们可以把蓝色区域包含在灰色区域之中,也可以分成两个同级的区域重叠在一起。但这里需要注意一点:蓝色区域表明的是一个时间区间,它的水平位置和宽度是随时可变的,所以,考虑到后面定位的方便,未知的需求变化,我更倾向分成两个独立区域重叠起来。
第二步,细化每个区域中的共同点,不同点。月份栏,没有问题,就是在每月第一天的位置显示月份标签,唯一不同的是每月第一天的横坐标(left)。日期栏基本与月份栏情况一致,多一点不同在于实现过程中考虑突出显示【今天】。灰色线很简单,从左到右一拉到底,蓝色线很显然是在选中某个事件标签的时候才会出现,所以期初也不用考虑。最后还是刻度栏相对复杂一点,水平位置上的差异不再多说,每月第一天需要追加高刻度样式,而且为了方便后面与事件标签关联,我们需要在生成刻度的时候,在每个刻度上存上对应的日期。大致就是这样,下面就可以着手编码了。
第三步,搭框架。就好像画素描一样,先勾勒出整个作品的骨架,再慢慢细化。
代码很简单,先创建一个时间线全局容器,再往里面写入第一步和第二步中我们分析出来的几个独立区块,最后想整个时间线放入页面中准备好的节点(wrap)中。
第四步,写静态数据,细节优化。根据前面的分析,各个部分的容器都已经准备就绪,接着就该将各部分应该呈现的内容写入到对应的位置中去了,这一步代码会稍微多些。而且根据自己的需求,可能在某些判断逻辑上会略显不同,先看看我的示例代码吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
var Utils = { // 格式化数字,小于10补前置0 prefixZero: function(num) { return num < 10 ? '0' + num : num; } }; function createTimeline(from, to) { var Timeline, f = typeof from === 'string' ? new Date(from.replace(/-/g, '/')) : from, t = typeof to === 'string' ? new Date(to.replace(/-/g, '/')) : to, timestamp = t - f, day = 24 * 60 * 60 * 1000, today = new Date(), miliStart = f.getTime(), dayCount = Math.floor(timestamp / day) + 1, // 计算时间轴上显示的总天数 offLeft = 12, // 初始日期左边距 offRight = 12, // 结束日期右边距 offDay = 20, // 日与日之间的间距 lineLength = dayCount * offDay + offLeft + offRight; // 计算时间轴的长度 var line = $('<div class="J_TimeLine timeline-slider"></div>'), monthLabel, dayLabel, dayDiff, scaleLabel; line.css({width: lineLength, height: 134}); line.html('<div class="J_MonthLabel month-label"></div>' + '<div class="J_DayLabel day-label"></div>' + '<div class="J_ScaleLine scale-line"></div>' + '<div class="J_DayDiff day-diff"></div>' + '<div class="J_ScaleLabel scale-label"></div>'); monthLabel = line.find('.J_MonthLabel'); dayLabel = line.find('.J_DayLabel'); dayDiff = line.find('.J_DayDiff'); scaleLabel = line.find('.J_ScaleLabel'); for (var i = 0; i < dayCount; i++) { var d = new Date(miliStart + i * day), left = i * offDay + offLeft, monthObj, dayObj, scaleObj; dayObj = $('<span class="J_Day day"></span>'); dayObj.css('left', left - 9); dayObj.html(d.getDate()); // 如果【今天】在时间轴范围内,则强调显示 ܨ设计师设计的时候进行充分沟通,而当我们动手去实现的时候就更为得心应手了。开始之前,我们还是先看看最终的交互效果:
第一步,分析控件结构,说多了反而容易引起误导,直接看图吧,直观明了: 接下来,我来说说我为什么要这么去划分。简单的说,在我看来分析一个控件的结构,其实就是尝试去发现一些规律性的东西。如上图,在月份栏很明显是在每月第一日的位置上方显示当月标签,因此第一行自然可以独立成一个在特定位置显示月份信息的独立区域。而第二行更明显,将时间线上的每一天从左往右挨个儿显示就行了,很显然这一行上只会出现具体天的数据,所以我也将它独立成一个区域。再往下,我们先看最下面的刻度区域,这里存在一定的迷惑性,由于每月第一天的那条线高度刚好填充满,而两个月的第一天刚好将整条刻度划分成一个一个的小区间,但事实上,我觉得它们其实就是一条横向连通的刻度线,所以应该整个一行是一个整体。最后再来说说灰色、蓝色重叠的那条区域,我们可以把蓝色区域包含在灰色区域之中,也可以分成两个同级的区域重叠在一起。但这里需要注意一点:蓝色区域表明的是一个时间区间,它的水平位置和宽度是随时可变的,所以,考虑到后面定位的方便,未知的需求变化,我更倾向分成两个独立区域重叠起来。 第二步,细化每个区域中的共同点,不同点。月份栏,没有问题,就是在每月第一天的位置显示月份标签,唯一不同的是每月第一天的横坐标(left)。日期栏基本与月份栏情况一致,多一点不同在于实现过程中考虑突出显示【今天】。灰色线很简单,从左到右一拉到底,蓝色线很显然是在选中某个事件标签的时候才会出现,所以期初也不用考虑。最后还是刻度栏相对复杂一点,水平位置上的差异不再多说,每月第一天需要追加高刻度样式,而且为了方便后面与事件标签关联,我们需要在生成刻度的时候,在每个刻度上存上对应的日期。大致就是这样,下面就可以着手编码了。 第三步,搭框架。就好像画素描一样,先勾勒出整个作品的骨架,再慢慢细化。 代码很简单,先创建一个时间线全局容器,再往里面写入第一步和第二步中我们分析出来的几个独立区块,最后想整个时间线放入页面中准备好的节点(wrap)中。 第四步,写静态数据,细节优化。根据前面的分析,各个部分的容器都已经准备就绪,接着就该将各部分应该呈现的内容写入到对应的位置中去了,这一步代码会稍微多些。而且根据自己的需求,可能在某些判断逻辑上会略显不同,先看看我的示例代码吧:
|