天学习了平面动画,今天来3D动画:
css3的强大之处就在于它可以用很少量的标签,来实现一些要用到插件或者js,jq很多代码才能实现的复杂功能。随着css3版本的推进,各浏览器的兼容性也会越来越好,开发会很容易。
实现上图的关键点在于,如何布局不了解css3的可能会说要定位,其实不然,我们只需要transform的rotate和translate即可轻松实现旋转位移.至于图片了可以用img也可以直接背景图。下面是我的页面结构和css样式
<style>
*{margin:0; padding:0; list-style: none;}
div{
width: 105px;
height: 150px;
margin:100px auto;
-webkit-perspective: 1000;
-webkit-perspective-origin: center center;
}
ul{
width: 105px;
height: 150px;
position: relative;
-webkit-transform-style: preserve-3d;
-webkit-transform:rotateX(-16deg) rotateY(0deg) rotateZ(0deg);
-webkit-animation: ;
}
@-webkit-keyframes run{
from{ }
to{ }
}
ul li{width: 105px; height: 150px; position: absolute; -webkit-background-size:100% 100%;}
ul li:nth-child(1){
background-image: url(images/01.jpg);
-webkit-transform: translateZ(200px);
}
ul li:nth-child(2){
background-image: url(images/02.jpg);
-webkit-transform:rotateY(30deg) translateZ(200px);
}
ul li:nth-child(3){
background-image: url(images/03.jpg);
-webkit-transform:rotateY(60deg) translateZ(200px);
}
ul li:nth-child(4){
background-image: url(images/04.jpg);
-webkit-transform:rotateY(90deg) translateZ(200px);
}
ul li:nth-child(5){
background-image: url(images/05.jpg);
-webkit-transform:rotateY(120deg) translateZ(200px);
}
ul li:nth-child(6){
background-image: url(images/06.jpg);
-webkit-transform:rotateY(150deg) translateZ(200px);
}
ul li:nth-child(7){
background-image: url(images/07.jpg);
-webkit-transform:rotateY(180deg) translateZ(200px);
}
ul li:nth-child(8){
background-image: url(images/08.jpg);
-webkit-transform:rotateY(210deg) translateZ(200px);
}
ul li:nth-child(9){
background-image: url(images/09.jpg);
-webkit-transform:rotateY(240deg) translateZ(200px);
}
ul li:nth-child(10){
background-image: url(images/10.jpg);
-webkit-transform:rotateY(270deg) translateZ(200px);
}
ul li:nth-child(11){
background-image: url(images/11.jpg);
-webkit-transform:rotateY(300deg) translateZ(200px);
}
ul li:nth-child(12){
background-image: url(images/12.jpg);
-webkit-transform:rotateY(330deg) translateZ(200px);
}
</style>
结构是div抱着ul和li有多少图片就有多少个li(这里就不展示了)
只有这个相册就可以旋转了么,当然不会,各位还需要在上文@-webkit-keyframes处补全animation动画即可,animation动画在上篇《纯css实现无缝滚动》中又详细代码 拿过来即可
这里是云端源想IT,帮你轻松学IT”
嗨~ 今天的你过得还好吗?
忧虑像一把摇椅
它可以使你有事做
但不能使你前进一步
- 2024.04.10 -
在深入探讨CSS变形动画之前,让我们先探讨一下掌握它之后你可以实现哪些有趣的效果。
学习了CSS变形动画之后,你将能够为你的网页添加引人注目的动态效果,例如创建一个立体的3D魔方,或者设计一个引人入胜的旋转菜单。这些仅仅是众多可能性中的一小部分,但或许可以勾起我们的学习兴趣。
CSS变形动画是利用CSS3的transform属性创建的动画效果。它可以使元素旋转、缩放、倾斜甚至翻转,让静态的网页元素动起来,为用户带来更加丰富的交互体验。
坐标系统
首先我们要学习的变形动画,想达到在上图中出现的3D效果单纯的X与Y两个轴是实现不了的,还需要加入一条纵深轴,即Y轴的参与才有一个3D的视觉感受。
那么如何来理解X,Y,Z这三条轴的关系呢?可以看一下下面这张图。
X和Y轴都非常好理解,怎么理解这个Z轴呢?
CSS的中文名称叫做层叠样式表,那么它肯定是一层一层的。之前学习过z-index就是用来设置层的优先级,优先级越高越在上面,也可以理解为离我们肉眼越近,它把优先级低的层给盖住了,所以Z轴可以理解为我们观察的视角与被观察物体之间的一条轴。
使用 transform 来控制元素变形操作,包括控制移动、旋转、倾斜、3D转换等。
下面我们通过一些例子来演示一下,比较常用的变形操作:
2.1 位移 translate()
translate()函数可以将元素向指定的方向移动,类似于position中的relative。或以简单的理解为,使用translate()函数,可以把元素从原来的位置移动,而不影响在X、Y轴上的任何Web组件。
想象一下,当你滚动页面时,一个元素平滑地从一个位置滑向另一个位置,这种流畅的过渡效果可以大大提升用户体验。
translate我们分为三种情况:
1)translate(x,y)水平方向和垂直方向同时移动(也就是X轴和Y轴同时移动)
2)translateX(x)仅水平方向移动(X轴移动)
3)translateY(Y)仅垂直方向移动(Y轴移动)
实例演示:通过translate()函数将元素向Y轴下方移动50px,X轴右方移动100px。
HTML代码:
<div class="wrapper">
<div>我向右向下移动</div>
</div>
CSS代码:
.wrapper {
width: 200px;
height: 200px;
border: 2px dotted red;
margin: 20px auto;
}
.wrapper div {
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
background: orange;
color: #fff;
-webkit-transform: translate(50px,100px);
-moz-transform:translate(50px,100px);
transform: translate(50px,100px);
}
演示结果:
旋转rotate()函数通过指定的角度参数使元素相对原点进行旋转。旋转不仅可以是固定的度数,还可以是动态变化的,创造出无限的可能性。
它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度。如果这个值为正值,元素相对原点中心顺时针旋转;如果这个值为负值,元素相对原点中心逆时针旋转。如下图所示:
HTML代码:
<div class="wrapper">
<div></div>
</div>
CSS代码:
.wrapper {
width: 200px;
height: 200px;
border: 1px dotted red;
margin: 100px auto;
}
.wrapper div {
width: 200px;
height: 200px;
background: orange;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
演示结果:
扭曲skew()函数能够让元素倾斜显示。这种效果常常用于模拟速度感或者倾斜的视觉效果。
它可以将一个对象以其中心位置围绕着X轴和Y轴按照一定的角度倾斜。这与rotate()函数的旋转不同,rotate()函数只是旋转,而不会改变元素的形状。skew()函数不会旋转,而只会改变元素的形状。
Skew()具有三种情况:
1)skew(x,y)使元素在水平和垂直方向同时扭曲(X轴和Y轴同时按一定的角度值进行扭曲变形);
第一个参数对应X轴,第二个参数对应Y轴。如果第二个参数未提供,则值为0,也就是Y轴方向上无斜切。
2)skewX(x)仅使元素在水平方向扭曲变形(X轴扭曲变形);
3)skewY(y)仅使元素在垂直方向扭曲变形(Y轴扭曲变形)
示例演示:
通过skew()函数将长方形变成平行四边形。
HTML代码:
<div class="wrapper">
<div>我变成平形四边形</div>
</div>
CSS代码:
.wrapper {
width: 300px;
height: 100px;
border: 2px dotted red;
margin: 30px auto;
}
.wrapper div {
width: 300px;
height: 100px;
line-height: 100px;
text-align: center;
color: #fff;
background: orange;
-webkit-transform: skew(45deg);
-moz-transform:skew(45deg)
transform:skew(45deg);
}
演示结果:
缩放 scale()函数 让元素根据中心原点对对象进行缩放。这不仅可以用来模拟放大镜效果,还可以创造出元素的进入和退出动画,比如一个图片慢慢缩小直至消失。
缩放 scale 具有三种情况:
1) scale(X,Y)使元素水平方向和垂直方向同时缩放(也就是X轴和Y轴同时缩放)。
例如:
div:hover {
-webkit-transform: scale(1.5,0.5);
-moz-transform:scale(1.5,0.5)
transform: scale(1.5,0.5);
}
注意:Y是一个可选参数,如果没有设置Y值,则表示X,Y两个方向的缩放倍数是一样的。
2)scaleX(x)元素仅水平方向缩放(X轴缩放)
3)scaleY(y)元素仅垂直方向缩放(Y轴缩放)
HTML代码:
<div class="wrapper">
<div>我将放大1.5倍</div>
</div>
CSS代码:
.wrapper {
width: 200px;
height: 200px;
border:2px dashed red;
margin: 100px auto;
}
.wrapper div {
width: 200px;
height: 200px;
line-height: 200px;
background: orange;
text-align: center;
color: #fff;
}
.wrapper div:hover {
opacity: .5;
-webkit-transform: scale(1.5);
-moz-transform:scale(1.5)
transform: scale(1.5);
}
演示结果:
注意:scale()的取值默认的值为1,当值设置为0.01到0.99之间的任何值,作用使一个元素缩小;而任何大于或等于1.01的值,作用是让元素放大。
matrix() 是一个含六个值的(a,b,c,d,e,f)变换矩阵,用来指定一个2D变换,相当于直接应用一个[a b c d e f]变换矩阵。就是基于水平方向(X轴)和垂直方向(Y轴)重新定位元素。
此属性值使用涉及到数学中的矩阵,我在这里只是简单的说一下CSS3中的transform有这么一个属性值,如果需要深入了解,需要对数学矩阵有一定的知识。
示例演示:通过matrix()函数来模拟transform中translate()位移的效果。
HTML代码:
<div class="wrapper">
<div></div>
</div>
CSS代码:
.wrapper {
width: 300px;
height: 200px;
border: 2px dotted red;
margin: 40px auto;
}
.wrapper div {
width:300px;
height: 200px;
background: orange;
-webkit-transform: matrix(1,0,0,1,50,50);
-moz-transform:matrix(1,0,0,1,50,50);
transform: matrix(1,0,0,1,50,50);
}
演示结果:
想要快速入门前端开发吗?推荐一个前端开发基础课程,这个老师讲的特别好,零基础学习无压力,知识点结合代码,边学边练,可以免费试看试学,还有各种辅助工具和资料,非常适合新手!点这里前往学习哦!「链接」
任何一个元素都有一个中心点,默认情况之下,其中心点是居于元素X轴和Y轴的50%处。如下图所示:
在没有重置transform-origin改变元素原点位置的情况下,CSS变形进行的旋转、位移、缩放,扭曲等操作都是以元素自己中心位置进行变形。
但很多时候,我们可以通过transform-origin来对元素进行原点位置改变,使元素原点不在元素的中心位置,以达到需要的原点位置。
transform-origin取值和元素设置背景中的background-position取值类似,如下表所示:
示例演示:
通过transform-origin改变元素原点到左上角,然后进行顺时旋转45度。
HTML代码:
<div>
<div>原点在默认位置处</div>
</div>
<div class="wrapper transform-origin">
<div>原点重置到左上角</div>
</div>
CSS代码:
.wrapper {
width: 300px;
height: 300px;
float: left;
margin: 100px;
border: 2px dotted red;
line-height: 300px;
text-align: center;
}
.wrapper div {
background: orange;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.transform-origin div {
-webkit-transform-origin: left top;
transform-origin: left top;
}
演示结果:
以上就是css动画中几种基本的变形技巧了,掌握这些我们可以操控我们的网页元素实现我们想要的一些基本动画效果。
在这个充满创造力的时代,CSS变形动画是每个前端开发者必备的技能。它不仅能提升用户体验,更能激发设计师和开发者的创意火花。所以,不妨尝试一下,让你的网页动起来,给用户留下深刻的印象吧!
我们下期再见!
END
文案编辑|云端学长
文案配图|云端学长
内容由:云端源想分享
程序员分享javascript实现自由编辑图片代码详解,当下我们项目中需要一个可自由编辑图片的功能,当图片可能出现需要频繁编辑,同时能满足发现裁剪不满意想要微调的时候,会发现如果我们处理图片按照平常的习惯,如裁剪后上传服务器或者转base64,都是不符合需求的。那么该怎么处理比较好呢?如何以尽量少的网络请求、少占用存储来解决应用场景呢?那么,便想到了只用纯数据来跟我们的功能打交道。
先安利个裁图神器cropperjs,个人认为是个易上手,配置和api方法蛮齐全的一个组件库。
项目内引入,一定不要漏了引用样式
import Cropper from 'cropperjs'; import 'cropperjs/dist/cropper.css';
这里我们以react为例
this.state = { width: 640, //图片展示宽 height: 360, //图片展示高 imgWidth: 640, //图片实际宽 imgHeight: 360, //图片实际高 imgLeft: 0, //图片左偏移 imgTop: 0, //图片上偏移 editing: false //是否编辑中 } //展示图片的基本dom结构,我们使用外div内img的形式,来跟数据结合控制裁剪图片的展示 const { width, height, imgWidth, imgHeight, imgLeft, imgTop, editing } = this.state; const containerStyle = { width: `${width}px`, height: `${height}px` } const imgStyle = { width: `${imgWidth}px`, height: `${imgHeight}px`, left: `${imgLeft}px`, top: `${imgTop}px` } .img-container { overflow: hidden; position: relative; } .crop-img { position: absolute; left: 0; top: 0; } <div className="img-container" style={containerStyle} > <img className="crop-img" src={picture} style={imgStyle} alt="pic" ></img> </div>
简单来说就是外层元素控制裁剪展示的宽高,同时根据项目需求的元素定位也挂在这,内部img挂载图片实际大小和偏移。
cropperjs初始化后的元素,是会与初始化对象img处在同一dom层级,也就是说如果我们直接对展示img进行初始化的话,编辑区域展示将会受父元素,如图,放大图片时候会不方查看超出部分
所以在这里,为了图片编辑的自由度,建议分开展示dom与用以初始化cropper对象的dom,在这里编辑区域为全屏幕为例,根据项目实际功能区域进行调整
.edit-container { position: absolute; left: 0; right: 0; top: 0; bottom: 0; } <div className="img-container" style={containerStyle} > <img className="crop-img" src={picture} style={imgStyle} alt="pic" ></img> </div> //cropper初始化 this.myRef = React.createRef(); this.myCropper = new Cropper(this.myRef.current, options); //options配置 const options = { dragMode: 'move', //使裁剪时图片可拖动 background: false, //因为我们现在是全屏可编辑,需要隐藏掉默认的背景 } //当然还有许多常见的配置项,如编辑框尺寸比例等,大家可自行查看api //裁剪保存 save() { const cropBoxData = this.myCropper.getCropBoxData(); //获取裁剪框数据 const canvasData = this.myCropper.getCanvasData(); //获取图片数据 this.setState({ width: cropBoxData.width, height: cropBoxData.height, imgLeft: canvasData.left - cropBoxData.left, imgTop: canvasData.top - cropBoxData.top, imgWidth: canvasData.width, imgHeight: canvasData.height }) }
这样的话 我们就可以完全在自定义的全屏内编辑,保存效果如下,到这里我们就完成了第一部分功能,裁剪并保存数据和展示
重点介绍下我们用到的两个api方法getCropBoxData和getCanvasData,getCanvasData是用来获取图片的实际数据的(当前的宽高,和相对于父元素可视区域的位移偏移量),getCropBoxData则是获取相对于图片区域的裁剪区相关数据。
那么后续的需求接着来了,我们怎么做到二次编辑的时候,能还原效果呢,嗯,其实在前面我们记录裁图数据的时候,把相应的数据关系再计算一遍就好了,在初始化cropper的options中增加配置
const options = { dragMode: 'move', background: false, //控件初始化后重置相应配置 ready: () => { const { width, height, imgWidth, imgHeight, imgLeft, imgTop } = this.state; //根据实际需要出现裁图功能进行定位,此处left和top仅为测试暂时默认值定义 const left = 50; const top = 50; this.myCropper.setCanvasData({ width: imgWidth, height: imgHeight, left: left, top: top }); this.myCropper.setCropBoxData({ left: left - imgLeft, top: top - imgTop, width: width, height: height }) } }
this.myCropper = new Cropper(this.myRef.current, options);
这时候我们再点击裁图,就完美还原了,左边和上边的间隙就是setCanvasData的top和left,根据实际项目进行调整,setCropBoxData的left和top是相对于cropper-canvas的定位,才有了以上的计算形式。
此时,基本功能到此结束,如果说是应用在h5编辑中,设计到scale缩放的话,相关的数据计算都要算上scale的缩放值哦,不然就会出现展示图片和编辑图片大小不对等的状况。同时还有许多功能就不做展示了,设置裁剪框比例,编辑缩放等,欢迎尝试。
当然了,如果想要保存图片,也有相应的方法到处裁剪图片的数据
this.myCropper.getCroppedCanvas().toDataURL('image/jpeg')
最后,我们可以看到,在整个功能过程中,我们需要的只是裁剪的数据,读写快,也不需要进行额外的图片存储,减少文件服务器存储的开销与优化。
*请认真填写需求信息,我们会在24小时内与您取得联系。