效果图
界面有点丑(我很丑,但我很优秀),可自行优化。
部分重要代码
对于日历实现没有什么难度,需要说的就是 定义三个全局属性,分别是 显示模式: 年、月、日 三种; 当前日期: 即现在的日期; 选择日期: 即页面上选择的日期;然后分别实现日(天),月,年.尽量复用组件.比如月组件实现可重复利用日组件,年组件实现可重复利用月组件.具体实现看完整代码:除此之外实现了一个格式化日期的脚本 DatePlus.ts
export default class DatePlus {
// 日期
private date: Date;
public constructor(date?: Date) {
this.date = date ? date : new Date();
}
/**
* 格式化
* @param fmt
* @returns
*/
public format(fmt: string = 'yyyy-mm-dd'): string {
let _date = this.date;
var o = {
'M+': _date.getMonth() + 1, //月份
'd+': _date.getDate(), //日
'h+': _date.getHours(), //小时
'm+': _date.getMinutes(), //分
's+': _date.getSeconds(), //秒
'q+': Math.floor((_date.getMonth() + 3) / 3), //季度
S: _date.getMilliseconds(), //毫秒
};
// 获取年份
// ①
if (/(y+)/i.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (_date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
for (var k in o) {
// ②
if (new RegExp('(' + k + ')', 'i').test(fmt)) {
fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
}
}
return fmt;
}
}
使用方式:
let datePlus = new DatePlus(new Date());
// 输出2021年04月15日
console.log(datePlus.format('yyyy年mm月dd日'));
工具类:
工具类中实现了 判断是否闰年、深拷贝 Date对象、获取下一年、下一月、下一日、上一年、上一月、上一日等方法. Util.ts
export class Util {
/**
* 是否闰年
* @param year 年份
* @returns
*/
public static isLeapYear(year: number) {
var date = new Date(year, 1, 29);
return date.getDate() === 29;
}
/**
* 深拷贝时间
* @param date
* @returns
*/
public static cloneDate(date: Date): Date {
return new Date(date.valueOf());
}
/**
* 下一日、下一周、下一月、下一年
* @param date 待处理时间
* @param type 类型
* @returns
*/
public static nextDate(date: Date, type: CALENDAR = CALENDAR.DAY): Date {
let year = date.getFullYear();
let month = date.getMonth();
let day = date.getDate();
switch (type) {
case CALENDAR.YEAR:
{
// 1
// date = new Date(date.setFullYear(year + 1));
// 2 优化版
year++;
date = new Date(year, month + 1, 0);
if (day <= date.getDate()) {
date = new Date(year, month, day);
}
}
break;
case CALENDAR.MONTH:
{
// 1 缺陷版
// date = new Date(date.setMonth(month + 1));
// 2 优化版
// month++;
// if (month === 12) {
// year++;
// month = 0;
// }
// date = new Date(year, month + 1, 0);
// 3 优化版
month++;
date = new Date(year, month + 1, 0);
if (day <= date.getDate()) {
date = new Date(year, month, day);
}
}
break;
case CALENDAR.DAY:
{
date = new Date(date.setDate(day + 1));
}
break;
case CALENDAR.WEEK:
{
date = new Date(date.setDate(day + 7));
}
break;
default:
break;
}
return date;
}
/**
* 上一日、上一周、上一月、上一年
* @param date 待处理时间
* @param type 类型
* @returns
*/
public static lastDate(date: Date, type: CALENDAR = CALENDAR.DAY): Date {
let year = date.getFullYear();
let month = date.getMonth();
let day = date.getDate();
switch (type) {
case CALENDAR.YEAR:
{
// 1 缺陷版
// date = new Date(date.setFullYear(year - 1));
// 2 优化版
year--;
date = new Date(year, month + 1, 0);
if (day <= date.getDate()) {
date = new Date(year, month, day);
}
}
break;
case CALENDAR.MONTH:
{
// 1 缺陷版
// date = new Date(date.setMonth(month - 1));
// 2 优化版
// month--;
// if (month === -1) {
// year--;
// month = 11;
// }
// date = new Date(year, month + 1, 0);
// 3 优化版
month--;
date = new Date(year, month + 1, 0);
if (day <= date.getDate()) {
date = new Date(year, month, day);
}
}
break;
case CALENDAR.DAY:
{
date = new Date(date.setDate(day - 1));
}
break;
case CALENDAR.WEEK:
{
date = new Date(date.setDate(day - 7));
}
break;
default:
break;
}
return date;
}
}
悬浮框触摸移动
FloatingTouchMove.ts
const { ccclass, property } = cc._decorator;
@ccclass
export default class FloatingTouchMove extends cc.Component {
private startPos: cc.Vec2;
start() {
// 节点初始位置,每次触摸结束更新
this.startPos = this.node.getPosition();
}
onEnable() {
// 触摸节点移动
this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
// 非触摸节点可移动
// this.node.parent.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
// this.node.parent.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
// this.node.parent.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
}
onDisable() {
// 触摸节点移动
this.node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
// 非触摸节点可移动
// this.node.parent.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
// this.node.parent.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
// this.node.parent.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
}
onTouchMove(event: cc.Event.EventTouch) {
let pos = this.node.getPosition();
// 触摸刚开始的位置
let oldPos: cc.Vec2 = this.node.parent.convertToNodeSpaceAR(event.getTouches()[0].getStartLocation());
// 触摸时不断变更的位置
let newPos: cc.Vec2 = this.node.parent.convertToNodeSpaceAR(event.getTouches()[0].getLocation());
// 1.x 版本使用 cc.pSub
// let subPos = cc.pSub(oldPos,newPos);
// 2.x 版本使用 p1.sub(p2);
let subPos = oldPos.sub(newPos);
pos.x = this.startPos.x - subPos.x;
pos.y = this.startPos.y - subPos.y;
// 控制节点移不出父节点;
let minX = -this.node.parent.width / 2 + this.node.width / 2; //最小X坐标;
let maxX = Math.abs(minX);
let minY = -this.node.parent.height / 2 + this.node.height / 2; //最小Y坐标;
let maxY = Math.abs(minY);
if (pos.x < minX) {
pos.x = minX;
} else if (pos.x > maxX) {
pos.x = maxX;
}
if (pos.y < minY) {
pos.y = minY;
} else if (pos.y > maxY) {
pos.y = maxY;
}
this.node.setPosition(pos);
}
onTouchEnd(event: cc.Event.EventTouch) {
this.startPos = this.node.getPosition(); // 更新获取触摸结束之后的node坐标;
}
onTouchCancel(event: cc.Event.EventTouch) {
this.startPos = this.node.getPosition(); // 更新获取触摸结束之后的node坐标;
}
}