易得天气
1、未来40日天气详情弹窗
2、未来40日天气日历
3、未来40日天气趋势图
效果图
未来40日天气详情弹窗
.onClick(() => {
if (this.showHideWeatherContent) {
this.showHideWeatherContent(false)
}
DialogHelper.showCustomDialog(wrapBuilder(WeatherForecase40DetailPopupBuilder), {
dialogId: 'weather_forecase40_detail_popup',
forecast40Data: this.weatherItemData?.weatherData?.forecast40_v2,
forecast40: this.weatherItemData?.weatherData?.forecast40,
meta: this.weatherItemData?.weatherData?.meta,
isDark: this.isDark,
isWeatherHeaderDark: this.isWeatherHeaderDark,
panelOpacity: this.panelOpacity,
ref: this.popupExitRef,
backCancel: false,
maskColor: $r('app.color.transparent'),
transition: AnimationHelper.transitionInDown(0),
onWillDismiss: () => {
this.popupExitRef.exit()
},
onDidDisappear: () => {
if (this.showHideWeatherContent) {
this.showHideWeatherContent(true)
}
}
} as WeatherForecase40DetailPopupOptions)
})
@Builder
export function WeatherForecase40DetailPopupBuilder(options: WeatherForecase40DetailPopupOptions) {
WeatherForecase40DetailPopup({ options: options })
}
@ComponentV2
export struct WeatherForecase40DetailPopup {
@Require @Param options: WeatherForecase40DetailPopupOptions
@Local contentOpacity: number = 0
@Local titleBarOpacity: number = 0
@Local calendarPanelWidth: number = 0
@Local calendarPanelHeight: number = 0
@Local marginTop: number = 0
@Local pageData: Array<Array<WeatherDetailData>> = []
@Local currentSelectedItem: WeatherDetailData | undefined = undefined
private itemAlign: ItemAlign = ItemAlign.End
private swiperController = new SwiperController()
private chartController = new WeatherForecase40ChartController()
aboutToAppear(): void {
this.generatePageData()
this.options.ref.exit = this.exit
const weatherObserveForecase40PanelRectangle = componentUtils.getRectangleById('weather_observe_forecase40_panel')
this.calendarPanelWidth = px2vp(weatherObserveForecase40PanelRectangle.size.width)
this.calendarPanelHeight = px2vp(weatherObserveForecase40PanelRectangle.size.height)
this.marginTop =
px2vp(weatherObserveForecase40PanelRectangle.windowOffset.y) - 48 - 12 - px2vp(AppUtil.getStatusBarHeight())
this.itemAlign =
weatherObserveForecase40PanelRectangle.windowOffset.x < DisplayUtil.getWidth() / 2 ? ItemAlign.Start :
ItemAlign.End
setTimeout(() => {
this.calendarPanelWidth = px2vp(DisplayUtil.getWidth()) - 2 * 16
this.calendarPanelHeight = 488
this.marginTop = 0
this.contentOpacity = 1
setTimeout(() => {
this.titleBarOpacity = 1
}, 200)
}, 16)
}
generatePageData() {
this.pageData.splice(0, this.pageData.length)
const temp = [...this.options.forecast40]
const firstDateTime = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(temp[0].date))
const lastDateTime = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(temp[temp.length - 1].date))
const firstWeekday = firstDateTime.getDay()
const fixedFirstWeekday = firstWeekday >= 7 ? 0 : firstWeekday
let index = 1
let list: Array<WeatherDetailData>
for (let i = 0; i < 2; i++) {
list = []
for (let j = 0; j < 28; j++) {
if (i == 0) {
if (j < fixedFirstWeekday) {
list.push({
date: DateUtil.getAmountDayStr(firstDateTime, -(fixedFirstWeekday - j), Constants.YYYYMMDD)
} as WeatherDetailData)
} else {
const removeItem = temp.splice(0, 1)[0]
if (!this.currentSelectedItem) {
const date = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(removeItem.date))
if (DateUtil.isToday(date)) {
this.currentSelectedItem = removeItem
}
}
list.push(removeItem)
}
} else {
if (ArrayUtil.isNotEmpty(temp)) {
list.push(temp.splice(0, 1)[0])
} else {
list.push({
date: DateUtil.getAmountDayStr(lastDateTime, index, Constants.YYYYMMDD)
} as WeatherDetailData)
index++
}
}
}
this.pageData.push(list)
}
}
exit = () => {
this.titleBarOpacity = 0
setTimeout(() => {
const weatherObserveForecase40PanelRectangle = componentUtils.getRectangleById('weather_observe_forecase40_panel')
this.calendarPanelWidth = px2vp(weatherObserveForecase40PanelRectangle.size.width)
this.calendarPanelHeight = px2vp(weatherObserveForecase40PanelRectangle.size.height)
this.marginTop =
px2vp(weatherObserveForecase40PanelRectangle.windowOffset.y) - 48 - 12 - px2vp(AppUtil.getStatusBarHeight())
this.contentOpacity = 0
setTimeout(() => {
DialogHelper.closeDialog('weather_forecase40_detail_popup')
}, 200)
}, 200)
}
build() {
Column() {
Stack({ alignContent: Alignment.Start }) {
Text(this.options.meta?.city)
.width('100%')
.height(48)
.textAlign(TextAlign.Center)
.fontSize(20)
.fontColor(this.options.isWeatherHeaderDark ? $r('app.color.special_white') : $r('app.color.special_black'))
.fontWeight(FontWeight.Bold)
OpacityLayout({
child: () => {
this.closeIcon()
},
onTap: () => {
this.exit()
}
})
}
.width('100%')
.height(48)
.margin({ top: px2vp(AppUtil.getStatusBarHeight()) })
.opacity(this.titleBarOpacity)
.animation({ curve: Curve.Ease, duration: 200 })
Scroll() {
Column() {
Column() {
this.weatherForecase40Calendar()
}
.width(this.calendarPanelWidth)
.height(this.calendarPanelHeight)
.alignSelf(this.itemAlign)
.borderRadius(12)
.backgroundColor(ColorUtils.alpha(this.options.isDark ? $r('app.color.special_white') :
$r('app.color.special_black'), this.options.panelOpacity))
.clip(true)
.margin({ top: this.marginTop })
.opacity(this.contentOpacity)
.animation({ curve: Curve.Ease, duration: 200 })
Blank().height(12)
Column() {
this.weatherForecase40Chart()
}
.width('100%')
.height(288)
.borderRadius(12)
.backgroundColor(ColorUtils.alpha(this.options.isDark ? $r('app.color.special_white') :
$r('app.color.special_black'), this.options.panelOpacity))
.opacity(this.titleBarOpacity)
.animation({ curve: Curve.Ease, duration: 200 })
}
.padding({
left: 16,
top: 12,
right: 16,
bottom: px2vp(AppUtil.getNavigationIndicatorHeight()) + 12
})
}
.width('100%')
.layoutWeight(1)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })
}
.width('100%')
.height('100%')
}
@Builder
closeIcon() {
Stack() {
Image($r('app.media.ic_close_icon1'))
.width(22)
.height(22)
.colorFilter(ColorUtils.translateColor(this.options.isWeatherHeaderDark ? $r('app.color.special_white') :
$r('app.color.special_black')))
}
.width(54)
.height(48)
}
@Builder
weatherForecase40Calendar() {
Column() {
Row() {
this.weekTitle('日')
this.weekTitle('一')
this.weekTitle('二')
this.weekTitle('三')
this.weekTitle('四')
this.weekTitle('五')
this.weekTitle('六')
}
Swiper(this.swiperController) {
ForEach(this.pageData, (item: Array<WeatherDetailData>) => {
this.weatherForecase40CalendarItem(item)
}, (item: Array<WeatherDetailData>) => item[0].date)
}
.width('100%')
.height(348)
.loop(false)
.indicator(
Indicator.dot()
.itemWidth(3)
.itemHeight(2)
.selectedItemWidth(6)
.selectedItemHeight(2)
.color(ColorUtils.alpha($r('app.color.special_white'), 0.5))
.selectedColor($r('app.color.special_white'))
.bottom(0)
)
Blank().height(6)
Divider()
.strokeWidth(0.5)
.color(ColorUtils.alpha($r('app.color.special_white'), 0.2))
Row() {
Column() {
Text(this.currentDateStr)
.fontSize(18)
.fontColor($r('app.color.special_white'))
Blank().height(8)
Text(this.currentWeekDay)
.fontSize(15)
.fontColor($r('app.color.special_white'))
}
.alignItems(HorizontalAlign.Start)
Column() {
Row() {
Text(this.currentSelectedItem?.aqi_level_name)
.fontSize(11)
.fontColor($r('app.color.special_white'))
.padding({
left: 8,
top: 2,
right: 8,
bottom: 2
})
.borderRadius(8)
.backgroundColor(ColorUtils.alpha(getAqiColor(this.currentSelectedItem?.aqi), 0.48))
.visibility(StrUtil.isNotEmpty(this.currentSelectedItem?.aqi_level_name) ? Visibility.Visible :
Visibility.Hidden)
Blank().width(4)
Text(`${this.currentSelectedItem?.high}/${this.currentSelectedItem?.low}°`)
.fontSize(18)
.fontColor($r('app.color.special_white'))
}
Blank().height(8)
Text(`${this.currentSelectedItem?.day?.wthr} ${this.currentSelectedItem?.day?.wd}${this.currentSelectedItem?.day?.wp}`)
.fontSize(15)
.fontColor($r('app.color.special_white'))
}
.alignItems(HorizontalAlign.End)
}
.width('100%')
.layoutWeight(1)
.padding({ left: 16, right: 16 })
.justifyContent(FlexAlign.SpaceBetween)
}
}
@Builder
weatherForecase40Chart() {
Column() {
Blank().height(12)
Text('40日天气趋势')
.fontSize(18)
.fontColor($r('app.color.special_white'))
.fontWeight(FontWeight.Bold)
.padding({ left: 16 })
Blank().height(16)
Row() {
Blank()
Text(`${this.options.forecast40Data?.down_days ?? 0}`)
.fontSize(18)
.fontColor($r('app.color.special_white'))
Text('天降温')
.fontSize(13)
.fontColor(ColorUtils.alpha($r('app.color.special_white'), 0.6))
Blank().width(4)
Text(`${this.options.forecast40Data?.up_days ?? 0}`)
.fontSize(18)
.fontColor($r('app.color.special_white'))
Text('天升温')
.fontSize(13)
.fontColor(ColorUtils.alpha($r('app.color.special_white'), 0.6))
Blank().width(4)
Text(`${this.options.forecast40Data?.rain_days ?? 0}`)
.fontSize(18)
.fontColor($r('app.color.special_white'))
Text('天有降水')
.fontSize(13)
.fontColor(ColorUtils.alpha($r('app.color.special_white'), 0.6))
Blank()
}
.width('100%')
WeatherForecase40Chart({
initSelectedItem: this.currentSelectedItem,
forecast40: this.options.forecast40,
chartController: this.chartController,
callback: (currentSelectedItem) => {
const index = this.pageData.findIndex(it => it.find(it1 => it1.date == currentSelectedItem?.date) != null)
if (index >= 0) {
this.swiperController.changeIndex(index, true)
}
this.currentSelectedItem = currentSelectedItem
}
})
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
weekTitle(title: string) {
Text(title)
.fontSize(12)
.fontColor($r('app.color.special_white'))
.layoutWeight(1)
.textAlign(TextAlign.Center)
.padding({ top: 12, bottom: 12 })
}
@Builder
weatherForecase40CalendarItem(item: Array<WeatherDetailData>) {
Grid() {
ForEach(item, (innerItem: WeatherDetailData, index: number) => {
this.weatherForecase40CalendarDateItem(innerItem, item[index - 1])
}, (innerItem: WeatherDetailData) => innerItem.date)
}
.width('100%')
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
.maxCount(7)
.layoutDirection(GridDirection.Row)
}
@Builder
weatherForecase40CalendarDateItem(item: WeatherDetailData, preItem: WeatherDetailData | undefined) {
GridItem() {
Stack() {
Stack()
.width('100%')
.height(324 / 4)
.borderRadius(6)
.backgroundColor(this.isSelected(item) ?
ColorUtils.alpha(this.options.isDark ? $r('app.color.special_black') : $r('app.color.special_white'),
this.options.panelOpacity) : undefined)
.opacity(this.isSelected(item) ? 1 : 0)
.animation({ curve: Curve.Ease, duration: 200 })
Column() {
Blank().height(12)
Text(this.isToday(item) ? '今天' : this.dateStr(item, preItem))
.fontSize(15)
.fontColor(ColorUtils.alpha($r('app.color.special_white'), this.isEnabled(item) ? 1 : 0.6))
.fontWeight(this.isToday(item) ? FontWeight.Bold : undefined)
Blank().height(4)
if (this.isEnabled(item)) {
Image(WeatherIconUtils.getWeatherIconByType(item.day?.type ?? -1, item.day?.third_type ?? '', false))
.width(24)
.height(24)
} else {
Blank().width(24).height(24)
}
Blank()
Text('降水')
.align(Alignment.Bottom)
.padding({
left: 6,
top: 3,
right: 6,
bottom: 3
})
.margin({ bottom: 4 })
.borderRadius(100)
.backgroundColor($r('app.color.color_0da8ff'))
.fontSize(13)
.fontColor($r('app.color.special_white'))
.visibility(this.isRain(item) ? Visibility.Visible : Visibility.Hidden)
}
.height(324 / 4)
}
.width('100%')
.height(324 / 4)
.onClick(this.isEnabled(item) ? () => {
this.currentSelectedItem = item
this.chartController.updateCurrentSelectedItem(item)
} : undefined)
}
}
isSelected(data: WeatherDetailData): boolean {
return this.currentSelectedItem?.date == data.date
}
isEnabled(data: WeatherDetailData | undefined): boolean {
return !ObjectUtil.isEmpty(data?.day)
}
isToday(data: WeatherDetailData): boolean {
const date = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(data.date))
return DateUtil.isToday(date)
}
isRain(data: WeatherDetailData): boolean {
const weatherType = data.day?.third_type
return weatherType == 'LIGHT_RAIN' || weatherType == 'MODERATE_RAIN' || weatherType == 'HEAVY_RAIN' ||
weatherType == 'STORM_RAIN'
}
dateStr(data: WeatherDetailData, preData: WeatherDetailData | undefined): string {
const date = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(data.date))
let dateStr = DateUtil.getFormatDateStr(date, 'dd')
if (preData) {
const preDate = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(preData.date))
if (date.getMonth() != preDate.getMonth()) {
dateStr = parseInt(DateUtil.getFormatDateStr(date, 'MM')) + '月'
}
}
return dateStr
}
get currentDateStr() {
const date = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(this.currentSelectedItem?.date))
return DateUtil.getFormatDateStr(date, 'MM月dd日')
}
get currentWeekDay() {
const date = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(this.currentSelectedItem?.date))
const weekDay = DateUtil.getWeekDay(date)
switch (weekDay) {
case 0:
return '星期日'
case 1:
return '星期一'
case 2:
return '星期二'
case 3:
return '星期三'
case 4:
return '星期四'
case 5:
return '星期无'
case 6:
return '星期六'
}
return ''
}
}
export class WeatherForecase40ChartController {
updateCurrentSelectedItem = (_?: WeatherDetailData) => {
}
}
@ComponentV2
export struct WeatherForecase40Chart {
@Param initSelectedItem: WeatherDetailData | undefined = undefined
@Param forecast40: Array<WeatherDetailData> = []
@Param chartController?: WeatherForecase40ChartController = undefined
@Event callback?: (currentSelectedItem?: WeatherDetailData) => void = undefined
@Local currentSelectedItem: WeatherDetailData | undefined = undefined
@Local currentAxisX: number = 0
private maxTempData: WeatherDetailData | undefined = undefined
private minTempData: WeatherDetailData | undefined = undefined
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private chartRect: Edges<number> = {
left: 32,
top: 0,
right: px2vp(DisplayUtil.getWidth()) - 32,
bottom: 0
} as Edges<number>
aboutToAppear(): void {
if (this.chartController) {
this.chartController.updateCurrentSelectedItem = (currentSelectedItem) => {
const length = this.forecast40.length
const chartRectWidth = this.chartRect.right - this.chartRect.left
const gaps = 2.5
const radius = (chartRectWidth - (length - 1) * gaps) / length / 2
const index = this.forecast40.findIndex(it => it.date == currentSelectedItem?.date)
this.currentAxisX = 32 + (2 * radius + gaps) * index + radius
this.currentSelectedItem = currentSelectedItem
this.draw()
}
}
this.currentSelectedItem = this.initSelectedItem ?? this.forecast40?.[0]
this.maxTempData = this.forecast40?.reduce((e1, e2) => (e1.high ?? 0) > (e2.high ?? 0) ? e1 : e2)
this.minTempData = this.forecast40?.reduce((e1, e2) => (e1.low ?? 0) < (e2.low ?? 0) ? e1 : e2)
}
build() {
Column() {
Stack({ alignContent: Alignment.BottomStart }) {
Text(this.desc)
.width(this.descWidth)
.height(24)
.textAlign(TextAlign.Center)
.fontSize(12)
.fontColor($r('app.color.special_black'))
.borderRadius(100)
.backgroundColor($r('app.color.special_white'))
.margin({ left: this.marginLeft })
}
.width('100%')
.height(38)
.padding({ left: 32, right: 32 })
Stack({ alignContent: Alignment.BottomStart }) {
Column() {
Text(getTemp(this.maxTempData?.high))
.width(32)
.textAlign(TextAlign.Center)
.fontSize(12)
.fontColor($r('app.color.special_white'))
Text(getTemp(this.minTempData?.high))
.width(32)
.textAlign(TextAlign.Center)
.fontSize(12)
.fontColor($r('app.color.special_white'))
.margin({ top: 35 })
Text('水')
.width(32)
.textAlign(TextAlign.Center)
.fontSize(12)
.fontColor($r('app.color.special_white'))
}
.width(32)
.height('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({ top: 18, bottom: 24 })
Row() {
this.dateItem(this.forecast40[0].date)
this.dateItem(this.forecast40[9].date)
this.dateItem(this.forecast40[19].date)
this.dateItem(this.forecast40[29].date)
this.dateItem(this.forecast40[39].date)
}
.width('100%')
.height(28)
Canvas(this.canvasContext)
.width('100%')
.height('100%')
.onReady(() => {
this.draw()
})
}
.layoutWeight(1)
.gesture(
PanGesture({ direction: PanDirection.Horizontal })
.onActionStart((event: GestureEvent | undefined) => {
if (event) {
this.touch(event.fingerList[0].localX)
}
})
.onActionUpdate((event: GestureEvent | undefined) => {
if (event) {
this.touch(event.fingerList[0].localX)
}
})
.onActionEnd((event: GestureEvent | undefined) => {
if (event) {
this.touch(event.fingerList[0].localX)
}
})
)
.onTouch((e) => {
if (e.type == TouchType.Down) {
this.touch(e.touches[0].x)
}
})
}
.layoutWeight(1)
}
get descWidth() {
const desc = this.desc
const width = px2vp(this.getUIContext().getMeasureUtils().measureText({
textContent: desc,
fontSize: 12
}))
return width + 2 * 8
}
get marginLeft() {
let marginLeft = 0
const fixedAxisX = this.currentAxisX - 32 - 16
const descWidth = this.descWidth
if (fixedAxisX > descWidth * 0.5) {
const chartRectWidth = this.chartRect.right - this.chartRect.left
const remainWidth = chartRectWidth - descWidth
marginLeft = fixedAxisX - descWidth / 2
marginLeft = Math.min(marginLeft, remainWidth)
}
return marginLeft
}
@Builder
dateItem(date?: string) {
Text(this.date(date))
.fontSize(11)
.fontColor($r('app.color.special_white'))
.layoutWeight(1)
.textAlign(TextAlign.Center)
}
date(date?: string): string {
return DateUtil.getFormatDateStr(DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(date)), 'MM/dd')
}
touch(x: number) {
if (ArrayUtil.isEmpty(this.forecast40)) {
return
}
const length = this.forecast40.length
const chartRectWidth = this.chartRect.right - this.chartRect.left
let index = Math.round((x - this.chartRect.left) / (chartRectWidth / length))
if (index < 0) {
index = 0
}
if (index > length - 1) {
index = length - 1
}
const gaps = 2.5
const radius = (chartRectWidth - (length - 1) * gaps) / length / 2
this.currentSelectedItem = this.forecast40[index]
this.currentAxisX = 32 + (2 * radius + gaps) * index + radius
this.draw()
if (this.callback) {
this.callback(this.currentSelectedItem)
}
}
draw() {
const canvas = this.canvasContext
if (!canvas) {
return
}
canvas.clearRect(0, 0, canvas.width, canvas.height)
const hGap = 32
const bGap = 28
const newRect = {
left: hGap,
top: 0,
right: canvas.width - hGap,
bottom: canvas.height - bGap
} as Edges<number>
const length = this.forecast40?.length ?? 0
const gaps = 2.5
const radius = (newRect.right - newRect.left - (length - 1) * gaps) / length / 2
const lineRect = {
left: newRect.left,
top: newRect.top + 24,
right: newRect.right,
bottom: newRect.bottom - 48
} as Edges<number>
this.drawDashLine(canvas, lineRect, lineRect.top, radius)
this.drawDashLine(canvas, lineRect, lineRect.top + (lineRect.bottom - lineRect.top) / 2, radius)
this.drawDashLine(canvas, lineRect, lineRect.bottom, radius)
let currentPoint = {} as Position
const linePath = new Path2D()
this.forecast40?.forEach((e, index) => {
const isSelected = e.date == this.currentSelectedItem?.date
const isRain = this.isRain(e)
const circleRect = {
left: newRect.left + (2 * radius + gaps) * index,
top: newRect.bottom - 2 * radius,
right: newRect.left + (2 * radius + gaps) * index + 2 * radius,
bottom: newRect.bottom
} as Edges<number>
this.drawLine(canvas, circleRect, newRect.top, radius, isSelected)
this.drawCircle(canvas, circleRect, radius, isRain)
const point = this.drawWeatherLine(linePath, e, index, circleRect, lineRect, isSelected)
if (point) {
currentPoint = point
}
})
canvas.lineWidth = 2
canvas.strokeStyle = ColorUtils.alpha($r('app.color.color_0da8ff'), 1)
canvas.stroke(linePath)
canvas.beginPath()
canvas.shadowBlur = 4
canvas.shadowColor = ColorUtils.alphaStr($r('app.color.color_0da8ff'), 0.4)
canvas.fillStyle = ColorUtils.alpha($r('app.color.special_white'), 1)
canvas.arc(currentPoint.x, currentPoint.y, 6, 0, Math.PI * 2)
console.log('currentPoint = ' + JSON.stringify(currentPoint))
canvas.fill()
canvas.beginPath()
canvas.fillStyle = ColorUtils.alpha($r('app.color.color_0da8ff'), 1)
canvas.arc(currentPoint.x, currentPoint.y, 4, 0, Math.PI * 2)
canvas.fill()
}
drawWeatherLine(linePath: Path2D, data: WeatherDetailData, index: number,
circleRect: Edges<number>, lineRect: Edges<number>, isSelected: boolean): Position | undefined {
const high = this.maxTempData?.high ?? 0
const low = this.minTempData?.high ?? 0
const currentTemp = data.high ?? 0
const percent = (currentTemp - low) / (high - low)
const centerX = circleRect.left + (circleRect.right - circleRect.left) / 2
const point = { x: centerX, y: lineRect.bottom - (lineRect.bottom - lineRect.top) * percent } as Position
if (index == 0) {
linePath.moveTo(point.x, point.y)
} else {
linePath.lineTo(point.x, point.y)
}
if (isSelected) {
return point
}
return undefined
}
drawCircle(canvas: CanvasRenderingContext2D, circleRect: Edges<number>, radius: number, isRain: boolean) {
const centerX = circleRect.left + (circleRect.right - circleRect.left) / 2
const centerY = circleRect.top + (circleRect.bottom - circleRect.top) / 2
canvas.beginPath()
canvas.arc(centerX, centerY, radius, 0, Math.PI * 2)
canvas.fillStyle =
isRain ? ColorUtils.alpha($r('app.color.color_0da8ff'), 1) : ColorUtils.alpha($r('app.color.special_white'), 1)
canvas.fill()
}
drawLine(canvas: CanvasRenderingContext2D, circleRect: Edges<number>, lineY: number, radius: number,
isSelected: boolean) {
const x = circleRect.left + (circleRect.right - circleRect.left) / 2
canvas.beginPath()
canvas.moveTo(x, circleRect.bottom - radius)
canvas.lineTo(x, lineY)
canvas.lineWidth = isSelected ? 2 : 0.5
canvas.strokeStyle = isSelected ? ColorUtils.alpha($r('app.color.color_0da8ff'), 1) :
ColorUtils.alpha($r('app.color.special_white'), 0.4)
canvas.stroke()
}
drawDashLine(canvas: CanvasRenderingContext2D, lineRect: Edges<number>, lineY: number, radius: number) {
const dashWidth = 2
const spaceWidth = 8
let startX = lineRect.left + radius
canvas.lineWidth = 0.8
canvas.strokeStyle = ColorUtils.alpha($r('app.color.special_white'), 0.8)
while (startX < lineRect.right) {
let endX = startX + dashWidth
if (endX > lineRect.right - radius) {
endX = lineRect.right - radius
}
canvas.beginPath()
canvas.moveTo(startX, lineY)
canvas.lineTo(endX, lineY)
canvas.stroke()
startX += dashWidth + spaceWidth
}
}
get desc() {
const date = DateUtil.getFormatDate(getHarmonyDateTimeFormattedString(this.currentSelectedItem?.date))
return `${DateUtil.getFormatDateStr(date,
'MM月dd日')} ${this.currentSelectedItem?.day?.wthr} ${getTemp(this.currentSelectedItem?.low)}~${getTemp(this.currentSelectedItem?.high)}`
}
isRain(data: WeatherDetailData): boolean {
const weatherType = data.day?.third_type
return weatherType == 'LIGHT_RAIN' || weatherType == 'MODERATE_RAIN' || weatherType == 'HEAVY_RAIN' ||
weatherType == 'STORM_RAIN'
}
}