要求:
在六个不同颜色的牌面上放置在一个文件夹下随机选取的六张照片,放在前端页面上,点击可以翻转过来,再次点击翻转回去,在不刷新网页的前提下,牌面后的图片是不会变化的,刷新页面则会重新在特定文件夹下随机选取六张放置在牌面下。点击查看全部图片可以看到文件夹下的所有图片以及图片的名称,使用servlet和Vue完成。
思路:
首先编写六个牌面,然后制定旋转动画,使旋转背面放入图片路径(路径需要在servlet中随机获取),在Vue代码区定义一个数组,在六个牌面设置点击事件,每点击一下对于的数组加一,然后用余数来规定牌面的正反。展示所有图片的前端也是需要靠随机图片的路径来获取。定义一个JsonUtil工具类,将数据转化成json格式,再响应给浏览器。编写ImgUtil类,可以将构造缓冲区,使图片显示更流畅,提高读写效率。
代码如下:
ImgC.java
package com.hp.utils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
public class ImgUtil {
//响应某个图片给浏览器
/*
imgPath 表示图片的全路径 例如 C:\学习\暑假培训\beauty/a.webp
*/
public static void responseImg(String imgPath, HttpServletResponse resp){
try{
FileInputStream is = new FileInputStream(imgPath);
ServletOutputStream os = resp.getOutputStream();
//构建缓冲流,提高读写效率
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] bytes = new byte[1000];
//2.循环,边读边写
while ((bis.read(bytes))!=-1){
os.write(bytes);
}
//关闭资源
bos.flush();
bos.close();
bis.close();
os.close();
is.close();
}catch (Exception e){
}
}
}
RandomImgC.java:
package com.hp.controller;
import com.hp.utils.ImgUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
@WebServlet("/randomImgC")
public class RandomlmgC extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取某个文件夹下所有的文件名称
String[] fileNames = new File("C:\\学习\\暑假培训\\beauty/").list();
String imgName=fileNames[(int)Math.floor(Math.random()*fileNames.length)];//随机生成
System.out.println("随机生成的图片名称是:"+imgName);
ImgUtil.responseImg("C:\\学习\\暑假培训\\beauty/"+imgName,resp);
}
}
ImgUtil.java:
package com.hp.utils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
public class ImgUtil {
//响应某个图片给浏览器
/*
imgPath 表示图片的全路径 例如 C:\学习\暑假培训\beauty/a.webp
*/
public static void responseImg(String imgPath, HttpServletResponse resp){
try{
FileInputStream is = new FileInputStream(imgPath);
ServletOutputStream os = resp.getOutputStream();
//构建缓冲流,提高读写效率
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] bytes = new byte[1000];
//2.循环,边读边写
while ((bis.read(bytes))!=-1){
os.write(bytes);
}
//关闭资源
bos.flush();
bos.close();
bis.close();
os.close();
is.close();
}catch (Exception e){
}
}
}
JsonUtil.java:
package com.hp.utils;
import com.alibaba.fastjson.JSON;
import javax.servlet.http.HttpServletResponse;
public class JsonUtil {
public static void transJson(Object obj, HttpServletResponse resp){
try {
//数据转化成json格式,再响应给浏览器
String josn_string = JSON.toJSONString(obj);
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(josn_string);
}catch (Exception e){
e.printStackTrace();
}
}
}
前端代码页:
beauty.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue/vue.min.js"></script>
<style>
.f{
display: flex;
justify-content: space-around;
}
.f>div{
width: 150px;
height: 250px;
cursor: pointer;
background-size: 150px 250px;
margin-left: 20px;
}
.f>div:nth-child(odd){
background-color: aqua;
}
.f>div:nth-child(even){
background-color: rebeccapurple;
}
@keyframes xz {
0%{
transform: rotateY(0deg);
background-image: url("");
}100%{
transform: rotateY(180deg);
}
}
@keyframes xzr {
0%{
transform: rotateY(180deg);
}100%{
transform: rotateY(0deg);
background-image: url("");
}
}
.xz{
animation: xz 1s linear 1 forwards;
}
.xzr{
animation: xzr 1s linear 1 forwards;
}
</style>
</head>
<body>
<div id="app">
<button onclick="location.assign('/home.html')">进入后宫,观看三千佳丽</button>
<div class="f">
<div v-for="i in 6" @click="xzImg($event,i)"></div>
</div>
<hr>
<img src="/randomImgC" alt="" width="400" height="450"><br>
<button onclick="location.reload()">点击换一张图片</button>
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
//记录每个图片被点击的次数
arr:[0,0,0,0,0,0]
},
methods:{
xzImg(e,i){
if(this.arr[i-1]%2){
e.target.style.backgroundImage='url()'
e.target.className='xzr'
console.log('xz')
}else {
e.target.style.backgroundImage='url(/randomImgC?'+i+')'
e.target.className='xz'
console.log('xz')
}
console.log(e.target,i,this.arr)
this.arr[i-1]++
}
}
})
</script>
</html>
home.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后宫</title>
<script src="vue/vue.min.js"></script>
<script src="vue/axios.min.js"></script>
<style>
.f{
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.f>div{
width: 150px;
height: 250px;
border: 1px solid rebeccapurple;
margin: 30px;
}
.f>div>img{
width: 150px;
height: 230px;
}
</style>
</head>
<body>
<div id="app">
<div class="f">
<div v-for="img in imgNames">
<img :src="imgSrc(img)" alt=""><br>
{{img}}
</div>
</div>
</div>
</body>
<script>
/*
在axios的回调函数then中,
如果是普通函数function(){this} 普通函数中的this指代js的bom顶层对象,类似于java中的Object
如果使用箭头函数()=>{this},此时this表示整个vue实例,也就是new Vue({})函数的返回值vueObj
*/
const vueObj = new Vue({
el:'#app',
data:{
imgNames:[]
},
methods:{
imgSrc(imgName){
return '/imgC?action=getImgByName&imgName='+imgName
},
getAllImgNames(){
axios.get('/imgC?action=getAllImgNames').then((resp)=>{
this.imgNames=resp.data
console.log(resp.data,1,this)
})
},
},
mounted(){
this.getAllImgNames()
//此处的this代表整个vue对象
console.log(this.imgNames,2,this)
}
})
</script>
</html>