diff --git a/src/components/weather/README.md b/src/components/weather/README.md new file mode 100644 index 0000000..a4aa96e --- /dev/null +++ b/src/components/weather/README.md @@ -0,0 +1,39 @@ +# star-weather + +星光 Web 组件——天气组件:weather组件介绍(10 月 08 日) + +## 介绍 + +star-weather 组件主要是用来显示当前天气状况和预测1周内天气详情的组件 +star-weather 属性: + +### 1、type 属性 +天气风格样式类型,type一共包含6种类型,分别为type11、type12、type21、type22、type23和type32,其中 +type="type11"的内容排布为只包含天气图标的样式, +type="type12"的内容排布(从左向右)为包含地理位置信息、温度和对应的天气图标, +type="type21"的内容排布(从上至下)为包含天气图标,地理位置和温度信息, +type="type22"的内容排布(从上至下)为包含地理位置、温度、天气图标、空气质量、体感温度、湿度、风级、能见度、紫外线等详细信息。 +`html demo ` + +### 2、data 属性 + +天气详细信息,其中包含地理位置、温度、日期、天气情况、风级、湿度、空气质量、体感温度、能见度、紫外线等具体信息 +`html demo ` +### 3、自适应布局 +天气组件整体布局设计为自适应布局,可自适应缩放显示天气组件。 +### 4、weatherData数据格式说明 +weatherData = { + location: "", //位置信息 + weatherInfo: [ //天气详情信息,包含天气情况、风级、湿度、空气质量、体感温度、能见度、紫外线等详情信息 + { + date: new Date(), 日期 + …… + }, + { + date: new Date(), + } + ] + } + + + diff --git a/src/components/weather/package.json b/src/components/weather/package.json new file mode 100644 index 0000000..f6868a1 --- /dev/null +++ b/src/components/weather/package.json @@ -0,0 +1,22 @@ +{ + "name": "@star-web-components/weather", + "version": "0.0.1", + "description": "", + "type": "module", + "main": "./index.js", + "module": "./index.js", + "exports": { + ".": { + "default": "./index.js" + }, + "./index": { + "default": "./index.js" + }, + "./weather.js": { + "default": "./weather.js" + }, + "./package.json": "./package.json" + }, + "author": "", + "license": "ISC" +} diff --git a/src/components/weather/svg/Cloudy.svg b/src/components/weather/svg/Cloudy.svg new file mode 100644 index 0000000..0724e45 --- /dev/null +++ b/src/components/weather/svg/Cloudy.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/weather/svg/Noload.svg b/src/components/weather/svg/Noload.svg new file mode 100644 index 0000000..c7f5495 --- /dev/null +++ b/src/components/weather/svg/Noload.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/weather/svg/Overcast48.svg b/src/components/weather/svg/Overcast48.svg new file mode 100644 index 0000000..b8c61b0 --- /dev/null +++ b/src/components/weather/svg/Overcast48.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/weather/svg/Partly Cloudy.svg b/src/components/weather/svg/Partly Cloudy.svg new file mode 100644 index 0000000..74310e6 --- /dev/null +++ b/src/components/weather/svg/Partly Cloudy.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/weather/svg/Partly Cloudy48.svg b/src/components/weather/svg/Partly Cloudy48.svg new file mode 100644 index 0000000..296d8a0 --- /dev/null +++ b/src/components/weather/svg/Partly Cloudy48.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/weather/svg/Sunny.svg b/src/components/weather/svg/Sunny.svg new file mode 100644 index 0000000..73264d5 --- /dev/null +++ b/src/components/weather/svg/Sunny.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/weather/weather-style.ts b/src/components/weather/weather-style.ts new file mode 100644 index 0000000..ff2a73b --- /dev/null +++ b/src/components/weather/weather-style.ts @@ -0,0 +1,148 @@ +import {css, CSSResult} from 'lit' +export const sharedStyles: CSSResult = css` + * { + margin: 0; + padding: 0; + box-sizing: border-box; + } + .star-weather-main { + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + } + /* 背景框 */ + .star-weather { + width: var(--autoWidth--); + min-width: var(--autoWidth--); + height: var(--autoHeight--); + min-height: var(--autoHeight--); + transform: scale(var(--autoScale--)); + border-radius: 20px; + overflow: hidden; + background: linear-gradient( + 137.64deg, + #f5f0f5 0%, + #fafafa 20.46%, + #d5daf2 90.45% + ); + display: flex; + flex-direction: column; + } + .star-weather * { + white-space: nowrap; + } + /* .star-weather-top */ + .star-weather-top { + display: flex; + align-items: center; + justify-content: space-between; + } + .type12 .star-weather-top { + width: 100%; + height: 100%; + } + .type21 .star-weather-top { + width: 100%; + height: 100%; + flex-direction: column-reverse; + align-items: center; + } + .type22 .star-weather-top { + width: 100%; + height: 45%; + /* border:1px solid red; */ + } + /* .star-weather-bottom */ + .star-weather-bottom { + display: flex; + flex-wrap: wrap; + } + .type22 .star-weather-bottom { + height: 50%; + } + /* 天气图标 */ + .star-weather-img { + display: flex; + justify-content: center; + align-items: center; + transform: scale(0.7); + } + .type11 .star-weather-img { + height: 100%; + width: 100%; + } + .type12 .star-weather-img { + height: 100%; + margin-right: 30px; + } + .type21 .star-weather-img { + width: 100%; + } + .type22 .star-weather-img { + height: 90%; + margin-right: 30px; + /* border:1px solid red; */ + } + .weather-img { + width: 100%; + height: 100%; + } + /* 位置温度()*/ + .star-weather-location-temperature { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + } + .type12 .star-weather-location-temperature { + height: 100%; + margin-left: 47px; + } + .type21 .star-weather-location-temperature { + width: 100%; + margin-bottom: 40px; + } + .type22 .star-weather-location-temperature { + height: 100%; + /* margin-top:10%; */ + margin-left: 47px; + } + .star-weather-location { + text-align: left; + margin-bottom: 10px; + font-size: 22px; + color: rgba(38, 38, 38, 0.45); + } + .type21 .star-weather-location { + text-align: center; + } + .star-weather-temperature { + font-size: 40px; + font-weight: bold; + position: relative; + display: flex; + align-items: center; + } + /* detailType() */ + .detail-today-item { + height: 50%; + width: 31%; + display: flex; + flex-direction: column; + justify-content: center; + padding-left: 47px; + } + .detail-today-item-top { + font-size: 16px; + color: rgba(38, 38, 38, 0.45); + margin-bottom: 5px; + } + .detail-today-item-bottom { + font-size: 26px; + text-align: left; + color: #4d4d4d; + } +` \ No newline at end of file diff --git a/src/components/weather/weather.ts b/src/components/weather/weather.ts new file mode 100644 index 0000000..05c12a3 --- /dev/null +++ b/src/components/weather/weather.ts @@ -0,0 +1,169 @@ +import {html, LitElement, CSSResultArray} from 'lit' +import {customElement, property, query} from 'lit/decorators.js' +import {sharedStyles} from './weather-style' +import Sunny from './svg/Sunny.svg' +import Cloudy from './svg/Cloudy.svg' +import Noload from './svg/Noload.svg' +import PartlyCloudy from './svg/Partly Cloudy.svg' +const weatherMy: Record = { + Sunny: Sunny, + Cloudy: Cloudy, + PartlyCloudy: PartlyCloudy, +} +const typeMy: Record = { + // height / width + type11: '1', + type12: '0.4', + type21: '1.9', + type22: '0.8', + type23: '0.7', + type32: '1.6', +} +const minAll: Record = { + // width + type11: '100', + type12: '400', + type21: '200', + type22: '500', + type23: '600', + type32: '600', +} +@customElement('star-weather') +export class StarWeather extends LitElement { + public static override get styles(): CSSResultArray { + return [sharedStyles] + } + @property({type: String}) type = 'type11' + @property({type: Object}) data = Object() + + @query('.star-weather-main') + starWeather: HTMLDivElement | undefined + + dataBoo() { + return !!Object.keys(this.data).length + } + render() { + return html` +
+
+
+ ${this.locationType()} ${this.weatherType()} +
+
${this.detailType()}
+
+
+ ` + } + weatherType() { + return html` +
+ +
+ ` + } + locationType() { + if (this.type !== 'type11' && typeMy[this.type]) { + return html` +
+
+
+ ${(this.dataBoo() && this.data.location) || ''} +
+
+ ${(this.dataBoo() && this.data.weatherInfo[0]?.temperature?.max) || ''} +
+
+
+ ` + } else { + return '' + } + } + detailType() { + if (this.type === 'type22') { + return html` + + 空气质量 + + ${this.dataBoo() && (this.data.weatherInfo[0]?.airQuality?.value + + this.data.weatherInfo[0]?.airQuality?.type) || ''} + + + + 体感温度 + + ${(this.dataBoo() && + this.data.weatherInfo[0].somatosensoryTemperature) || ''} + + + + 湿度 + + ${(this.dataBoo() && this.data.weatherInfo[0]?.humidity) || ''} + + + + + ${(this.dataBoo() && this.data.weatherInfo[0]?.wind?.label) || '风向'} + + + ${(this.dataBoo() && this.data.weatherInfo[0]?.wind?.value) || ''} + + + + 能见度 + + ${(this.dataBoo() && this.data.weatherInfo[0]?.visibility) || ''} + + + + 紫外线 + + ${(this.dataBoo() && this.data.weatherInfo[0]?.ultravioletRys) || ''} + + + ` + } else { + return '' + } + } + protected firstUpdated() { + this.resize() + window.addEventListener('resize', () => { + this.resize() + }) + } + protected resize() { + let parentHeight, parentWidth + if (this.parentElement){ + parentHeight = this.parentElement.offsetHeight + parentWidth = this.parentElement.offsetWidth + }else if(this.parentNode instanceof ShadowRoot){ + parentHeight=(this.parentNode.host as HTMLElement).offsetHeight + parentWidth=(this.parentNode.host as HTMLElement).offsetWidth + } + let height = parentHeight || 10 + let width = parentWidth || 10 + // console.log(height,width,'111111111') + // this.style.setProperty('--autoWidth2--', width + 'px') + // this.style.setProperty('--autoHeight2--', height + 'px') + let proportion: any = typeMy[this.type] + let minOne: any = minAll[this.type] + this.style.setProperty('--autoWidth--', minOne + 'px') + this.style.setProperty('--autoHeight--', minOne * proportion + 'px') + if (height / width >= proportion) { + this.style.setProperty('--autoScale--', width / minOne + '') + } else { + this.style.setProperty('--autoScale--', height / (minOne * proportion) + '') + } + } +} +declare global { + interface HTMLElementTagNameMap { + 'star-weather': StarWeather + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 3d72209..d3a30d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ import './components/radio/radio-group' import './components/radio/radio' import './components/confirm/confirm' import './components/clock/clock' +import './components/weather/weather' import './components/toast/toast' import './components/picker/picker' import './components/overflowmenu/overflowmenu' diff --git a/src/test/panels/root.ts b/src/test/panels/root.ts index 59e7730..8de14da 100644 --- a/src/test/panels/root.ts +++ b/src/test/panels/root.ts @@ -21,6 +21,7 @@ import './container/container' import './radio/radio' import './confirm/confirm' import './clock/clock' +import './weather/weather' import './overflowmenu/overflowmenu' import './switch/switch' import './slider/slider' @@ -317,6 +318,14 @@ export class PanelRoot extends LitElement { iconcolor="green" href="#clock" > +
+ diff --git a/src/test/panels/weather/weather.ts b/src/test/panels/weather/weather.ts new file mode 100644 index 0000000..10bc3e2 --- /dev/null +++ b/src/test/panels/weather/weather.ts @@ -0,0 +1,53 @@ +import {html, css, LitElement} from 'lit' +import {customElement, query, state} from 'lit/decorators.js' +import {StarWeather} from '../../../components/weather/weather.js' +import {weatherData} from './weatherData.js' +@customElement('panel-weather') +export class PanelWeather extends LitElement { + @state() + foo = '' + @state() + data = Array() + @query('#type11') weatherDemo1!: StarWeather + @query('#type12') weatherDemo2!: StarWeather + @query('#type21') weatherDemo3!: StarWeather + @query('#type22') weatherDemo4!: StarWeather + render() { + return html` +
+ + + + +
+ ` + } + static styles = css` + * { + margin: 0; + padding: 0; + box-sizing: border-box; + } + ` + protected firstUpdated() { + // this.weatherDemo1.data = weatherData + // this.weatherDemo2.data = weatherData + // this.weatherDemo3.data = weatherData + this.weatherDemo4.data = weatherData + } +} +declare global { + interface HTMLElementTagNameMap { + 'panel-weather': PanelWeather + } +} diff --git a/src/test/panels/weather/weatherData.ts b/src/test/panels/weather/weatherData.ts new file mode 100644 index 0000000..6b33b75 --- /dev/null +++ b/src/test/panels/weather/weatherData.ts @@ -0,0 +1,30 @@ +export const weatherData = { + location: '长沙市', + weatherInfo: [ + { + date: new Date(), + temperature: { + min: '22℃', + max: '29℃', + }, + weather: { + labelZh: '多云', + labelEn: 'PartlyCloudy', + }, + wind: { + label: '南风', + value: '6级', + }, + humidity: '40%', + airQuality: { + label: '空气质量', + value: '28', + type: '优', + }, + somatosensoryTemperature: '32°C', + visibility: '33km', + ultravioletRys: '强', + }, + {}, + ], +}