前端每日实战:166# 视频演示如何用 CSS 创作一个 Safari LOGO

2019-05-17 admin

图片描述

效果预览

按下右侧的“点击预览”按钮可以在当前页面预览,点击链接可以全屏预览。

https://codepen.io/comehope/pen/rgmPLR

可交互视频

此视频是可以交互的,你可以随时暂停视频,编辑视频中的代码。

请用 chrome, safari, edge 打开观看。

https://scrimba.com/p/pEgDAM/c2LBPPtg

源代码下载

每日前端实战系列的全部源代码请从 github 下载:

https://github.com/comehope/front-end-daily-challenges

代码解读

容器基本属性

Safari 浏览器的 LOGO 是一个指南针的形状,它的主要元素有 2 个,一个是围绕在表盘周围的刻度线,一个是中间的指针。所以我们定义 dom 结构如下,其中 .marks 代表刻度线,.pointer 代表指针。.marks 中有 4 个 <span> 元素,它们代表刻度线,实际的刻度线有几十条,这里只定义 4 条,目的是便于书写样式,等样式写好后,接下来会用 JavaScript 批量生成刻度线:

<figure class="safari">
    <div class="marks">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    <div class="pointer"></div>
</figure>

让作品显示在页面正中,页面背景为黑色:

body {
    margin: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: black;
}

LOGO 容器是一个白色的圆角正方形。作品将使用 em 作为长度单位,如果想修改 LOGO 的尺寸,只要修改这里的 font-size 属性就可以了。用 flex 布局令其中的子元素 .marks.pointer 都居中显示:

.safari {
    font-size: 10px;
    width: 15em;
    height: 15em;
    background-color: snow;
    border-radius: 25%;
    padding: 1em;
    display: flex;
    align-items: center;
    justify-content: center;
}

绘制刻度线

先绘制出刻度线所在的表盘,用线性渐变填充上蓝色渐变色:

.marks {
    width: inherit;
    height: inherit;
    background-image: linear-gradient(
        hsl(191, 98%, 55%),
        hsl(220, 88%, 53%)
    );
    border-radius: 50%;
}

再绘制出刻度线。围绕着一个圆周绘图的技巧是先令一组元素逐个旋转较小的角度(用 rotate() 函数实现),再让这些元素向旋转的方向移动(用 translate() 函数实现)。这里用变量 --rotate-deg 存储旋转的角度:

.marks {
    display: flex;
    align-items: center;
    justify-content: center;
}

.marks span {
    position: absolute;
    width: 0.1em;
    height: 0.9em;
    background-color: snow;
    transform: rotate(var(--rotate-deg)) translateY(6em);
}

.marks span:nth-child(1) {--rotate-deg: 0deg;}
.marks span:nth-child(2) {--rotate-deg: 90deg;}
.marks span:nth-child(3) {--rotate-deg: 180deg;}
.marks span:nth-child(4) {--rotate-deg: 270deg;}

现在可以看到 4 条刻度线分别定位到表盘的上、下、左、右的边缘位置了。

用 Javascript 批量生成刻度线

因为刻度线有很多条,为了减少代码量,我们用 JavaScript 来批量创建刻度线。

在此之前,先删除掉 html 中的声明 <span> 元素的 4 行代码:

<figure class="safari">
    <div class="marks">
        <!-- <span></span>
        <span></span>
        <span></span>
        <span></span> -->
    </div>
    <div class="pointer"></div>
</figure>

再删除 css 中设置刻度线角度的代码:

/* .marks span:nth-child(1) {--rotate-deg: 0deg;}
.marks span:nth-child(2) {--rotate-deg: 90deg;}
.marks span:nth-child(3) {--rotate-deg: 180deg;}
.marks span:nth-child(4) {--rotate-deg: 270deg;} */

然后用 js 来批量创建 60 条刻度线:

const MARKS_COUNT = 60

Array(MARKS_COUNT).fill('').forEach((x, i) => {
    let span = document.createElement('span')
    span.style.setProperty('--rotate-deg', i * 360 / MARKS_COUNT + 'deg')
    document.querySelector('.marks').appendChild(span)
})

这里稍复杂的是表达式 i * 360 / MARKS_COUNT + 'deg',其中 360 / MARKS_COUNT 是把一个圆周的 360 度分成若干份(也就是刻度线数量那么多的份数)之后每一份的角度,再用每一份的下标值 i 去乘它,就得到每条刻度线应旋转的角度了。

接下来设置刻度线的细节,令刻度线长短交错。代表刻度线长度的变量是 --h,长线长 0.9em,短线长 0.5em,为了让刻度线对齐,再用变量 --y 存储偏移量,令长线偏移 6em,短线偏移 6.2em。同时修改 height 属性和 translateY() 函数,让它们引用这 2 个变量的值。因为刻度线长短交错,所以用 :nth-child(odd):nth-child(even) 来设置 2 组不同的参数值:

.marks span {
    height: var(--h);
    transform: rotate(var(--rotate-deg)) translateY(var(--y));
}

.marks span:nth-child(odd) {--h: 0.9em; --y: 6em;}
.marks span:nth-child(even) {--h: 0.5em; --y: 6.2em;}

至此,刻度线绘制完成。

绘制指针

指针是由 2 个三角形组成的,对于这种成对的元素,通常都用伪元素绘制。先确定一下指针的尺寸,用 flex 令它的子元素(也就是 2 个伪元素)纵向排列:

.pointer {
    position: absolute;
    width: 1.4em;
    height: 12em;
    display: flex;
    flex-direction: column;
}

绘制三角形的技巧是令容器的尺寸为 00 高,然后用 3 条边框构成三角形,要是看不懂这段代码的话,动手试试就明白了。这里也定义了一个变量 --c,用于存储 2 个三角形的颜色,分别是红色和白色:

.pointer::before,
.pointer::after {
    content: '';
    border-bottom: 6em solid var(--c);
    border-left: 0.7em solid transparent;
    border-right: 0.7em solid transparent;
}

.pointer::after {
    transform: rotate(180deg);
}

.pointer::before {--c: crimson;}
.pointer::after {--c: snow;}

到这里,指针绘制完成,整个 LOGO 的形状也已经完成了。

最后,加一点动画效果,让指针像指南针那样转动。原理很简单,就是让指针在 30 度到 50 度之间来回摆动:

.pointer {
    transform: rotate(30deg);
    animation: rotate 1s ease-in-out infinite alternate;
}

@keyframes rotate {
    to {
        transform: rotate(50deg);
    }
}

大功告成!

[转载]原文链接:https://segmentfault.com/a/1190000019216340

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-65214.html

文章标题:前端每日实战:166# 视频演示如何用 CSS 创作一个 Safari LOGO

相关文章
前端交流QQ群
我们建立了一个前端交流QQ群供大家交流,有什么问题都可以在群里提问,欢迎你的加入,也希望我们大家能够在群里互帮互助,同时也能学到东西。 我们相信,前端有你更精彩! 为了让更多的小伙伴加入我们,欢迎大家转发扩散! 长按以上二维码加入我们 ...
2016-04-01
零基础-5小时开发一个electron应用-[实践]
一、背景 三、技能升级 ​ 明明可以用颜值取胜,非要靠才华?不对,明明可以用代码搞定,非要搞设计?步入正题,正好最近对electron比较感兴趣,又是要做工具,那就直接怼 1.electron介绍 ​ electron最开始不叫这个名字,叫...
2017-12-26
2014年最流行前端开发框架对比评测
如今,各种开发框架层出不穷,各有千秋。哪些是去年较受开发者关注的呢?前不久,云适配根据Github上的流行程度整理了2014年最受欢迎的6个前端开发框架,并进行对比说明,希望帮助有需要的朋友选择合适自己的前端框架。 1. Bootstrap...
2015-11-12
必须记住的 30 类 CSS 选择器
开篇 有 30 个 CSS 选择器你必须烂熟于心,它们适应于当今各大主流浏览器。 1.* * { margin: 0; padding: 0; } *选择器选择的是每一个单一元素。很多程序员用上面的 CSS 将所有元素的 ma...
2015-11-16
CSS2.0帮助文档(参考手册)chm下载
下载地址:CSS2.0帮助文档(参考手册)chm下载 友情提示:如果打开空白,在手册上右键属性解除锁定即可。 ...
2015-11-12
如何为高负载网络优化Nginx 和 Node.js?
译者:AlfredCheung 在搭建高吞吐量web应用这个议题上,NginX和Node.js可谓是天生一对。他们都是基于事件驱动模型而设计,可以轻易突破Apache等传统web服务器的C10K瓶颈。预设的配置已经可以获得很高的并发,不过,...
2015-11-12
梳理前端开发使用eslint-prettier检查和格式化代码
问题痛点 在团队的项目开发过程中,代码维护所占的时间比重往往大于新功能的开发。因此编写符合团队编码规范的代码是至关重要的,这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性。 对于代码版本管理系统(svn 和 git或者其他)...
2018-05-07
可以从CSS框架中借鉴到什么
现在很多人会使用 CSS 框架进行快速建站。   那 CSS 框架是什么呢,它通常是一些 CSS 文件的集合,这些文件包括基本布局、表单样式、网格、简单组件、以及样式重置。使用 CSS 框架大大降低工作成本进行快速建站。   当然对于一些大...
2016-03-11
Web前端开发与iOS终端开发的异同
毕业之前一直在做前端开发,毕业后就转成做iOS开发,这两者有很多挺有意思的对比,尝试写下我能想到的它们的一些相同点和不同点。 语言 前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,...
2016-01-13
如何编写干净高效的CSS代码
其实CSS的学习并不困难,但在一些较为大型的项目中就显得杂乱无章,变得很难管理,尤其是不同的人编写CSS的风格总会略有不同,从团队合作的层面上来说,就更加难以沟通,所以,我们为此总结了一些如何实现高效整洁的CSS代码原则: 使用Reset但...
2015-11-12
回到顶部