办公位2.0,用SVG实现Chrome浏览器图标,文末有总结【玩转CSS】
功能拆解
很多图形的实现并不困难,我之前的文章也实现过各式各样的图形。基本是CSS里的样式约熟悉,图形实现的越快速、越相似。还有一些需要SVG或Canvas实现的图形,这就需要这两项技术的基本功扎实了。
简单图形设计
整个画面中有很多图形,有些图形比如画框、太阳、桌腿、便签,无论是形状还是线条都很简单,实现起来没什么难度。
其中有一个图形,我要简单说一下它是如何实现的。
这个图形就是白云。不规则的弧线用css实现是讲究技巧的。
这个技巧在于练习。练习多了,看到图形的时候,这样那样再这样就能在脑海中,串联起实现方案。
回归到云朵上,最开始我想着用一个椭圆➕一个圆,叠加的方式,但是效果不太理想。后来是又观察了云朵的图形,想到两个椭圆重叠试试,这下效果好多了。
.cloud {
width: 40px;
height: 18px;
border-radius: 20px;
background: #dbe5f0;
position: absolute;
z-index: 19;
transform: scale(0.8);
}
.cloud::before {
content: '';
width: 24px;
height: 32px;
background: #dbe5f0;
border-radius: 20px;
position: absolute;
left: 8px;
top: -10px;
}
复杂图形设计
比较复杂的图形是Chrome浏览器的图标。它在显示器的任务栏上。
它是一个三色的圈。一般圆圈的纯色或者渐变都好实现。但是三色实现还是有点难度的。
我这里借助的SVG,总共用四个圆形实现了Chrome浏览器的图标。
- 三个圆的半径一致,但是填充的颜色不同。其中两个设置了偏移,主要是为了露出底下圆的部分。
- 另外一个圆半径值要小于其它圆,因为图标正中间有一个小圆。
circle {
stroke-width: 26px;
fill: none;
stroke-dasharray: 300px;
stroke: #fbbd17;
}
.circle2 {
stroke-dashoffset: -80px;
stroke: url(#circle2);
}
.circle3 {
stroke-dashoffset: -150px;
stroke: url(#circle3);
}
.circle4 {
fill: #297dec;
stroke: none;
}
......
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='100' height='100' viewBox='0 0 150 150'>
<defs>
<linearGradient x1='1' y1='0' x2='0' y2='0' id='circle2'>
<stop offset='100%' stop-color='#2E9F49'></stop>
</linearGradient>
<linearGradient x1='1' y1='0' x2='0' y2='0' id='circle3'>
<stop offset='100%' stop-color='#E54032'></stop>
</linearGradient>
</defs>
<circle cx='60' cy='60' r='40' class='circle1'></circle>
<circle cx='60' cy='60' r='22' class='circle4'></circle>
<circle cx='60' cy='60' r='40' transform='rotate(-20 60 60)' class='circle2'></circle>
<circle cx='60' cy='60' r='40' transform='rotate(-10 60 60)' class='circle3'></circle>
</svg>
Chrome浏览器的图标
来看一个大图更加明显基本上是神似的
https://code.juejin.cn/pen/7155686614541271047
SVG知识点
<circle>
<circle> 元素是一个 SVG 的基本形状,用来创建圆,基于一个圆心和一个半径。
属性
- cx和cy属性定义圆点的x和y坐标。如果省略cx和cy,圆的中心会被设置为(0, 0)
- r属性定义圆的半径
stroke 属性
stroke属性定义了给定图形元素的外轮廓的颜色。它的默认值是none。(MDN文档)
属性名 |
介绍 |
stroke-width |
指定了当前对象的轮廓的宽度。它的默认值是1。如果使用了一个<percentage>,这个值代表当前视口的百分比。如果使用了0值,则将不绘制轮廓。 |
stroke-dasharray |
可控制用来描边的点划线的图案范式。 |
stroke-dashoffset |
指定了 dash 模式到路径开始的距离。 如果使用了一个 <百分比> 值,那么这个值就代表了当前 viewport 的一个百分比。 值可以取为负值。 |
stroke-linecap |
在开放子路径被设置描边的情况下,用于开放自路径两端的形状。 |
stroke-linejoin |
指明路径的转角处使用的形状或者绘制的基础形状。 |
stroke-opacity |
指定了当前对象的轮廓的不透明度。它的默认值是1。 |
stroke-miterlimit |
对斜接长度和stroke-width的比率强加了一个极限。当极限到达时,交汇处由斜接变成倒角。 |
创意功能设计
创意功能,很多是根据事物本身的特性。
有时候,我热衷给自己整活。比如一个完整的图画已经绘制完成了,我会思考加点有趣的交互效果。
比如这里的办公位,椅子可以旋转、时钟可以到点报时、办公区可以加入光照随时间光照从明亮变昏暗,还可以做显示器的开关机。
我这次实现的就是显示器的开关机。
功能介绍
- 自动开关机,根据一天当中的时间段,早6到晚6,显示器是开机状态 ,其余时间是关机状态。
- 手动开关机,显示器上有关机按钮,屏幕点亮时,点击关机,且不受自动开关机的约束;当前屏幕关闭时,点击开机。
实现
- new Date().getHours()获取当前时间点处于一天中的所处的小时。
- 开关机操作方法,无论是自动还是手动实现开关机的功能是一样的,关机屏幕变暗,开机屏幕变亮。所以我给屏幕最外层加了一个遮罩,开关机操作控制的是遮罩的展示和隐藏。
- 自动开关机,会根据当前所处小时,是否正在[6,18]这个区间中,进行控制 。
- 手动开关机,则是监听按钮的点击事件,点击之后,根据当前屏幕状态去反即可。
var clockMinute = document.getElementById('clockMinute');
var shutdown = document.getElementById('shutdown');
var monitorMask = document.getElementById('monitorMask');
var shutdownFlag = false; // 当前按钮是否点击过 默认false 如果点击过,则不再按照时间范围进行屏幕关和开
var shutdownHourFlag = false; // 屏幕是否关闭状态 默认false
var range = [6, 18];
// 屏幕操作
function screenFunc(flag, hour) {
// 关机
if (flag) {
shutdown.classList.add('shutdown-animation');
monitorMask.classList.add('monitor-mask');
} else {
// 开机
shutdown.classList.remove('shutdown-animation');
monitorMask.classList.remove('monitor-mask');
}
}
// 初始化日期信息
function initNowDate() {
var now = new Date();
var day = now.getDate();
var hourInit = now.getHours();
var hour = 0;
var minutes = now.getMinutes();
var weekList = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
var week = weekList[now.getDay()];
if (hourInit >= 0 && hourInit <= 9) {
hour = '0' + hourInit;
} else {
hour = hourInit;
}
if (minutes >= 0 && minutes <= 9) {
minutes = '0' + minutes;
}
var timeStr = hour + ':' + minutes;
clockMinute.innerHTML = timeStr;
// 没有点击过关机按钮,可以按照时间进行关机
if (!shutdownFlag) {
shutdownHourFlag = hourInit >= range[1] || hourInit <= range[0] ? true : false;
console.log(hourInit >= range[1]);
screenFunc(shutdownHourFlag);
}
}
initNowDate();
shutdown.addEventListener('click', e => {
shutdown.classList.toggle('shutdown-animation');
monitorMask.classList.toggle('monitor-mask');
shutdownFlag = true; // 点过关机键
shutdownHourFlag = !shutdownHourFlag;
screenFunc(shutdownHourFlag);
});
CSS创意经验分享
最近做了挺多功能的,分享我总结的CSS创意经验。
我这两年在技术文章分享上,有些变化。初期的技术分享大部分是关于业务开发经验、提高开发效率、技术学习上。最近的一段比较长的时间里文章分享内容主要两类:如何教非技术朋友了解技术和CSS创意实践。
虽然谈不上优质创作,但确是我目前的兴趣所在,特别是和朋友分享创作的时候,尤为喜悦。
如何提升自己的创意能力?
答曰:联想和练习。这两个项是相辅相成的,练习多了,遇到有趣的画面,就会情不自禁进行联想。联想有了但是想实现自己的想法,可能苦于无法实现,这个就要依靠日常的练习了。
怎么联想?看到就一定要实现出来吗?
绘制的过程还是挺耗时的,所以看到了不一定要立马实现它,可以先简单的记录下来,慢慢实现。
下面的截图是我目前有想法但是没有实现的创意:
图形绘制的多了,看到身边的实物,就能自然而然的产生联想。比如自然之境,日出日落、白云落叶、春华秋实,甚至是节气也可以依据每个节气不同的习俗实现一副画作。宇宙星尘、科技产品,自然与技术,也是一个不错的搭配。
如何高效练习?
唯手熟尔。我把这个熟归为了两类:知识点和构图。
知识点熟,有了技术储备,才能遇到好的创意的时候不卡壳。
构图熟,那图形实现起来就快了许多。
就算画多了,有什么用?
有这个时间,躺着睡会不香吗?
大抵是,睡醒过后,一瞬间感觉我被这个世界遗忘了。空虚和无助涌上心头,很不是滋味。但是当我是完成一个目标,再去休息的时候,我会比较没有负担。
约莫是,一无所长。
音乐细胞,无。
书画天分,无。
乐器,一项都不擅长。
厨艺,勉勉强强饿不着自己,其他人会选择点外卖。
跳舞,我懂得比我能做到的动作多多了。
运动,四层楼都得大喘气。
人是平凡了些,单不代表着没有梦想。虽然典型的“思想的巨人,天赋的矮子”,但是有灵感本身就挺值得欣慰的。如果能将灵感变为现实,岂不是锦上添花,意外收获。
时间都花在画图形了,还有时间提升其他能力吗?毕竟技术更新这么快
利用碎片化时间
不连贯且短暂的时间,我一般会用在阅读书籍或者技术文章上。一般碎片化的时间集中在上下班通勤、工作间隙。
时间短且不连贯,无法支持实现完整的功能开发。但是阅读几篇技术书籍或者一篇长度适中的文章是绰绰有余的。
灵活的目标定制
我一般都是定半年期的目标,然后拆分到每个月实现。但是如果遇到某个月工作特别多、排期特别紧。我就会将比较难实现的目标挪动一下。
更换目标实现的顺序,也是我常用的方式之一。
张弛有度的节奏
这个月,我整体的开发精力并不在创意实现上。毕竟也是有自己的生活的,我分了很多精力给日常生活,而且这个月下旬,我要集中精力做四季度的开发规划。
所以有充足的精力的时候,我会根据这一个周期想做的事,有精神头的去做。如果精力不能全部放到技术创新或者学习上,我也会适时的舍弃一些想法。
作者:非职业「传道授业解惑」的开发者叶一一简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)