582
社区成员
这个作业属于哪个课程 | 软件工程-23年春季学期 |
---|---|
这个作业要求在哪里 | 结对第二次作业--编程实现 |
结对学号 | 222000224 022000405 |
这个作业的目标 | 编程实现上一次原型设计作业的部分功能 |
其他参考文献 | GoogleStyleGuides、CSDN、《构建之法》 |
本项目的数据来源于 Official Website of the Australian Open 2023 | AO,该爬取行为仅用于课程教学。
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
• Estimate | • 估计这个任务需要多少时间 | 10 | 10 |
Discussion | 结对讨论 | 270 | 270 |
• Analysis | • 分析功能,决定分工 | 120 | 150 |
• Coding Standard | • 代码规范 | 120 | 100 |
• Design Spec | • 生成设计文档 | 30 | 20 |
Development | 开发 | 660 | 840 |
• Design | • 具体设计 | 180 | 200 |
• Coding | • 具体编码 | 360 | 540 |
• Code Review | • 代码复审 | 120 | 100 |
Reporting | 报告 | 140 | 130 |
• Test Report | • 撰写博客 | 90 | 100 |
• Size Measurement | • 计算工作量 | 20 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 20 |
合计 | 1080 | 1450 |
澳大利亚网球公开赛
视频演示:
由于两人为舍友,大多数交流都由口头完成。
我们在设计项目时,最先想到的是参考上次的原型模型和澳大利亚网球公开赛的官网。因此我们的成品也与这两者在外观和交互逻辑上都高度还原。
导航栏与标题栏部分:
在实现每日赛况时,我们也遇到了许多问题:
晋级图部分:
#navbar-nav{
position: relative;
display: flex;
flex-wrap:nowrap;
align-items: center;
justify-content: space-between;
padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);
align-items: center; /* 将列表项垂直居中 /
height: 50px; / 设置列表项高度 */
gap: 10px;
padding:10px 30% 0px 30%;
}
#navbar-nav .nav-item .nav-link{
flex-wrap:nowrap ;
}
/选中动画 条/
#navbar-nav .nav-item .nav-link {
position: relative;
}
#navbar-nav .nav-item .nav-link::after {
content: '';
display: block;
width: 0%;
height: 2px;
background-color:rgb(45, 125, 245);
position: absolute;
bottom: -2px;
left: 25%;
transition: width 0.3s ease-out;
}
#navbar-nav .nav-item .nav-link:hover::after,
#navbar-nav .nav-item .nav-link:focus::after {
width: 50%;
}
/选项激活/
#navbar-nav .nav-item .active {
font-weight: bold;
color: rgb(0,157,255);
}
/选中动画 字体/
.nav-link-animate {
transition: color 0.5s ease;
}
.nav-link-animate:hover {
color: rgb(45, 125, 245);
}
#navbar-nav .nav-item .active::after {
content: '';
display: block;
width: 50%;
height: 2px;
background-color: rgb(0,157,255);
margin-top: 4px;
}
思路介绍:为导航栏的每个选项添加一个active类,当点击某个选项时,为其添加active类,同时移除其他选项的active类。这样,我们就能够通过active类来改变选项的样式。
为每个选项添加一个下划线,当选项被激活时,下划线的宽度变为50%,同时,选项的颜色也会发生变化。
导航栏中澳大利亚网球公开赛的logo显示参考了官网,采用了svg的矢量图形式:
```html
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" viewBox="0 0 88 44" height='30px'>
<title>Australian Open Logo</title>
<path
d="M65.4 31.1c-5.2 0-9.4-4.2-9.4-9.5 0-5.2 4.2-9.5 9.4-9.5s9.4 4.2 9.4 9.5-4.2 9.5-9.4 9.5M65.5 0C53.6 0 44 9.7 44 21.7s9.6 21.7 21.5 21.7S87 33.7 87 21.7C86.9 9.7 77.3 0 65.5 0">
</path>
<path d="M25 1h-6.9L0 42.5h13.4L21.6 21l8.1 21.5h13.4z"></path>
</svg>
/*svg颜色*/
path {
fill: rgb(0,145,210);
}
每日赛况中,用于自适应网页大小的html代码片段:
#con1{
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.score-row {
flex-basis: 320px;
flex-grow: 1;
width: 100%;
height: 200px;
margin: 10px;
border: 1px solid #e6e6e6;
-webkit-transition: all .25s ease;
transition: all .25s ease
}
思路介绍:当网页宽度小于等于768px时,flex-basis的值为320px,此时,每行显示一个元素;当网页宽度大于768px时,flex-basis的值为100%,此时,每行显示两个元素。
选手排名中,用于自适应网页大小的html代码片段:
<div style="width:90%;margin:0 5%;display: flex;flex-wrap: wrap;justify-content: center;">
<div style="flex: 1 0 auto;flex-basis:420px;width:100%;left:0%;">
<div class="containerL">
...
</div>
</div>
<div style="flex: 1 0 auto;flex-basis:420px;width:100%;right:0%;">
<div class="containerR">
...
</div>
</div>
</div>
<div style="width:90%;margin:0 5%;display: flex;flex-wrap: wrap;justify-content: center;">
<div style="flex: 1 0 auto;flex-basis:420px;width:100%;left:0;">
<div class="container2L">
<p class="title" id="Title1">Men’s Singles Aces <br> Leaders</p>
</div>
<div class="containerTableL">
...
</div>
</div>
<div style="flex: 1 0 auto;flex-basis:420px;width:100%;right:0">
<div class="container2R">
<p class="title" id="Title2">Women’s Singles Aces <br> Leaders</p>
</div>
<div class="containerTableR">
...
</div>
</div>
</div>
晋级图中用于连线的js代码片段:
var cards = document.querySelectorAll(".match-c");
var lines = document.getElementById("lines");
for (var i = 0; i < cards.length; i++) {
const rect = cards[i].getBoundingClientRect();
const refRect = lines.getBoundingClientRect();
var y = rect.top + rect.height / 2 - refRect.top;
var x1 = rect.left - 55 - refRect.left;
var x2 = rect.left - refRect.left;
var x3 = rect.right - refRect.left;
var x4 = rect.right + 55 - refRect.left;
/*将x1,x2,x3,x4用path连线*/
var path1 = document.createElementNS("http://www.w3.org/2000/svg", "path");
var path2 = document.createElementNS("http://www.w3.org/2000/svg", "path");
var path3 = document.createElementNS("http://www.w3.org/2000/svg", "path");
path1.setAttribute("x1", x1);
path1.setAttribute("y1", y);
path1.setAttribute("x2", x2);
path1.setAttribute("y2", y);
path1.setAttribute("d", "M" + x1 + " " + y + " " + x2 + " " + y);
path1.setAttribute("class", "connection");
path2.setAttribute("x1", x2);
path2.setAttribute("y1", y);
path2.setAttribute("x2", x3);
path2.setAttribute("y2", y);
path2.setAttribute("d", "M" + x2 + " " + y + " " + x3 + " " + y);
path2.setAttribute("class", "connection_2");
path3.setAttribute("x1", x3);
path3.setAttribute("y1", y);
path3.setAttribute("x2", x4);
path3.setAttribute("y2", y);
path3.setAttribute("d", "M" + x3 + " " + y + " " + x4 + " " + y);
path3.setAttribute("class", "connection");
lines.appendChild(path1);
lines.appendChild(path2);
if (i != cards.length - 1) {
lines.appendChild(path3);
}
/*x1="646" y1="237" x2="756" y2="468" class="connection" id="line11*/
}
var links = [[1, 2], [4, 5], [8, 9], [11, 12], [3, 6], [10, 13], [7, 14]];
for (var i = 0; i < links.length; i++) {
var rectA = cards[links[i][0] - 1].getBoundingClientRect();
var rectB = cards[links[i][1] - 1].getBoundingClientRect();
var refRect = lines.getBoundingClientRect();
var y1 = rectA.top + rectA.height / 2 - refRect.top;
var y2 = rectB.top + rectB.height / 2 - refRect.top;
var x = rectA.right - refRect.left + 55;
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("x1", x);
path.setAttribute("y1", y1);
path.setAttribute("x2", x);
path.setAttribute("y2", y2);
path.setAttribute("d", "M" + x + " " + y1 + " " + x + " " + y2);
path.setAttribute("class", "connection");
lines.appendChild(path);
}
思路介绍:首先获取所有的比赛卡片,然后遍历所有的卡片,获取每个卡片的位置信息,然后根据这些位置信息计算出每两个卡片之间的连线的起点和终点的坐标,然后使用svg的path标签将这些坐标连接起来,实现连线的效果。