记录图鸟UI Tabbar大赛创作学习过程-scss任意弧度曲线渲染

声明:本人前端技术小白,借着图鸟UI Tabbar大赛学习一下前端知识,以下是思维过程。


前言

图鸟UI整了一个Tabbar大赛,正好最近有空,试着来参加一下,学习一下前端知识,以下是思维过程。


一、图鸟UI

官网:https://docs.ahuaaa.cn/

图鸟UI-是图鸟科技打造的开发者全成长周期开源平台,围绕酷炫、效率、合作、成就、变现,五大用户价值布局平台能力,全力服务开发者,旨在成为开发者的好朋友。图鸟历经多轮打磨雕刻,集海量高品质图鸟模板、实时在线预览、多元化场景模板、轻便好学、易上手等多重优势于一身的开发神器,更自带免费开源可商用属性,为企业集团、公司团队、前端后端开发者、运营大佬、社交达人、学生小白提供了一个零成本的在线开发平台和资源库。

二、前期思考

1.Tabbar选择

由于本人毫无审美,所以就在图鸟UI的Tabbar模板库看看选择一下大方向。地址:图鸟UI官网
看了一圈,对一个tabbar的样式很感兴趣。突出效果
因为之前在其他群里有人问过类似的突起效果怎么做,当时我的想法就是一个圆+两个马尾辫。借着这个机会,我想来复现一下我的想法。于是就准备复现以下这个圆弧。

2.突起平滑圆弧实现

1.双马尾 ❎

当时有人在群里问这种平滑圆弧如何实现,我当时的想法就是一个圆+两个双马尾:

.circle {
  position: relative;
  width: 300rpx;
  height: 150rpx; 
  border-radius: 300rpx 300rpx 0 0; 
  background-color: red;
  overflow: visible; 
  &::before {
    content: '';
    position: absolute;
    top: 150rpx; 
    left: 300rpx; 
    width: 300rpx;
    height: 150rpx; 
    border-radius: 0 0 300rpx 300rpx;
    background-color: salmon;
    border: 20rpx solid #000;
    box-sizing: border-box;
  }
}

效果:双马尾
看着就奇奇怪怪的不够平滑,这时候就很好奇图鸟是怎么实现这个效果的:翻阅图鸟代码发现是使用的SVG,好像SVG就是css中连续平滑曲线的最佳实现:

 -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 61.5'%3E%3Cpath d='M100 0H0c32.9 0 49.3 61.5 100 61.5S167.1 0 200 0H100z'/%3E%3C/svg%3E"), linear-gradient(#000, #000);

svg
但是我就想用css去实现该效果,于是继续仔细观察这个图像
三角函数

这个图像很像三角函数中的sin图像移动而来,于是我准备在css中复现三角函数

2.三角函数 ❎

因为我们使用的是scss 于是百度scss sin函数图像实现:地址:sin图像实现
代码实现:scss sin函数实现
图像:sin

这个方法有个问题,那就是其函数图像是用连续的阴影来实现的而非border,这样会与border看起来失真。

3.剪裁圆形状 ❎

我们发现方法二双马尾中,曲线不平滑的原因就是快到交点的时候斜率骤降,导致图像不平滑,那我们就可以在不平滑之前,截断曲线,于是我将圆进行了剪裁,然后将两个圆进行拼接。
代码:

.mask {
  position: relative;
  --w: 200rpx;
  --h: 100rpx;
  width: calc(2*var(--w));
  height: 50rpx;
  background-color: aqua;
  overflow: hidden;
  .circle1 {
    position: absolute;
    width: var(--w);
    height: var(--h);
    border-top-right-radius: 100%;
    background-color: red;
  }
  .circle2 {
    position: absolute;
    width: var(--w);
    left: var(--w);
    height: var(--h);
    border-top-left-radius: 100%;
    background-color: blue;
  }
}

效果:
剪裁
写到这里,大家想必都知道接下来咋办了吧,弦长公式计算出弦长然后将两个半圆分成两块,再剪裁x轴方向,将两个图像的顶点对齐即可。
但是这样也太复杂了,相较于svg好像没有半点优势,再观察svg图像,你会发现,其实图像连续的本质好像是斜率相同,即:两个圆相外切,平滑的本质就是在上图裁剪的部分作切点即可!

4.两图像在裁剪点相外切 ✅

综上所述,我们绘制以下草图:
两圆图像相切

代码:

//sqrt的scss实现
@function sqrt($r) {
  $x0: 1;
  $x1: $x0;

  @for $i from 1 through 10 {
    $x1: (
      $x0 + $r / $x0) / 2;
    $x0: $x1;
  }

  @return $x1;
}

$static-a: 10px;
$static-b: 20px;

$a-val: $static-a / 1px;
$b-val: $static-b / 1px;

$R-val: sqrt($a-val * $a-val + $b-val * $b-val) / 2;
$static-R: #{$R-val}px;
.box {
  position: relative;
  --a: #{$static-a};
  --b: #{$static-b};
  --R: #{$static-R};

  .c1 {
    position: absolute;
    width: calc(2 * #{$static-R});
    height: calc(2 * #{$static-R});
    border-radius: 50%;
    background-color: #fff;
    z-index: 999;
  }

  .c2 {
    position: absolute;
    left: #{$static-b};
    top: calc(-1 * #{$static-a});
    width: calc(2 * #{$static-R});
    height: calc(2 * #{$static-R});
    border-radius: 50%;
    background-color: #000;
  }
}

效果:
相切
接下来就是剪裁大法啦,将右边的图像y轴剪裁:r+a/2个长度即可啦。
代码:

.box {
  position: relative;
  --a: #{$static-a};
  --b: #{$static-b};
  --R: #{$static-R};

  .c1 {
    position: absolute;
    width: calc(2 * #{$static-R});
    height: calc(2 * #{$static-R});
    border-radius: 50%;
    background-color: #fff;
    z-index: 999;
  }

  .c2 {
    position: absolute;
    left: #{$static-b};
    top: calc(-1 * #{$static-a});
    width: calc(2 * #{$static-R});
    height: calc(2 * #{$static-R});
    border-radius: 50%;
    clip-path: polygon(0 #{$clip-height-px}, 50% #{$clip-height-px}, 50% 100%, 0 100%);
    box-shadow: 0 0 0 10px #000;
  }

但是我们发现因为使用了裁剪大法,当b和a的比值大时,图像是这样的:
裁剪
因为使用了clip-path 导致shadow没有办法完整的显示出来,如果使用overflow: hidden;的话又太麻烦了。于是我就问GPT,css还有哪些方法画圆:
✅ 方法 1:使用 border-radius
✅ 方法 2:使用 clip-path
✅ 方法 3:使用 mask(遮罩)实现圆形
✅ 方法 4:使用 canvas
其他都知道,这个mask遮罩是什么东西?

background-image: radial-gradient(shape size at position, start-color, ..., last-color);

看了一下,好像是在指定地方position,创建画布,画出shape并且指定颜色。
at后面是相较于div进行定位,然后后面还可以控制背景图层的定位,这样子更容易画出我们想要的图像。
好像这个更方便一点
代码:`

.box {
  --a: #{$static-a};
  --b: #{$static-b};
  --R: #{$static-R};
  height: 200px;
  width: 200px;
  margin: 5px;
  background:
    radial-gradient(var(--R) at 50% var(--R), #000 100%, #0000 100%) center center / calc(4 * var(--b)) 100%,
    radial-gradient(var(--R) at calc(50% + var(--b)) calc((var(--R) - var(--a))), #000 100%, #0000 100%) center center / calc(4 * var(--b)) 100% no-repeat;
}

效果:相切

然后就是无聊的乐高时间~

.box {
  --a: #{$static-a};
  --b: #{$static-b};
  --R: #{$static-R};
  height: calc(2*var(--b));
  width: 200px;
  margin: 5px;
  background-color: aqua;
  background:
    radial-gradient(calc(2*var(--R)) at 50% calc(var(--b) + var(--a)), #000 99%, #0000 101%) calc(50% - 2*var(--b)) 0/calc(4*var(--b)) 100% no-repeat,
    radial-gradient(calc(2*var(--R)) at 50% calc(-1*var(--a)), #0000 99%, #fff 101%) 50% var(--b)/calc(4*var(--b)) 100% no-repeat;
}
  • 出门回来再拼乐高吧,先用div写一个,时间来不及了呜呜呜,下午要出门。理论上一个div就可以实现这个的渲染。

3. 添加动画

加一点贝尔曲线,再加一个到点翻转(实在是没时间了,要出门了qwq)
qwq


总结

以上方法可以用一个div radial-gradient 实现任意曲线。
曲线平滑过渡:外切。
我是一个个人开发者,我从事于校园市场。
开源课表(准备用图鸟UI重写):https://gitee.com/czczcz666/kezhidao

VX:lczwuairu 欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值