提交 44d00d73 编写于 作者: 雪洛's avatar 雪洛

fix: 不要依赖type默认值,不要触发kotlin特性null+null = "nullnull"

上级 99dd98b7
<template>
<view class="root">
<view class="date">
<text class="date-text">{{current_month}}</text>
</view>
<view ref="draw-header" class="calendar-header"></view>
<view ref="draw-weeks" class="calendar-week" @touchstart="select"></view>
<view class="btn-group">
<button size="mini" @click="preDate">上个月</button>
<button size="mini" @click="gotoToday">回到今天</button>
<button size="mini" @click="nextDate">下个月</button>
</view>
<view>{{timeData.fullDate}} {{current_day}}</view>
</view>
<view class="root">
<view class="date">
<text class="date-text">{{current_month}}</text>
</view>
<view ref="draw-header" class="calendar-header"></view>
<view ref="draw-weeks" class="calendar-week" @touchstart="select"></view>
<view class="btn-group">
<button size="mini" @click="preDate">上个月</button>
<button size="mini" @click="gotoToday">回到今天</button>
<button size="mini" @click="nextDate">下个月</button>
</view>
<view>{{timeData.fullDate}} {{current_day}}</view>
</view>
</template>
<script>
import { Calendar, DateType } from './index.uts'
type CoordsType = {
x : number;
y : number;
width : number;
height : number;
data : DateType
}
export default {
data() {
return {
weeks: [] as Array<Array<DateType>>,
$coords: [] as Array<CoordsType>,
$calendar: new Calendar() as Calendar,
timeData: {
fullDate: '',
year: 0,
month: 0,
date: 0,
day: 0,
lunar: '',
disabled: false,
} as DateType
}
},
computed: {
// 获取月份
current_month() : string {
const nowDate = this.timeData
const month = nowDate.month
return month < 10 ? '0' + month : month.toString()
},
current_day() : string {
const time = this.timeData.data
return time?.IMonthCn + time?.IDayCn
}
},
created() { },
onReady() {
this.weeks = this.$calendar.getWeeks()
this.timeData = this.$calendar.getDateInfo()
// 绘制日历头部
this.drawHeader()
this.drawWeek(this.weeks, '')
},
methods: {
// 触发整个日历的点击事件,需要计算点击位置
select(event : TouchEvent) {
const refs = this.$refs['draw-weeks'] as Element
const rect = refs.getBoundingClientRect();
const dom_x = rect.left; // 元素左上角相对于视口的 X 坐标
const dom_y = rect.top; // 元素左上角相对于视口的 Y 坐标
const touch = event.touches[0];
const clientX = touch.clientX; // X 坐标
const clientY = touch.clientY; // Y 坐标
// 计算点击的相对位置
const x = clientX - dom_x
const y = clientY - dom_y
this.clickGrid(x, y)
},
// 点击具体的日历格子
clickGrid(x : number, y : number) {
// 小格子数组
const gridArray = this.$coords
// 遍历小格子数组,找到最接近点击坐标的小格子
for (let i = 0; i < gridArray.length; i++) {
const grid = gridArray[i]
// 计算小格子理论上的最大值
const max_x = grid.x + grid.width
const max_y = grid.y + grid.height
const is_x_limit = grid.x < x && x < max_x
const is_y_limit = grid.y < y && y < max_y
const is_select = is_x_limit && is_y_limit
if (is_select) {
const data = grid.data
this.timeData = this.$calendar.getDateInfo(data.fullDate)
this.drawWeek(this.weeks, grid.data.fullDate)
}
}
},
// 切换上个月
preDate() {
const fulldate = this.timeData.fullDate
const time = this.$calendar.getDate(fulldate, -1, 'month')
this.timeData = this.$calendar.getDateInfo(time.fullDate)
this.weeks = this.$calendar.getWeeks(time.fullDate)
// 重新绘制日历
this.drawWeek(this.weeks, time.fullDate)
},
// 切换下个他
nextDate() {
const fulldate = this.timeData.fullDate
const time = this.$calendar.getDate(fulldate, 1, 'month')
this.timeData = this.$calendar.getDateInfo(time.fullDate)
this.weeks = this.$calendar.getWeeks(time.fullDate)
// 重新绘制日历
this.drawWeek(this.weeks, time.fullDate)
},
// 回到今天
gotoToday() {
const time = this.$calendar.getDate()
this.timeData = this.$calendar.getDateInfo(time.fullDate)
this.weeks = this.$calendar.getWeeks(time.fullDate)
// 重新绘制日历
this.drawWeek(this.weeks, time.fullDate)
},
// 绘制日历顶部信息
drawHeader() {
const refs = this.$refs['draw-header'] as Element
let ctx = refs.getDrawableContext()
if (ctx == null) return
const date_header_map = ['一', '二', '三', '四', '五', '六', '日']
const width = refs.getBoundingClientRect().width
const num = date_header_map.length
const one_width = width / num
for (let i = 0; i < num; i++) {
let box_left = i * one_width + 2
let box_width = one_width - 4
let box_height = 26
// 文本赋值
const text = date_header_map[i]
let text_left = box_width / 2 + box_left
let text_top = box_height / 2 + 6
ctx.font = '12'
ctx.textAlign = 'center'
ctx.fillText(text, text_left, text_top)
ctx.update()
}
},
// 绘制日历主体
drawWeek(weeks : Array<Array<DateType>>, time : string) {
const start_time = Date.now()
const refs = this.$refs['draw-weeks'] as Element
let ctx = refs.getDrawableContext()
if (ctx == null) return
const dom = refs.getBoundingClientRect()
const width = dom.width
const height = dom.height
let week_len = weeks.length
const one_width = width / weeks[0].length
const one_height = height / week_len
if (time !== '') {
this.$coords = []
ctx.reset()
}
for (let week = 0; week < week_len; week++) {
const week_item = weeks[week]
for (let day = 0; day < week_item.length; day++) {
const day_item = week_item[day]
let day_left = day * one_width + 2
let day_top = one_height * week + 2
let day_width = one_width - 4
let day_height = one_height - 4
// 文本赋值
let text = day_item.date.toString()
let text_left = day * one_width + (one_width / 2)
let text_top = one_height * week + 25
ctx.font = '16'
ctx.textAlign = 'center'
// 日期是否禁用
if (day_item.disabled) {
ctx.fillStyle = '#ccc'
} else {
// 是否为今天
if (day_item.is_today) {
ctx.fillStyle = 'red'
} else {
// 是否为选中
if (time === day_item.fullDate) {
ctx.fillStyle = 'blue'
} else {
ctx.fillStyle = '#666'
}
}
// 第一次渲染获取数据
// if (time === '') {
// 存储坐标组,用于点击事件
const coords : CoordsType = {
x: day_left,
y: day_top,
width: day_width,
height: day_height,
data: day_item
}
this.$coords.push(coords)
// }
}
ctx.fillText(text, text_left, text_top)
text = day_item.lunar
let lunar_left = day * one_width + (one_width / 2)
let lunar_top = one_height * week + 42
ctx.font = '10'
ctx.textAlign = 'center'
ctx.fillText(text, lunar_left, lunar_top)
}
}
ctx.update()
console.log('diff time', Date.now() - start_time);
}
}
}
import { Calendar, DateType } from './index.uts'
type CoordsType = {
x : number;
y : number;
width : number;
height : number;
data : DateType
}
export default {
data() {
return {
weeks: [] as Array<Array<DateType>>,
$coords: [] as Array<CoordsType>,
$calendar: new Calendar() as Calendar,
timeData: {
fullDate: '',
year: 0,
month: 0,
date: 0,
day: 0,
lunar: '',
disabled: false,
is_today: false
} as DateType
}
},
computed: {
// 获取月份
current_month() : string {
const nowDate = this.timeData
const month = nowDate.month
return month < 10 ? '0' + month : month.toString()
},
current_day() : string {
const time = this.timeData.data
if (time == null) {
return ''
}
return time.IMonthCn + time.IDayCn
}
},
created() { },
onReady() {
this.weeks = this.$calendar.getWeeks()
this.timeData = this.$calendar.getDateInfo()
// 绘制日历头部
this.drawHeader()
this.drawWeek(this.weeks, '')
},
methods: {
// 触发整个日历的点击事件,需要计算点击位置
select(event : TouchEvent) {
const refs = this.$refs['draw-weeks'] as Element
const rect = refs.getBoundingClientRect();
const dom_x = rect.left; // 元素左上角相对于视口的 X 坐标
const dom_y = rect.top; // 元素左上角相对于视口的 Y 坐标
const touch = event.touches[0];
const clientX = touch.clientX; // X 坐标
const clientY = touch.clientY; // Y 坐标
// 计算点击的相对位置
const x = clientX - dom_x
const y = clientY - dom_y
this.clickGrid(x, y)
},
// 点击具体的日历格子
clickGrid(x : number, y : number) {
// 小格子数组
const gridArray = this.$coords
// 遍历小格子数组,找到最接近点击坐标的小格子
for (let i = 0; i < gridArray.length; i++) {
const grid = gridArray[i]
// 计算小格子理论上的最大值
const max_x = grid.x + grid.width
const max_y = grid.y + grid.height
const is_x_limit = grid.x < x && x < max_x
const is_y_limit = grid.y < y && y < max_y
const is_select = is_x_limit && is_y_limit
if (is_select) {
const data = grid.data
this.timeData = this.$calendar.getDateInfo(data.fullDate)
this.drawWeek(this.weeks, grid.data.fullDate)
}
}
},
// 切换上个月
preDate() {
const fulldate = this.timeData.fullDate
const time = this.$calendar.getDate(fulldate, -1, 'month')
this.timeData = this.$calendar.getDateInfo(time.fullDate)
this.weeks = this.$calendar.getWeeks(time.fullDate)
// 重新绘制日历
this.drawWeek(this.weeks, time.fullDate)
},
// 切换下个他
nextDate() {
const fulldate = this.timeData.fullDate
const time = this.$calendar.getDate(fulldate, 1, 'month')
this.timeData = this.$calendar.getDateInfo(time.fullDate)
this.weeks = this.$calendar.getWeeks(time.fullDate)
// 重新绘制日历
this.drawWeek(this.weeks, time.fullDate)
},
// 回到今天
gotoToday() {
const time = this.$calendar.getDate()
this.timeData = this.$calendar.getDateInfo(time.fullDate)
this.weeks = this.$calendar.getWeeks(time.fullDate)
// 重新绘制日历
this.drawWeek(this.weeks, time.fullDate)
},
// 绘制日历顶部信息
drawHeader() {
const refs = this.$refs['draw-header'] as Element
let ctx = refs.getDrawableContext()
if (ctx == null) return
const date_header_map = ['一', '二', '三', '四', '五', '六', '日']
const width = refs.getBoundingClientRect().width
const num = date_header_map.length
const one_width = width / num
for (let i = 0; i < num; i++) {
let box_left = i * one_width + 2
let box_width = one_width - 4
let box_height = 26
// 文本赋值
const text = date_header_map[i]
let text_left = box_width / 2 + box_left
let text_top = box_height / 2 + 6
ctx.font = '12'
ctx.textAlign = 'center'
ctx.fillText(text, text_left, text_top)
ctx.update()
}
},
// 绘制日历主体
drawWeek(weeks : Array<Array<DateType>>, time : string) {
const start_time = Date.now()
const refs = this.$refs['draw-weeks'] as Element
let ctx = refs.getDrawableContext()
if (ctx == null) return
const dom = refs.getBoundingClientRect()
const width = dom.width
const height = dom.height
let week_len = weeks.length
const one_width = width / weeks[0].length
const one_height = height / week_len
if (time !== '') {
this.$coords = []
ctx.reset()
}
for (let week = 0; week < week_len; week++) {
const week_item = weeks[week]
for (let day = 0; day < week_item.length; day++) {
const day_item = week_item[day]
let day_left = day * one_width + 2
let day_top = one_height * week + 2
let day_width = one_width - 4
let day_height = one_height - 4
// 文本赋值
let text = day_item.date.toString()
let text_left = day * one_width + (one_width / 2)
let text_top = one_height * week + 25
ctx.font = '16'
ctx.textAlign = 'center'
// 日期是否禁用
if (day_item.disabled) {
ctx.fillStyle = '#ccc'
} else {
// 是否为今天
if (day_item.is_today) {
ctx.fillStyle = 'red'
} else {
// 是否为选中
if (time === day_item.fullDate) {
ctx.fillStyle = 'blue'
} else {
ctx.fillStyle = '#666'
}
}
// 第一次渲染获取数据
// if (time === '') {
// 存储坐标组,用于点击事件
const coords : CoordsType = {
x: day_left,
y: day_top,
width: day_width,
height: day_height,
data: day_item
}
this.$coords.push(coords)
// }
}
ctx.fillText(text, text_left, text_top)
text = day_item.lunar
let lunar_left = day * one_width + (one_width / 2)
let lunar_top = one_height * week + 42
ctx.font = '10'
ctx.textAlign = 'center'
ctx.fillText(text, lunar_left, lunar_top)
}
}
ctx.update()
console.log('diff time', Date.now() - start_time);
}
}
}
</script>
<style>
.root {
flex: 1;
position: relative;
padding: 15px;
background-color: #fff;
}
.calendar-header {
height: 30px;
margin-bottom: 10px;
}
.date {
margin-bottom: 10px;
margin-left: 10px;
}
.date-text {
font-size: 34px;
font-weight: bold;
}
.calendar-week {
height: 350px;
margin: 2px 0;
}
.btn-group {
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 20px 0;
}
.root {
flex: 1;
position: relative;
padding: 15px;
background-color: #fff;
}
.calendar-header {
height: 30px;
margin-bottom: 10px;
}
.date {
margin-bottom: 10px;
margin-left: 10px;
}
.date-text {
font-size: 34px;
font-weight: bold;
}
.calendar-week {
height: 350px;
margin: 2px 0;
}
.btn-group {
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 20px 0;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册