From 1c7ddfc8a9823d4b6b9a48d6f8908078dcfc1bbd Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sat, 20 Mar 2021 13:50:01 +0800 Subject: [PATCH] finish dialPlate --- src/static/i18n/strings_en-US.properties | 1 - src/static/i18n/strings_zh-CN.properties | 1 - src/static/js/datetimepicker.js | 231 ++++++++++++++++------- src/static/js/page/calendar.js | 13 +- src/static/tmpl/datetimepicker.tmpl | 2 +- src/templates/calendar.html | 44 +++-- 6 files changed, 192 insertions(+), 100 deletions(-) diff --git a/src/static/i18n/strings_en-US.properties b/src/static/i18n/strings_en-US.properties index ca927e0..068a053 100644 --- a/src/static/i18n/strings_en-US.properties +++ b/src/static/i18n/strings_en-US.properties @@ -63,7 +63,6 @@ ccn-i18n-login-form-login=Login ccn-i18n-todo-todoList=Todo list -ccn-i18n-calendar-calendar-jump=Jump ccn-i18n-calendar-calendar-today=Today ccn-i18n-calendar-calendar-add=Add... ccn-i18n-calendar-calendar-stripedEvents={0} items diff --git a/src/static/i18n/strings_zh-CN.properties b/src/static/i18n/strings_zh-CN.properties index a4b7eb2..1cce1fa 100644 --- a/src/static/i18n/strings_zh-CN.properties +++ b/src/static/i18n/strings_zh-CN.properties @@ -63,7 +63,6 @@ ccn-i18n-login-form-login=登录 ccn-i18n-todo-todoList=待办列表 -ccn-i18n-calendar-calendar-jump=转到 ccn-i18n-calendar-calendar-today=今天 ccn-i18n-calendar-calendar-add=添加... ccn-i18n-calendar-calendar-stripedEvents=共{0}项 diff --git a/src/static/js/datetimepicker.js b/src/static/js/datetimepicker.js index b5a68a1..9c3df4c 100644 --- a/src/static/js/datetimepicker.js +++ b/src/static/js/datetimepicker.js @@ -6,17 +6,21 @@ var ccn_datetimepicker_tabType = { minute: 4 }; -var ccn_datetimepicker_dialPlateRadius = 200; -var ccn_datetimepicker_dialPlateHalfRadius = ccn_datetimepicker_dialPlateRadius / 2; +var ccn_datetimepicker_dialPlateWidth = 200; +var ccn_datetimepicker_dialPlateRadius = ccn_datetimepicker_dialPlateWidth / 2; var ccn_datetimepicker_dialPlateHourInnerPercent = 0.6; var ccn_datetimepicker_dialPlateHourOutterPercent = 0.8; var ccn_datetimepicker_dialPlateHourDistinguishPercent = 0.7; var ccn_datetimepicker_dialPlateMinutePercent = 0.8; +var ccn_datetimepicker_dialPlateHourResolution = Math.PI * 2 / 12; +var ccn_datetimepicker_dialPlateMinuteResolution = Math.PI * 2 / 60; var ccn_datetimepicker_mode = undefined; -var ccn_datetimepicker_pickerIndex = undefined; var ccn_datetimepicker_isUTC = undefined; -var ccn_datetimepicker_callbackFunc = undefined; +var ccn_datetimepicker_pickerIndex = undefined; + +var ccn_datetimepicker_enableMinuteDrag = false; +var ccn_datetimepicker_enableHourDrag = false; var ccn_datetimepicker_internalDateTime = new Date(); var ccn_datetimepicker_displayCacheDateTime = new Date(); @@ -70,13 +74,25 @@ function ccn_datetimepicker_Insert() { $('#ccn-datetimepiacker-panelMonth-table > div > div').click(ccn_datetimepicker_ClickMonth); $('#ccn-datetimepiacker-panelDay-table > div:nth-child(n+1) > div').click(ccn_datetimepicker_ClickDay); + $('#ccn-datetimepicker-panelHour') + .mousedown(ccn_datetimepicker_StartDragHour) + .mousemove(ccn_datetimepicker_DraggingHour) + .mouseup(ccn_datetimepicker_StopDragHour); + + $('#ccn-datetimepicker-panelMinute') + .mousedown(ccn_datetimepicker_StartDragMinute) + .mousemove(ccn_datetimepicker_DraggingMinute) + .mouseup(ccn_datetimepicker_StopDragMinute); + + $('#ccn-datetimepicker-btnConfirm').click(ccn_datetimepicker_Confirm); + $('#ccn-datetimepicker-btnCancel').click(ccn_datetimepicker_Cancel); + } -function ccn_datetimepicker_Modal(mode, pickerIndex, isUTC, callbackFunc) { +function ccn_datetimepicker_Modal(mode, pickerIndex, isUTC) { ccn_datetimepicker_mode = mode; - ccn_datetimepicker_pickerIndex = pickerIndex; ccn_datetimepicker_isUTC = isUTC; - ccn_datetimepicker_callbackFunc = callbackFunc; + ccn_datetimepicker_pickerIndex = pickerIndex; ccn_datetimepicker_internalDateTime = ccn_datetimepicker_Get(pickerIndex, false); @@ -96,7 +112,22 @@ function ccn_datetimepicker_Modal(mode, pickerIndex, isUTC, callbackFunc) { } ccn_datetimepicker_SwitchTab(mode); - $('#ccn-datetimepicker-modal').show(); + $('#ccn-datetimepicker-modal').addClass('is-active'); +} + +function ccn_datetimepicker_Confirm() { + ccn_datetimepicker_Set( + ccn_datetimepicker_pickerIndex, + ccn_datetimepicker_internalDateTime, + ccn_datetimepicker_isUTC, + ccn_datetimepicker_mode + ); + + $('#ccn-datetimepicker-modal').removeClass('is-active'); +} + +function ccn_datetimepicker_Cancel() { + $('#ccn-datetimepicker-modal').removeClass('is-active'); } // ========================================= internal func @@ -133,11 +164,11 @@ function ccn_datetimepicker_SwitchTab(newTab) { function ccn_datetimepicker_RefreshDisplay(tab) { // header should be refreshed entirely - $('ccn-datetimepicker-datetime-year').text(ccn_datetimepicker_internalDateTime.getFullYear()); - $('ccn-datetimepicker-datetime-month').text(ccn_datetimepicker_internalDateTime.getMonth() + 1); - $('ccn-datetimepicker-datetime-day').text(ccn_datetimepicker_internalDateTime.getDate()); - $('ccn-datetimepicker-datetime-hour').text(ccn_datetimepicker_internalDateTime.getHours()); - $('ccn-datetimepicker-datetime-minute').text(ccn_datetimepicker_internalDateTime.getMinutes()); + $('#ccn-datetimepicker-datetime-year').text(ccn_datetimepicker_internalDateTime.getFullYear()); + $('#ccn-datetimepicker-datetime-month').text(ccn_datetimepicker_internalDateTime.getMonth() + 1); + $('#ccn-datetimepicker-datetime-day').text(ccn_datetimepicker_internalDateTime.getDate()); + $('#ccn-datetimepicker-datetime-hour').text(ccn_datetimepicker_internalDateTime.getHours()); + $('#ccn-datetimepicker-datetime-minute').text(ccn_datetimepicker_internalDateTime.getMinutes()); // refresh tab according to specific `tab` switch(tab) { @@ -168,7 +199,7 @@ function ccn_datetimepicker_RefreshDisplay(tab) { $('#ccn-datetimepiacker-panelMonth-table > div > div').attr('picked', 'false'); if (ccn_datetimepicker_internalDateTime.getFullYear() == ccn_datetimepicker_displayCacheDateTime.getFullYear()) { var month = ccn_datetimepicker_internalDateTime.getMonth(); - $('#ccn-datetimepiacker-panelMonth-table > div:nth-child({0}) > div:nth-child({1})'.format(Math.floor(month / 4), month % 4)) + $('#ccn-datetimepiacker-panelMonth-table > div:nth-child({0}) > div:nth-child({1})'.format(Math.floor(month / 4) + 1, (month % 4) + 1)) .attr('picked', 'true'); } @@ -203,9 +234,9 @@ function ccn_datetimepicker_RefreshDisplay(tab) { var gottenHour = ccn_datetimepicker_displayCacheDateTime.getHours(); var newX = Math.cos((15 - gottenHour) * Math.PI * 2 / 60); var newY = Math.sin((15 - gottenHour) * Math.PI * 2 / 60); - var radius = ccn_datetimepicker_dialPlateHalfRadius * (gottenHour < 12 ? ccn_datetimepicker_dialPlateHourOutterPercent : ccn_datetimepicker_dialPlateHourInnerPercent); - newX = newX * radius + ccn_datetimepicker_dialPlateHalfRadius; - newY = (-newY * radius) + ccn_datetimepicker_dialPlateHalfRadius; + var radius = ccn_datetimepicker_dialPlateRadius * (gottenHour < 12 ? ccn_datetimepicker_dialPlateHourOutterPercent : ccn_datetimepicker_dialPlateHourInnerPercent); + newX = newX * radius + ccn_datetimepicker_dialPlateRadius; + newY = (-newY * radius) + ccn_datetimepicker_dialPlateRadius; $('#ccn-datetimepicker-panelHour > line') .attr('x2', newX) @@ -220,9 +251,9 @@ function ccn_datetimepicker_RefreshDisplay(tab) { var gottenMinute = ccn_datetimepicker_displayCacheDateTime.getMinutes(); var newX = Math.cos((15 - gottenMinute) * Math.PI * 2 / 60); var newY = Math.sin((15 - gottenMinute) * Math.PI * 2 / 60); - var radius = ccn_datetimepicker_dialPlateHalfRadius * ccn_datetimepicker_dialPlateMinutePercent; - newX = newX * radius + ccn_datetimepicker_dialPlateHalfRadius; - newY = (-newY * radius) + ccn_datetimepicker_dialPlateHalfRadius; + var radius = ccn_datetimepicker_dialPlateRadius * ccn_datetimepicker_dialPlateMinutePercent; + newX = newX * radius + ccn_datetimepicker_dialPlateRadius; + newY = (-newY * radius) + ccn_datetimepicker_dialPlateRadius; $('#ccn-datetimepicker-panelMinute > line') .attr('x2', newX) @@ -253,15 +284,27 @@ function ccn_datetimepicker_Str2TabType(strl) { } function ccn_datetimepicker_PrevNextYear(isPrev) { + ccn_datetimepicker_displayCacheDateTime.setFullYear( + ccn_datetimepicker_displayCacheDateTime.getFullYear() + (isPrev ? -12 : 12)); + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_displayCacheDateTime); + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.year); } function ccn_datetimepicker_PrevNextMonth(isPrev) { - + ccn_datetimepicker_displayCacheDateTime.setFullYear( + ccn_datetimepicker_displayCacheDateTime.getFullYear() + (isPrev ? -1 : 1)); + + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_displayCacheDateTime); + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.month); } function ccn_datetimepicker_PrevNextDay(isPrev) { - + ccn_datetimepicker_displayCacheDateTime.setMonth( + ccn_datetimepicker_displayCacheDateTime.getMonth() + (isPrev ? -1 : 1)); + + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_displayCacheDateTime); + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.day); } function ccn_datetimepicker_ClickYear() { @@ -269,82 +312,125 @@ function ccn_datetimepicker_ClickYear() { if (ele.attr('data') == '') return; ccn_datetimepicker_internalDateTime.setFullYear(parseInt(ele.attr('data'))); + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime); + if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.year) ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.month); + else + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.year); } function ccn_datetimepicker_ClickMonth() { var ele = $(this); if (ele.attr('data') == '') return; - ccn_datetimepicker_internalDateTime.setMonth(parseInt(ele.attr('data'))); + ccn_datetimepicker_internalDateTime.setFullYear( + ccn_datetimepicker_displayCacheDateTime.getFullYear(), + parseInt(ele.attr('data')) + ); + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime); + if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.month) ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.day); + else + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.month); } function ccn_datetimepicker_ClickDay() { var ele = $(this); if (ele.attr('data') == '') return; - ccn_datetimepicker_internalDateTime.setDate(parseInt(ele.attr('data'))); + ccn_datetimepicker_internalDateTime.setFullYear( + ccn_datetimepicker_displayCacheDateTime.getFullYear(), + ccn_datetimepicker_displayCacheDateTime.getMonth(), + parseInt(ele.attr('data')) + ); + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime); + if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.day) ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.hour); + else + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.day); } -/* -function ccn_datetimepicker_Init() { - var nowtime = new Date(); +function ccn_datetimepicker_StartDragHour() { ccn_datetimepicker_enableHourDrag = true; } +function ccn_datetimepicker_DraggingHour(e) { + var offset = $('#ccn-datetimepicker-panelHour').offset(); + var x = e.pageX - offset.left - ccn_datetimepicker_dialPlateRadius; + var y = -(e.pageY - offset.top - ccn_datetimepicker_dialPlateRadius); - $('.datetimepicker-year').attr('min', ccn_datetime_MIN_YEAR) - .attr('max', ccn_datetime_MAX_YEAR) - .attr('step', 1) - .val(nowtime.getFullYear()) - .bind('input propertychange', ccn_datetimepicker_Sync); + var distance = Math.sqrt(x * x + y * y); + var angle = Math.asin(y / distance); + if (x < 0) angle = Math.PI - angle; // correct negative x axis angle - $('.datetimepicker-month').attr('min', 1) - .attr('max', 12) - .attr('step', 1) - .val(nowtime.getMonth() + 1) - .bind('input propertychange', ccn_datetimepicker_Sync); + angle += (ccn_datetimepicker_dialPlateHourResolution / 2); // correct offset + if (angle > Math.PI * 2) + angle -= Math.PI * 2; - $('.datetimepicker-day').attr('min', 1) - .attr('step', 1) - .each(function(){ - ccn_datetimepicker_SyncEx($(this).attr("datetimepicker")); - }) - .val(nowtime.getDate()); - - $('.datetimepicker-hour').attr('min', 0) - .attr('max', 23) - .attr('step', 1) - .val(nowtime.getHours()); + var number = -(Math.floor(angle / (ccn_datetimepicker_dialPlateHourResolution / 2)) - 3); + if (number < 0) number += 12; + if (distance < ccn_datetimepicker_dialPlateRadius * ccn_datetimepicker_dialPlateHourDistinguishPercent) + number += 12; - $('.datetimepicker-minute').attr('min', 0) - .attr('max', 59) - .attr('step', 1) - .val(nowtime.getMinutes()); -} - -function ccn_datetimepicker_Sync() { - var pickerIndex = $(this).attr("datetimepicker"); - ccn_datetimepicker_SyncEx(pickerIndex); -} - -function ccn_datetimepicker_SyncEx(pickerIndex) { - year = parseInt($('.datetimepicker-year[datetimepicker=' + pickerIndex + ']').val()); - month = parseInt($('.datetimepicker-month[datetimepicker=' + pickerIndex + ']').val()); - - dayDOM = $('.datetimepicker-day[datetimepicker=' + pickerIndex + ']'); - if (typeof(year) == 'undefined' || typeof(month) == 'undefined') { - dayDOM.attr('max', 1) - .val(1); - } else { - dayDOM.attr('max', ccn_datetime_monthDayCount[month - 1] + ((month == 2 && ccn_datetime_IsLeapYear(year) ? 1 : 0))) - .val(1); + // judge + if (ccn_datetimepicker_displayCacheDateTime.getHours() != number) { + ccn_datetimepicker_displayCacheDateTime.setHours(number); + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.hour); } } -*/ +function ccn_datetimepicker_StopDragHour() { + ccn_datetimepicker_enableHourDrag = false; + + ccn_datetimepicker_internalDateTime.setHours(ccn_datetimepicker_displayCacheDateTime.getHours()); + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime); + + if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.hour) + ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.minute); +} + + +function ccn_datetimepicker_StartDragMinute() { ccn_datetimepicker_enableMinuteDrag = true; } +function ccn_datetimepicker_DraggingMinute(e) { + var offset = $('#ccn-datetimepicker-panelMinute').offset(); + var x = e.pageX - offset.left - ccn_datetimepicker_dialPlateRadius; + var y = -(e.pageY - offset.top - ccn_datetimepicker_dialPlateRadius); + + var distance = Math.sqrt(x * x + y * y); + var angle = Math.asin(y / distance); + if (x < 0) angle = Math.PI - angle; // correct negative x axis angle + + angle += (ccn_datetimepicker_dialPlateMinuteResolution / 2); // correct offset + if (angle > Math.PI * 2) + angle -= Math.PI * 2; + + var number = -(Math.floor(angle / (ccn_datetimepicker_dialPlateMinuteResolution / 2)) - 3); + if (number < 0) number += 12; + + // judge + if (ccn_datetimepicker_displayCacheDateTime.getMinutes() != number) { + ccn_datetimepicker_displayCacheDateTime.setMinutes(number); + ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.minute); + } +} +function ccn_datetimepicker_StopDragMinute() { + ccn_datetimepicker_enableMinuteDrag = false; + + ccn_datetimepicker_internalDateTime.setMinutes(ccn_datetimepicker_displayCacheDateTime.getMinutes()); + ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime); + + // no page need to be jumped +} + + +function ccn_datetimepicker_ClampDateTime(dateObj) { + if (dateObj < ccn_datetime_MIN_DATETIME) + dateObj.setTime(ccn_datetime_MIN_DATETIME.getTime()); + if (dateObj >= ccn_datetime_MAX_DATETIME) + dateObj.setTime(ccn_datetime_MAX_DATETIME.getTime()); +} + +// ========================================================== universal function function ccn_datetimepicker_Set(pickerIndex, dt, isUTC, mode) { var ele = $('[datetimepicker=' + pickerIndex + ']'); @@ -358,6 +444,9 @@ function ccn_datetimepicker_Set(pickerIndex, dt, isUTC, mode) { ele.attr('datetimepicker-hour', isUTC ? dt.getUTCHours() : dt.getHours()); if (mode < ccn_datetimepicker_tabType.minute) return; ele.attr('datetimepicker-minute', isUTC ? dt.getUTCMinutes() : dt.getMinutes()); + + if (typeof(ele.prop('callbackFunc')) == 'function') + ele.prop('callbackFunc')(); } function ccn_datetimepicker_Get(pickerIndex, isUTC) { diff --git a/src/static/js/page/calendar.js b/src/static/js/page/calendar.js index 3664d4d..fb6faa5 100644 --- a/src/static/js/page/calendar.js +++ b/src/static/js/page/calendar.js @@ -30,8 +30,10 @@ $(document).ready(function() { // process calendar it self ccn_calendar_calendar_LoadCalendarBody(); - // init datetimepicker + // init datetimepicker and preset ccn_datetimepicker_Insert(); + var nowtime = new Date(); + ccn_datetimepicker_Set(1, nowtime, false, ccn_datetimepicker_tabType.month); // bind tab control switcher and set current tab $("#tabcontrol-tab-1-1").click(function(){ @@ -58,7 +60,11 @@ $(document).ready(function() { // bind event $('#ccn-calendar-collection-btnRefresh').click(ccn_calendar_collection_Refresh); - $('#ccn-calendar-calendar-btnJump').click(ccn_calendar_calendar_btnRefresh); + $('#ccn-calendar-calendar-btnJump') + .prop('callbackFunc', ccn_calendar_calendar_btnRefresh) + .click(function() { + ccn_datetimepicker_Modal(ccn_datetimepicker_tabType.month, 1, false); + }); $('#ccn-calendar-calendar-btnToday').click(ccn_calendar_calendar_btnToday); $('#ccn-calendar-calendar-btnAdd').click(ccn_calendar_calendar_btnAdd); }); @@ -74,6 +80,7 @@ function ccn_calendar_calendar_Refresh() { var gottenDateTime = ccn_datetimepicker_Get(1, false); var gottenYear = gottenDateTime.getFullYear(); var gottenMonth = gottenDateTime.getMonth() + 1; + $('#ccn-calendar-calendar-textMonth').text('{0} - {1}'.format(gottenYear, ccn_i18n_UniversalGetMonth(gottenMonth - 1))); // don't need to set anything, because its default value is enough to use. var gottenWeek = ccn_datetime_DayOfWeek(gottenYear, gottenMonth, 1); @@ -247,7 +254,7 @@ function ccn_calendar_calendar_btnRefresh() { function ccn_calendar_calendar_btnToday() { var nowtime = new Date(); - ccn_datetimepicker_Set(1, nowtime, false); + ccn_datetimepicker_Set(1, nowtime, false, ccn_datetimepicker_tabType.month); ccn_calendar_calendar_Refresh(); ccn_calendar_calendar_Analyse(); ccn_calendar_calendar_Render(); diff --git a/src/static/tmpl/datetimepicker.tmpl b/src/static/tmpl/datetimepicker.tmpl index e75f7cf..4a537f3 100644 --- a/src/static/tmpl/datetimepicker.tmpl +++ b/src/static/tmpl/datetimepicker.tmpl @@ -1,4 +1,4 @@ -