1.css内容展开收起
CSS 实现多行文本展开收起效果 极简教程 - 知乎最终实现效果: 本文主要实现难点: 如何实现 展开 和 收起 切换按钮的文字环绕效果 如何实现多行文本溢出省略效果 如何实现 展开 和 收起 的状态切换 初始 html: <div class="text"> <label cl…https://zhuanlan.zhihu.com/p/400514833https://blog.csdn.net/weixin_43765747/article/details/123041267
https://blog.csdn.net/weixin_43765747/article/details/123041267
1.简单示例 input:checked + label 和 input:checked ~label
1.简单示例 input:checked + label 和 input:checked ~label
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#checked_1:checked + label {
background-color: red;
}
.checked_class:checked ~ label {
background-color: red;
}
</style>
</head>
<body>
<div>
<input id="checked_1" type="checkbox" />
<label for="checked_1">aaaa1</label>
<label for="checked_1">bbbb1</label>
<div>111</div>
</div>
<div>
<input id="checked_2" class="checked_class" type="checkbox" />
<label for="checked_2">aaaa2</label>
<label for="checked_2">bbbb2</label>
<div>222</div>
</div>
</body>
</html>
2.只展开收缩 关键点通过input:checked 选择器来更改后面元素的样式
**不一定是label元素,input:checked + .text**
input:checked + label
input:checked ~ label
input:checked ~ label :相邻同胞选择器,选择被勾选的input标签后 所有的label标签[input 和 label标签有共同的父元素];
input:checked + label :相邻同胞选择器,选择被勾选的input标签后 第一个label标签[input 和 label标签有共同的父元素];
示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#checked_3:checked + .text {
background-color: red;
}
</style>
</head>
<body>
<div>
<input type="checkbox" id="checked_3" />
<div class="text">333333333333333333</div>
</div>
</body>
</html>
完整的只展开收缩
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.content {
display: flex;
}
.text {
width: 475px;
border: aqua solid 1px;
color: #333;
font-size: 14px;
/* 多行文本溢出 */
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.text::before {
content: "";
float: right;
height: 100%;
margin-bottom: -20px;
}
.btn {
color: dodgerblue;
cursor: pointer;
float: right;
clear: both;
margin-right: 8px;
}
#exp {
display: none;
}
#exp:checked + .text {
background-color: pink;
-webkit-line-clamp: 999; /*设置一个足够大的行数就可以了*/
}
.btn::after {
content: "展开";
}
#exp:checked + .text .btn::after {
content: "收起";
}
</style>
</head>
<body>
<div class="content">
<input type="checkbox" id="exp" />
<div class="text">
<label class="btn" for="exp"></label>
<span>
但听得蹄声如雷,十余乘马疾风般卷上山来。马上乘客一色都是玄色薄毡大氅,
里面玄色布衣,但见人似虎,马如龙,人既矫捷,马亦雄骏,每一匹马都是高头
长腿,通体黑毛,奔到近处,群雄眼前一亮,金光闪闪,却见每匹马的蹄铁竟然
是黄金打就。来者一共是一十九骑,人数虽不甚多,气势之壮,却似有如千军万
马一般,前面一十八骑奔到近处,拉马向两旁一分,最后一骑从中驰出</span
>
</div>
</div>
</body>
</html>
3.根据内容长短是否显示展开收起
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.content {
display: flex;
background-color: #ecf5ff;
width: 700px;
padding: 10px;
border-radius: 5px;
box-shadow: 0px 6px 11px 1px rgba(0, 0, 0, 0.06);
}
.text {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
/* 兼容 */
/* line-height: 1.5;
max-height: 4.5em; */
overflow: hidden;
position: relative;
}
.text::before {
content: "";
float: right;
width: 0px;
height: calc(100% - 16px);
}
/* 兼容火狐和苹果浏览器加上省略号 */
/* .btn::before {
content: '...';
position: absolute;
left: -10px;
color: #333;
transform: translateX(-100%)
} */
/* 添加覆盖层,在文字较少时覆盖展开按钮*/
.text::after {
content: "";
width: 100%;
height: 100%;
position: absolute;
background: #ecf5ff;
}
.btn {
border-radius: 5px;
border: none;
color: white;
background-color: #409eff;
float: right;
clear: both;
height: 14px;
line-height: 14px;
font-size: 14px;
padding: 1px 5px;
cursor: pointer;
}
/* 隐藏单选框 */
.handle {
display: none;
}
.handle:checked + .text {
/*设置一个足够大的行数*/
-webkit-line-clamp: 999;
/* 兼容 */
/* max-height: none; */
}
.btn::after {
/*生成文字*/
content: "展开";
}
.handle:checked + .text .btn::after {
/*生成文字*/
content: "收起";
}
/* 在展开时隐藏覆盖层 */
.handle:checked + .text::after {
visibility: hidden;
}
</style>
</head>
<body>
<div class="content">
<input type="checkbox" id="check" class="handle" />
<div class="text">
<label class="btn" for="check"></label>
<!-- 将进酒 -->
君不见黄河之水天上来,奔流到海不复回。君不见高堂明镜悲白发,朝如青丝暮成雪。人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。岑夫子,丹丘生,将进酒,君莫停。与君歌一曲,请君为我侧耳听。钟鼓馔玉不足贵,但愿长醉不愿醒。古来圣贤皆寂寞,惟有饮者留其名。陈王昔时宴平乐,斗酒十千恣欢谑。主人何为言少钱,径须沽取对君酌。五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
</div>
</div>
<br />
<div class="content">
<input type="checkbox" id="check" class="handle" />
<div class="text">
<label class="btn" for="check"></label>
将进酒
</div>
</div>
</body>
</html>
2.本地图片转base64
可以有两种情况,一种是本地上传,然后获取到上传的图片数据去转base64,还有一种是直接拿到图片本地地址或者网页端地址数据去转base64
1.本地上传图片转base64
1. 结构
<input ref="uploadImg" v-show="!imageUrl" type="file" id="file" class="filepath" @change="changepic" accept="image/jpg,image/jpeg,image/png,image/PNG" />
2.逻辑处理
changepic(event: any) {
const reader = new FileReader()
const file = event.target.files[0]
reader.readAsDataURL(file)
//将图片转为base64
reader.onload = e => {
//获取到base64
this.imageUrl = reader.result
// 为了保证上传重复的图片能触发change
// ;(this.$refs.uploadImg as any).value = null
event.target.value = null
}
}
2.直接拿到图片转base64
1.实现函数
base64 (url) {
return new Promise((resolve) => {
const image = new Image()
// 先设置图片跨域属性
image.crossOrigin = 'Anonymous'
// 再给image赋值src属性,先后顺序不能颠倒
image.src = url
image.onload = function () {
const canvas = document.createElement('CANVAS')
// 设置canvas宽高等于图片实际宽高
canvas.width = image.width
canvas.height = image.height
canvas.getContext('2d').drawImage(image, 0, 0)
// toDataUrl可以接收2个参数,参数一:图片类型,参数二: 图片质量0-1(不传默认为0.92)
const dataURL = canvas.toDataURL('image/jpeg')
resolve(dataURL)
}
image.onerror = () => {
resolve({ message: '相片处理失败' })
}
})
}
2.调用示例
async mounted () {
// this.init()
const url = await this.base64('https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg')
console.log(url)
},
遍历的代码如下
const newImgOBj = await Promise.all(this.imgOBj.map(async (item) => {
return {
name: item.name,
img: await this.base64(item.img)
}
}))
console.log(newImgOBj)
3.出图/ 截图 (cesium需要特殊处理)
1.普通出图
// 出图
exportScene() {
const divPlayer = document.querySelector('#player video')
if (!divPlayer) return
const canvas: any = document.createElement('canvas')
canvas.width = divPlayer?.clientWidth
canvas.height = divPlayer?.clientHeight
canvas.getContext('2d').drawImage(divPlayer, 0, 50, canvas.width, canvas.height)
let img = canvas.toDataURL()
const a = document.createElement('a')
a.href = img
a.download = '场景截图' // 下载后文件名
a.style.display = 'none'
document.body.appendChild(a)
a.click() // 点击下载
document.body.removeChild(a) // 下载完成移除元素
}
2.cesium出图时需要注意:必须设置以下配置,要不然出不来图
var viewer = new Cesium.Viewer("csiumContain", {
homeButton: false,//是否显示Home按钮
animation: false,//是否显示动画控件
timeline: false,//是否显示时间线控件
fullscreenButton: false,
baseLayerPicker: false,//是否显示图层选择控件
sceneModePicker: true, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
geocoder: false, //是否显示地名查找控件
sceneModePicker: false,//是否显示3D/2D选择器
//必须配置这里
contextOptions: {
webgl: {
alpha: true,
depth: true,
stencil: true,
antialias: true,
premultipliedAlpha: true,
// preserveDrawingBuffer 通过canvas.toDataURL()实现截图需要将该项设置为true
preserveDrawingBuffer: true,
failIfMajorPerformanceCaveat: true
}
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>导出图片</title>
<script src="../libs/Cesium/Cesium.js"></script>
<link rel="stylesheet" href="../libs/Cesium/Widgets/widgets.css">
<style>
html,
body,
#csiumContain {
width: 100%;
height: 100%;
margin: 0px;
}
.cesium-widget-credits {
display: none !important;
/*去除Cesium默认版权信息*/
}
.tool-bar {
position: absolute;
top: 1vh;
left: 2vw;
z-index: 999999;
}
.cesium-viewer-infoBoxContainer {
display: none !important;
}
</style>
</head>
<body>
<div id="toolbar" class="param-container tool-bar layui-form-item">
<button onclick="saveToFile()">场景出图</button>
</div>
<div id="csiumContain"></div>
<script>
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);
var viewer = new Cesium.Viewer("csiumContain", {
homeButton: false,//是否显示Home按钮
animation: false,//是否显示动画控件
timeline: false,//是否显示时间线控件
fullscreenButton: false,
baseLayerPicker: false,//是否显示图层选择控件
sceneModePicker: true, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
geocoder: false, //是否显示地名查找控件
sceneModePicker: false,//是否显示3D/2D选择器
contextOptions: {
webgl: {
alpha: true,
depth: true,
stencil: true,
antialias: true,
premultipliedAlpha: true,
//通过canvas.toDataURL()实现截图需要将该项设置为true
preserveDrawingBuffer: true,
failIfMajorPerformanceCaveat: true
}
}
})
function saveToFile() {
let canvas = viewer.scene.canvas;
let image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
let link = document.createElement("a");
let blob = dataURLtoBlob(image);
let objurl = URL.createObjectURL(blob);
link.download = "scene.png";
link.href = objurl;
link.click();
}
function dataURLtoBlob(dataurl) {
let arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
</script>
</body>
</html>