CSS案例:实现书页任意折角效果

书页任意角度折角效果示意图

    <div class='note'>
        欢迎来到二狗哥的博客,HTML、CSS、JavaScript等前端代码研究,你我共勉!
    </div>

  

代码编程要求:

1、折线与上边缘构成角度为30°;2、背景颜色色标#6d98bd,折角部分色标#577b98;3、为增加逼真效果,需要为折角添加阴影;4、折角不能遮盖内容文字部分;

书页任意角度折角效果分解为两个步骤:(1)绘制满足要求的特定三角形;(2)将三角形位置设置为指定坐标地点。

构建数学模型进行分析:

矩形ABCD代表主体元素(.note),三角形EFB1代表折角元素,并且三角形EFB1与三角形EBF关于EF轴对称。

实现思路:主体采用相对定位,翻折部分用伪元素通过绝对定位来实现。主体元素(.note)的背景翻折部分(虚线三角形),通过线性渐变颜色显示剪去翻折部分。

上面是数学模型的局部放大图,采用背景线性渐变来剪去目标三角形,剪去部分为透明色(transparent)。重点是确定达到指定线性渐变的渐变角度以及色标长度值。根据W3C中线性渐变渐变线的定义,想要EF为分界线,渐变角度为210°,透明色渐变长度等于线段BH长度值(BH与EF互相垂直)。

根据几何图形对称轴的特性有:

EB=EB1

FB=FB1

根据直角三角形的关系,我们可以得出:

BE=√3 BF

EB长度等于伪元素的高度y,BF长度等于伪元素的宽度x。若是网页设计时,相关圆角和尺寸都会由设计时进行确定,有比较详细的标注。这里采用圆角边框半径用5px,透明色标长度18px效果比较理想。考虑代码的后期维护性,转换为相对单位em。主元素的CSS代码如下:

  .note {
            font-size: 12px;
            color: rgb(199, 197, 197);
            width: 200px;
            height: 100px;
            padding: 20px;
            border-radius: .4166em;
            /* 5px  */
            position: relative;
            background: #6d98bd;
            /* 回退机制 */
            background: linear-gradient(210deg, transparent 1.5em, #6d98bd 0);
        }

  

对于目标三角形来说,由于透明色色标已经确定,它的长度和高度与BH关联确定。根据三角函数,可知:高度值y=2BH=3em,宽度值 x= 2BH/√3代入数值计算,值约为:1.732em。

.note::before {
            content: '';
            display: block;
            width: 1.73em;
            height: 3em;
   }

  

伪元素显示为直角三角形,同样通过线性渐变来实现。线性渐变色标分界线为对角线,根据线性渐变定义,可以知道透明色色标色标值为渐变线长度的50%。

background: linear-gradient(60deg, #577b98 50%, transparent 0);

  

这样初步实现了折角部分效果,下面重点是进行定位。默认的伪元素(.note::before)为主元素(.note)的第一个子元素,位于其内容盒中的左上角。目标位置靠近右上角,并需要经过一定的旋转实现。

伪元素位于主元素右上角后,需要上移FL距离,然后以F点为旋转点,旋转60°,即达到目标位置。FL=y-x=1.27em。

绝对定位与位置转换:

 position: absolute;
 right: 0;
 top: 0;
 transform: translateY(-1.27em) rotate(-30deg);
 transform-origin: bottom right;

  

左下角圆弧:

border-bottom-left-radius: inherit;

  

最后增加阴影效果,让折角更加逼真:

box-shadow: -.2em .2em .3em -.1em rgba(0, 0, 0, .15);

  

完整的代码:

       .note {
            font-size: 12px;
            color: rgb(199, 197, 197);
            width: 200px;
            height: 100px;
            padding: 20px;
            border-radius: .4166em;
            /* 5px  */
            position: relative;
            background: #6d98bd;
            /* 回退机制 */
            background: linear-gradient(210deg, transparent 1.5em, #6d98bd 0);
        }

        .note::before {
            content: '';
            display: block;
            width: 1.73em;
            height: 3em;
            position: absolute;
            background: linear-gradient(60deg, #577b98 50%, transparent 0);
            right: 0;
            top: 0;
            border-bottom-left-radius: inherit;
            transform: translateY(-1.27em) rotate(-30deg);
            transform-origin: bottom right;
            box-shadow: -.2em .2em .3em -.1em rgba(0, 0, 0, .15);

        }

  

 

posted @ 2020-12-02 18:24  请叫我二狗哥  阅读(1271)  评论(0编辑  收藏  举报