一、小程序效果展示:
二、小程序功能
(一)基本功能
1.导航栏显示”今日天气“
2.点击地区文字可以修改地区
3.显示该地区的天气和温度
4.显示天气对应的图片
(二)额外功能
1.横向显示给该地区接下来24小时的天气情况。
2.添加背景面板
3.如果地区为雨天,增加雨点效果
三、基本步骤
-
API密钥申请与服务器域名
(1)首先,进入和风天气开发服务 ~ 强大、丰富的天气数据服务网址,注册和风天气账号并申请API密钥。
(2)然后,进入微信小程序控制台微信公众平台。登录账号后,进入管理=>开发管理=>服务器域名,设置request的合法域名。
2. 创建项目,并配置文件
(1)创建新的项目
(2)配置文件
在https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/demo2_file.zip网址下载天气图片,创建文件夹images,将下载的天气图标放入images文件夹中。
删除不需要的文件和代码
3.设计导航栏
修改app.json代码,对window属性进行调整,代码如下:
"window": { "navigationBarTitleText": "今日天气", "navigationBarBackgroundColor": "#3883FA" },
4. **页面设计**
(1)背景设计:
选择合适的图片放入/images/icon中,然后编写如下代码:
<view class='container'>
<image class="background-image" src="/images/icons/back.png" mode="aspectFill"></image>
</view>
对应container和background-image的css设置如下:
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.background-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1; /* 将背景图放在最底层 */
}
```
设计后效果如下:
(2)区域一:地区选择
使用picker控件,进行地域的选择。:
<!-- 区域1:地区选择器 -->
<picker mode='region' bindchange='regionChange'>
<view>{{region}}</view>
</picker>
效果图如下所示:
(3)区域二: 天气信息显示
使用text控件
<view class="horizon-container">
<text> {{now.temp}}° </text>
<text class="weather-text">{{now.text}}</text>
</view>
(4)区域三: 天气图标
使用image控件显示天气图标
<!-- 区域3:天气图标 -->
<image src='/images/{{now.icon}}.png' mode='widthFix'></image>
(5)区域四:显示接下来24小时天气
使用scroll-view控件,然后使用for循环从js代码中获取24个小控件:
<scroll-view scroll-x="true" class="hourly-weather">
<block wx:for="{{hours}}" wx:key="index">
<view class="hour-item">
<text class="hour-time">{{item.time}}:00</text>
<image class="hour-icon" src="/images/{{item.icon}}.png"></image>
<text class="hour-temp">{{item.temp}}°</text>
</view>
</block>
</scroll-view>
为了美观,对应css如下:
.hourly-weather {
width: 100%;
display: flex;
overflow-x: auto; /* 允许横向滚动 */
white-space: nowrap; /* 防止内容换行 */
padding: 10px 0;
align-items: center;
}
.hour-item {
width: 12%;
flex-shrink: 0;
display: inline-block;
align-items: center; /* 水平居中 */
margin-right: 10px;
color: white;
}
.hour-time {
display: block;
font-size: 14px;
}
.hour-icon {
display: block;
width: 30px;
height: 30px;
margin: 5px 0;
}
.hour-temp {
display: block;
font-size: 16px;
font-weight: bold;
}
实现效果如下:
(6)区域五: 多行天气信息
显示2行3列的天气信息
<view class='detail'>
<view class="bar">
<view class='box'>湿度</view>
<view class='box'>气压</view>
<view class='box'>能见度</view>
</view>
<view class="bar">
<view class='box'>{{now.humidity}}%</view>
<view class='box'>{{now.pressure}}hPa</view>
<view class='box'>{{now.vis}}km</view>
</view>
<view class="bar">
<view class='box'>风向</view>
<view class='box'>风速</view>
<view class='box'>风力</view>
</view>
<view class="bar">
<view class='box'>{{now.windDir}}</view>
<view class='box'>{{now.windScale}}km/h</view>
<view class='box'>{{now.windSpeed}}级</view>
</view>
</view>
.detail {
width: 100%;
display: flex;
flex-direction: column;
}
.bar {
display: flex;
flex-direction: row;
margin: 20rpx 0;
}
.box {
width: 33.3%;
text-align: center;
}
对应效果如下:
5. **功能实现**
(1)创建页面初始数据信息
data用于连接wxml的数据,包括地区、地区对应id、当前的天气状况(8项指标)以及接下来24小时的天气情况
```js
data: {
region:['山东省','青岛市','黄岛区'],
id: 101220301,//对应的编号
now: {
temp: 0,//温度
text:'未知',//内容
icon:'999',//天气代码
humidity: 0,//湿度
pressure: 0,//大气压
vis: 0, //能见度
windDir: 0,//风向
windScale: 0,//风级
windSpeed: 0//风速
},
hours: [ //用于获取24小时的天气情况
{ time: 0, icon: '100', temp: 20 },
{ time: 1, icon: '100', temp: 19 },
{ time: 2, icon: '100', temp: 19 },
{ time: 3, icon: '100', temp: 19 },
{ time: 4, icon: '100', temp: 19 },
{ time: 5, icon: '100', temp: 19 },
{ time: 6, icon: '100', temp: 19 },
{ time: 7, icon: '100', temp: 19 },
{ time: 8, icon: '100', temp: 19 },
{ time: 9, icon: '100', temp: 19 },
{ time: 10, icon: '100', temp: 19 },
{ time: 11, icon: '100', temp: 19 },
{ time: 12, icon: '100', temp: 19 },
{ time: 13, icon: '100', temp: 19 },
{ time: 14, icon: '100', temp: 19 },
{ time: 15, icon: '100', temp: 19 },
{ time: 16, icon: '100', temp: 19 },
{ time: 17, icon: '100', temp: 19 },
{ time: 18, icon: '100', temp: 19 },
{ time: 19, icon: '100', temp: 19 },
{ time: 20, icon: '100', temp: 19 },
{ time: 21, icon: '100', temp: 19 },
{ time: 22, icon: '100', temp: 19 },
{ time: 23, icon: '100', temp: 18 }
]
},
```
(2)getWeather函数,用于**获取某地区的天气信息**(调用该函数前,应该知道对应地区的ID)。
首先向API发送id和key,获取当地的当前天气情况,然后判断是否是雨天。如果是雨天调用drawRain函数,产生雨滴效果,否则不产生雨滴效果。
getWeather: function() {
console.log(this.data.id)
let that = this
wx.request({
url: 'https://devapi.qweather.com/v7/weather/now',
data: {
location: that.data.id,
key: "32481277610c405b9f6cbfa910c2d165"
},
success: function(res) {
console.log(res.data)
that.setData({now: res.data.now})
if(res.data.now.icon>=300&&res.data.now.icon<=470) //用于产生雨点效果
{
that.drawRain();
}
else{
that.clearRain()
}
}
})
},
(3)getHourly函数,用于获取某地区接下来24小时天气情况
向apihttps://devapi.qweather.com/v7/weather/24h发送id和key,获取数据信息;其中时间信息需要截取第11到13位,从而获得对应的小时数。```
getHourly:function(){
let that = this
wx.request({
url: 'https://devapi.qweather.com/v7/weather/24h',
data:{
location:that.data.id,
key: "32481277610c405b9f6cbfa910c2d165"
},
success:function(res){
console.log(res.data)
let hourlyData = res.data.hourly.map(item => {
let st = item.fxTime.slice(11, 13); // 从 fxTime 中提取时间(小时)
return {
temp: item.temp,
time: st,
icon: item.icon
};
});
// 更新页面数据
that.setData({
hours: hourlyData
});
}
})
(4)getID函数,用于获取某个地区的ID,然后调用getWeather和getHourly。```js
getId: function(city) {
city = city.slice(0, -1)
let that = this
wx.request({
url: 'https://geoapi.qweather.com/v2/city/lookup',
data: {
location: city,
key: "32481277610c405b9f6cbfa910c2d165"
},
success: function(res) {
that.setData({id: res.data.location[0].id})
that.getWeather()
that.getHourly()
}
})
},
(5)当选择器发生变化时,可以自动加载新的地区的天气情况
regionChange: function(e) {
this.setData({region: e.detail.value})
this.getId(this.data.region[1])
},
(6)页面加载函数,进入页面首先调用getId,更新天气信息
onLoad: function (options) {
this.getId(this.data.region[1])
},
(7)雨滴效果实现
首先,它通过获取屏幕宽高来确定绘制区域,然后生成一定数量的雨滴,每个雨滴都有随机的初始位置、长度、透明度和下落速度。通过在画布上绘制每个雨滴并不断更新其位置,实现了雨滴从上到下的下落效果。当雨滴超出屏幕底部时,它们会重新出现在顶部,循环往复,形成持续的降雨动画效果。
drawRain: function () {
const ctx = wx.createCanvasContext('rainCanvas', this);
const w = wx.getSystemInfoSync().windowWidth;
const h = wx.getSystemInfoSync().windowHeight;
const raindrops = [];
const numDrops = 100;
for (let i = 0; i < numDrops; i++) {
raindrops.push({
x: Math.random() * w,
y: Math.random() * h,
length: Math.random() * 20 + 10,
opacity: Math.random() * 0.5 + 0.5,
speed: Math.random() * 3 + 2
});
}
const draw = () => {
ctx.clearRect(0, 0, w, h);
ctx.setFillStyle('rgba(174,194,224,0.5)');
ctx.setStrokeStyle('rgba(174,194,224,0.5)');
ctx.setLineWidth(2);
raindrops.forEach(drop => {
ctx.beginPath();
ctx.moveTo(drop.x, drop.y);
ctx.lineTo(drop.x, drop.y + drop.length);
ctx.stroke();
drop.y += drop.speed;
if (drop.y > h) {
drop.y = -drop.length;
drop.x = Math.random() * w;
}
});
ctx.draw();
requestAnimationFrame(draw);
};
draw();
},
获取指定 `canvas-id` 的画布上下文,调用 `clearRect` 方法清空整个画布区域,然后通过 `ctx.draw()` 执行清空操作。最后,使用 `this.setData({ isRaining: false })` 更新状态,表示降雨已停止。
clearRain: function() {
const ctx = wx.createCanvasContext('rainCanvas'); // 假设你的 canvas-id 为 'rainCanvas'
ctx.clearRect(0, 0, this.data.canvasWidth, this.data.canvasHeight); // 清空整个画布
ctx.draw(); // 执行清空操作
this.setData({ isRaining: false });
},
对应的画布如下:
.rain-canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1; /* 让雨滴效果在底层 */
}
实现效果如下:
四、遇到问题:
描述实验过程中所遇到的问题,以及是如何解决的。有哪些收获和体会,对于课程的安排有哪些建议。
问题:在设计查看24小时的天气情况时,不能正常横向显示,如图:
解决方案:修改hour-item,将display改为inline-block;然后为了保证其他组件垂直排列,将包含的组件的display设置位block