记录很早之前写的前端界面(具体时间有点久远)
一、说说模板
采用 适配器(Adapter)原理 来设计这款说说模板,首先看一下完整效果
这是demo样图,需要通过业务需求进行修改的部分
这一部分,就是demo代码了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- 图片定义为 150*150 -->
<style>
#say{
height: 400px;
width: 400px;
background-color: red;
}
.go{
padding: 10px 10px 0px 10px;
}
.go>div{
display: inline-block;
}
/* 第一行:Information */
#userImage{
position: relative;
height: 80px;
width: 80px;
background-color: blue;
}
#userImage+div,#userImage+div+div{
width: 120px;
height: 80px;
}
#userName{
width: 120px;
height: 40px;
background-color: blue;
}
#sayTime{
position: relative;
width: 120px;
height: 30px;
background-color: blue;
top: 10px;
}
#operate{
position: relative;
margin-left: auto;
width: 30px;
height: 20px;
background-color: blue;
}
/* 第二行:text */
#sayText{
position: relative;
height: 30px;
width: 380px;
background-color: blue;
}
/* 第三行:images */
#sayImages{
height: 150px;
width: 380px;
background-color: blue;
}
/* 第四行:position */
.go .ps{
width: 380px;
text-align: right;
}
.ps>div{
display: inline-block;
}
#position{
width: 80px;
height: 20px;
background-color: blue;
}
/* 第五行:用户操作 */
#dianzan,#pinglun,#zhuanfa{
width: 30px;
height: 30px;
background-color: blue;
}
</style>
</head>
<body>
<div id="say">
<div class="go">
<div id="userImage">
</div>
<div>
<div id="userName">
</div>
<div id="sayTime">
</div>
</div>
<div>
<div id="operate">
<!-- 操作模块 -->
</div>
</div>
</div>
<div class="go">
<div id="sayText">
</div>
</div>
<div class="go">
<div id="sayImages">
<!-- 建议是添加图片适配器 -->
</div>
</div>
<div class="go">
<div class="ps">
<div id="position">
</div>
</div>
</div>
<div class="go">
<div class="ps">
<!-- 为了使效果好看,这里最好也是使用适配器(适配器嵌套适配器) -->
<div id="dianzan">
</div>
<div id="pinglun">
</div>
<div id="zhuanfa">
</div>
</div>
</div>
</div>
</body>
</html>
二、登录界面
效果图(因为我这个项目有二维码登录的需求,所以有一个扫描图标,但demo里没有)
如果需要设计出一个这样的功能,可以参考同栏目下的【全栈开发】基于Spring Boot&Vue&Android扫码授权登录
建议:其实啊,我个人不是很推崇直接前端生成验证码数据,这玩意最好还是交给后端,始终要遵守开发安全原则 后端负责生成,前端负责渲染
html代码(使用了jQuery库,这里感谢开源者们的辛勤付出)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
<link rel="stylesheet" href="css/c002.css">
<script src="js/Jquery.js"></script>
</head>
<body>
<div class="main">
<div class="login-title">
用 户 登 录
</div>
<div class="input-data">
<input type="text" required="" id="userName" />
<div class="underlineN"></div>
<label>Name</label>
</div>
<div class="input-data">
<input type="text" required="" id="userPass" />
<div class="underlineP"></div>
<label>Password</label>
</div>
<div class="login-yzm">
<canvas id="canvas" width="120" height="40"></canvas>
<div id="yzm-text">验证码:</div>
<input type="text" id="yzm-input" >
</div>
<div class="login-btn">
<button onclick="eqNull()"><span>登录</span></button>
<button onclick=""><span>注册</span></button>
</div>
</div>
</body>
<script type="text/javascript" src="js/c002.js"></script>
</html>
css代码
* {
margin: 0;
padding: 0;
outline: none;
box-sizing: border-box;
}
/* 设置自适应屏幕大小 */
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: linear-gradient(-135deg, #50c8c2, #4158d0);
}
/* 标题设计 */
.login-title {
text-align: center;
font-size: 20px;
padding-bottom: 20px;
}
/* 输入框设计 */
.main {
width: 450px;
background-color: #fff;
padding: 30px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
/* 模块规格 */
/* 输入框、验证码 */
.main .input-data,.login-yzm {
width: 100%;
height: 40px;
margin: 10px;
position: relative;
}
/* 输入框规格设计 */
.main .input-data input {
width: 100%;
height: 100%;
border: none;
border-bottom: 2px solid silver;
font-size: 17px;
}
/* 动画效果 */
.input-data input:focus~label,
.input-data input:valid~label {
transform: translateY(-20px);
font-size: 15px;
color: #4158D0;
}
/* 输入框文本提醒动画 */
.main .input-data label {
position: absolute;
bottom: 10px;
left: 0;
color: grey;
pointer-events: none;
transition: all 0.3s ease;
}
/* 动画设计 */
.main .input-data .underlineN {
position: absolute;
bottom: 0px;
height: 2px;
width: 100%;
}
.input-data .underlineN::before {
background: #4158D0;
position: absolute;
content: "";
height: 100%;
width: 100%;
transform: scaleX(0);
transition: transform 0.3s ease;
}
.input-data input:focus~.underlineN:before,
.input-data input:valid~.underlineN:before {
transform: scaleX(1);
}
.main .input-data .underlineP {
position: absolute;
bottom: 0px;
height: 2px;
width: 100%;
}
.input-data .underlineP::before {
background: #4158D0;
position: absolute;
content: "";
height: 100%;
width: 100%;
transform: scaleX(0);
transition: transform 0.3s ease;
}
.input-data input:focus~.underlineP:before,
.input-data input:valid~.underlineP:before {
transform: scaleX(1);
}
/* 按钮设计 */
.login-btn {
text-align: center;
}
.login-btn button {
background: radial-gradient(circle, rgba(247, 150, 192, 1) 0%, rgba(118, 174, 241, 1) 100%);
border: none;
color: #fff;
font-family: 'Lato', sans-serif;
border-radius: 10px;
cursor: pointer;
padding: 10px 30px;
position: relative;
top: 20px;
}
/* 按钮触摸和移出 */
.login-btn button:hover {
background: transparent;
color: #76aef1;
}
.login-btn button::before,
.login-btn button::after {
content: '';
position: absolute;
width: 1px;
height: 1px;
box-shadow: -1px -1px 20px 0px rgba(255, 255, 255, 1), -4px -4px 5px 0px rgba(255, 255, 255, 1), 10px 10px 20px 0px rgba(0, 0, 0, .4), 6px 6px 5px 0px rgba(0, 0, 0, .3);
transition: all 0.8s ease;
padding: 0;
}
.login-btn button::before {
top: 0;
right: 0;
}
.login-btn button::after {
bottom: 0;
left: 0;
}
.login-btn button:hover::before,
.login-btn button:hover::after {
height: 100%;
}
.login-btn button span::before,
.login-btn button span::after {
position: absolute;
content: '';
width: 0px;
box-shadow: -1px -1px 20px 0px rgba(255, 255, 255, 1), -4px -4px 5px 0px rgba(255, 255, 255, 1), 10px 10px 20px 0px rgba(0, 0, 0, .4), 6px 6px 5px 0px rgba(0, 0, 0, .3);
transition: all 0.8s ease;
}
.login-btn button span::before {
top: 0;
left: 0;
}
.login-btn button span::after {
bottom: 0;
right: 0;
}
.login-btn button span:hover::before,
.login-btn button span:hover::after {
width: 100%;
}
/* 验证码 */
/* 布局 */
.login-yzm #canvas,#yzm-text{
float: left;
}
.login-yzm #yzm-text,#yzm-input{
position: relative;
left: 50px;
top: 10px;
}
/* 输入框样式 */
.login-yzm #yzm-input{
height: 30px;
width: 80px;
}
js代码
var canvas = document.getElementById("canvas"); //演员
var context = canvas.getContext("2d"); //舞台,getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
var input = document.getElementById("yzm-input"); //获取输入框
var num //定义容器接收验证码
//主函数
$(document).ready(main)
function main() {
//验证用户名是否符合规格
validation_userName()
draw();
}
//输入框区域
function validation_userName() {
var timer = null;
// 输入的值
var editor_start = 0;
// 对比时间的值
var editor_end = 0;
$("#userName").keyup(function() {
clearTimeout(timer) // 每次滚动前 清除一次
timer = setTimeout(save_html_message_fun(), 2000);
})
}
function save_html_message_fun() {
editor_end = $("#userName").val();
if(editor_end.length < 8) {
//输入不满足条件时
$('#userName').nextAll('div').append("<style>.input-data .underlineN::before{background: red}</style>")
} else {
$('#userName').nextAll('div').append("<style>.input-data .underlineN::before{background: #4158D0}</style>")
}
}
// 被动触发触发事件
// 为空判断
function eqNull() {
var userName = $('#userName').val()
if(userName == '') {
alert("用户名不能为空!")
} else if(userName.length < 8) {
alert("请输入正确的账号")
} else if($('#userPass').val() == '') {
alert("密码不能为空!")
} else if($("#yzm-input").val() != num){
reset()
alert("验证码错误!")
} else {
alert("ok" + userName)
}
}
//验证码区域
canvas.onclick = function() {
reset()
}
function reset() {
context.clearRect(0, 0, 120, 40); //在给定的矩形内清除指定的像素
draw();
}
// 随机颜色函数
function getColor() {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return "rgb(" + r + "," + g + "," + b + ")";
}
function draw() {
context.strokeRect(0, 0, 120, 40); //绘制矩形(无填充)
var aCode = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
// 绘制字母
var arr = [] //定义一个数组用来接收产生的随机数
for (var i = 0; i < 4; i++) {
var x = 20 + i * 20; //每个字母之间间隔20
var y = 20 + 10 * Math.random(); //y轴方向位置为20-30随机
var index = Math.floor(Math.random() * aCode.length); //随机索引值
var txt = aCode[index];
context.font = "bold 20px 微软雅黑"; //设置或返回文本内容的当前字体属性
context.fillStyle = getColor(); //设置或返回用于填充绘画的颜色、渐变或模式,随机
context.translate(x, y); //重新映射画布上的 (0,0) 位置,字母不可以旋转移动,所以移动容器
var deg = 90 * Math.random() * Math.PI / 180; //0-90度随机旋转
context.rotate(deg); // 旋转当前绘图
context.fillText(txt, 0, 0); //在画布上绘制“被填充的”文本
context.rotate(-deg); //将画布旋转回初始状态
context.translate(-x, -y); //将画布移动回初始状态
arr[i] = txt //接收产生的随机数
}
num = arr[0] + arr[1] + arr[2] + arr[3] //将产生的验证码放入num
// 绘制干扰线条
for (var i = 0; i < 8; i++) {
context.beginPath(); //起始一条路径,或重置当前路径
context.moveTo(Math.random() * 120, Math.random() * 40); //把路径移动到画布中的随机点,不创建线条
context.lineTo(Math.random() * 120, Math.random() * 40); //添加一个新点,然后在画布中创建从该点到最后指定点的线条
context.strokeStyle = getColor(); //随机线条颜色
context.stroke(); // 绘制已定义的路径
}
// 绘制干扰点,和上述步骤一样,此处用长度为1的线代替点
for (var i = 0; i < 20; i++) {
context.beginPath();
var x = Math.random() * 120;
var y = Math.random() * 40;
context.moveTo(x, y);
context.lineTo(x + 1, y + 1);
context.strokeStyle = getColor();
context.stroke();
}
}