前端CSS3:transform形状变换(2D)&案例:用旋转和li画钟表的12根针

1,251 阅读5分钟

“这是我参与更文挑战的第10天,活动详情查看: 更文挑战

transform属性向元素应用2D或3D转换,该属性允许我们对元素进行移动、缩放、旋转或倾斜
移动:translate
translateX()
translateY()
translateZ()
translate3d(x,y,z): xyz三个矢量值,算合力大小和方向,朝合力方向移动
简写:translate() -> translate(x,y)

1.默认水平X,竖直Y,Z是垂直屏幕的;

2.可写正值可写负值,3D图像translateZ正数,肉眼看是放大,translate负数,肉眼看是缩小,离眼睛更远了一样;

3.可以写px,也可以写百分比,
这个百分比是相对自身的,自身宽如果是300px,往X轴移动100%就是移动了300px;自身高度如果是100px,往Y轴移动100%就是移动了100px;如果img设置了宽,但是没有设置高,会等比缩放的,往Y轴平移根据等比缩放后的高来平移
这个功能不需要提前知道盒子的高度,可以用来解决未知宽高的盒子的水平垂直居中问题
当已知宽高时:
父级设置position: relative
img自身设置:

position: absolute;
top 50%
left 50%
margin-top :盒子高度的一半的负数
margin-left:盒子宽度的一半的负数

未知高度时:
img的父级设置position: relative
img自身设置:

position: absolute;
top: 50%
left: 50%
margin-left:盒子宽度的一半的负数
transform : translateY(-50%)

未知宽度同理,把宽translate50%
完整代码如下:

.wrapper {
    border: 20px solid orange;
    width: 600px;
    height: 600px;
    position: relative;
}
.wrapper img {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 200px;
    /* margin-top: -159px; */
    /* margin-left: -100px; */
    transform: translate(-50%, -50%);
}
<div class="wrapper">
    <img src="./img/2.jpg" alt="">
</div>

在这里插入图片描述
4.如果向XY轴各平移100px,不能写成:

transform : translateX(100px);
transform : translateY(100px);

由于设置的是同一个属性:transform,后者会覆盖前者,只有向Y轴平移的效果生效
要写成

transform : translateX(100px) translateY(100px);

中间没有逗号
或者简写成:transform: translate(x,y);,如果只写一个值,代表水平移动,Y轴不移

缩放:scale
scaleX(n):水平方向拉伸到原来的n倍,以中心点为轴,两边伸缩,n大于1是放大,小于1是缩小,负值代表翻转
scaleY()
scaleZ()
scale3d(x,y,z)
简写:scale(x,y) | scale(n) -> scale(n,n),如果只写一个值,水平垂直都缩放,如果写两个值,第一个是水平,第二个是垂直方向

默认图片的中心点就是其原点,缩放也是以中心点向四方缩放的

同样不能写两行,一行scaleX,一行scaleY,这样会覆盖,只保留后者的样式
设置scaleX(-0.5):

transform: translate(200px, 200px) scaleX(-0.5);

效果:水平方向翻转并缩小到原来的0.5,原图文字是:‘萌,’
在这里插入图片描述

transform-origin
transform-origin设置元素原点位置
transform-origin: 50% 50% 0;默认值

X轴方向:left | center | right | length | %
Y轴方向:top | center | bottom | length | %
Z轴方向:length
原图直接展示的效果:
在这里插入图片描述

当我用默认的origin时,scale(2,0.5)的效果是:在中心位置开始,高度缩小,宽度缩小

transform: scale(2, 0.5);

在这里插入图片描述
当我将中心点设置在左上角时:

transform-origin: 0 0;
transform: scale(2, 0.5);

可以看到,此时是从左上角开始缩放的
在这里插入图片描述
旋转:rotate
rotateX()
rotateY()
rotateZ()
rotate3d(x,y,x)
简写:rotate() -> rotateZ(),当写rotate时,默认就是沿Z轴旋转
当沿x轴方向旋转,会呈现前面大,后面小的效果,由于图片不是3d的,没有厚度,所以看不出来前大后小的效果,只能看到高度变小了,旋转90deg时,就看不见了(不是一条线),因为没有厚度
以下动图是图片rotate从45deg到90deg的效果
在这里插入图片描述
角度可以是负数,代表旋转方向,一圈360deg

同理,一张图片沿着Y轴旋转,肉眼可见的是,图片宽度变小,当旋转到90deg时,也是看不见了

沿Z轴旋转:rotateZ
从45deg转:
在这里插入图片描述
默认旋转中心点就是图片中心点
将旋转中心点设置成图片上方边缘正中:

width: 200px;
transform-origin: 100px 0;/* 或者写50% 0;或者center top;*/
transform: rotate(45deg);

从45deg向0deg改变:
在这里插入图片描述
案例:
画一个钟,有12个指针,用12个li和旋转实现

body, ul, li {
    padding: 0;
    margin: 0;
    list-style: none;
}
ul {
    margin: 0 auto;
    position: relative;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    border: 2px solid #000;
    
}
ul li {
    position: absolute;
    top: 0;
    left: 150px;
    width: 2px;
    height: 10px;
    background: #000;
    margin-left: -1px;
}

画一个圆,12个li目前都在0点位置
在这里插入图片描述
我们希望li能够绕着圆的中心旋转,而默认旋转的中心点是元素本身的中心点,即:

li:nth-child(1) {
    transform: rotate(30deg)
}

可以看到,旋转的中心点在元素本身的中心,所以第一个li旋转之后,与其他li形成了类似’x’的形状:
在这里插入图片描述
于是,我们要调整transform-origin,可以想像一下,origin设置成0 0 是元素li的左上角,那么,1px 150px,是不是就是圆中心了(li宽2px,圆半径150px)
在这里插入图片描述
效果:
在这里插入图片描述
一个li效果已完成,12个li都手动设置,代码太冗长,用js自动生成li以及旋转的样式

var oUl = document.getElementsByTagName('ul')[0];
var str = '';
for (var i = 1; i <= 12 ; i ++){
    str += '<li style = "transform :rotate(' + (i*30) + 'deg)"></li>'
}
oUl.innerHTML = str;

效果:
在这里插入图片描述
完整css代码:

    <style>
        .wrapper {
            border: 20px solid orange;
            width: 600px;
            height: 600px;
            /* position: relative; */
        }
        .wrapper img {
            /* position: absolute;
            top: 50%;
            left: 50%; */
            width: 200px;
            /* margin-top: -159px; */
            /* margin-left: -100px; */
            /* transform-origin: 0 0; */
            transform-origin: 100px 0;/* 或者写50% 0;或者center top;*/
            transform: rotate(45deg);
        }
        body, ul, li {
            padding: 0;
            margin: 0;
            list-style: none;
        }
        ul {
            margin: 0 auto;
            position: relative;
            width: 300px;
            height: 300px;
            border-radius: 50%;
            border: 2px solid #000;
            
        }
        ul li {
            position: absolute;
            top: 0;
            left: 150px;
            width: 2px;
            height: 10px;
            background: #000;
            margin-left: -1px;
            transform-origin: 1px 150px;
        }
    </style>

html代码:

<body>
    <ul>
    </ul>
    <script src="16.js"></script>
</body>

js代码就是上面的那个js代码

倾斜:skew
skewX(ndeg)
skewY(ndeg)
简写:skew(x,y),只写一个角度代表x轴,两个代表x,y轴
倾斜没有沿Z轴方向的,沿X轴方向等于手拿着左上角和右下角向外拉;沿Y轴方向等于手拿着左下角和右上角向外拉

沿x轴从45deg开始向100deg改变:
在这里插入图片描述
沿y轴从45deg开始向负数改变:
在这里插入图片描述