网站首页 > 技术文章 正文
最近项目上有个工业自动化的需求,做一个按钮,有按下弹起效果,你肯定会说这不是so easy吗?是的,没错,用css,分分钟写一个,不过我们是做的拓扑图,用的canvas,因此我就想css画图也是gpu绘制,css能做的效果,我大canvas理应也能实现,于是我试着用css的实现方式做了一个canvas版的按钮效果。
css3版的立体按钮效果
想想我们用css怎么做一个按钮,首先我们就能想到按钮需要有阴影,我们可以使用box-shadow,他的语法如下:
/* x偏移量 | y偏移量 | 阴影颜色 */ box-shadow: 60px -16px teal; /* x偏移量 | y偏移量 | 阴影模糊半径 | 阴影颜色 */ box-shadow: 10px 5px 5px black; /* x偏移量 | y偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */ box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2); /* 插页(阴影向内) | x偏移量 | y偏移量 | 阴影颜色 */ box-shadow: inset 5em 1em gold; /* 任意数量的阴影,以逗号分隔 */ box-shadow: 3px 3px red, -1em 0 0.4em olive; /* 全局关键字 */ box-shadow: inherit; box-shadow: initial; box-shadow: unset;
首先我们定义一个btn类,先画出一个按钮的基础样式
.btn { border-radius: 5px; padding: 15px 25px; font-size: 22px; text-decoration: none; margin: 20px; color: #fff; position: relative; display: inline-block; }
然后我们定义一下按钮的背景色
.blue { background-color: #55acee; }
这是我们的按钮基础样式就完成了,如下所示:
接下来我们在来为按钮添加阴影
.btn:active { transform: translate(0px, 5px); -webkit-transform: translate(0px, 5px); box-shadow: 0px 1px 0px 0px; } .blue { background-color: #55acee; box-shadow: 0px 5px 0px 0px #3C93D5; }
给y方向5px的偏移,就会有阴影的效果,有点立体感觉,然后按下按钮之后我们还要去掉阴影,然后按钮的位置要向下偏移响应的5px,这样效果如下所示:
canvas版的按钮效果
css的按钮我们已经知道了其实也就是利用box-shadow绘制阴影来实现按钮的样式,那么canvas我们怎么绘制阴影呢?翻一翻万能的mdn
shadowOffsetX = float
shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0 。
shadowOffsetY = float
shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0 。
shadowBlur = float
shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0 。
shadowColor = color
shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。
第一步我们先绘制矩形,绘制矩形我们使用moveTo和lineTo,因为按钮一般是带有圆角的,所以我们封装一个绘制圆角矩形的
createPath: function (x, y, width, height, radius) { this.ctx.moveTo(x, y + radius); this.ctx.lineTo(x, y + height - radius); this.ctx.quadraticCurveTo(x, y + height, x + radius, y + height); this.ctx.lineTo(x + width - radius, y + height); this.ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius); this.ctx.lineTo(x + width, y + radius); this.ctx.quadraticCurveTo(x + width, y, x + width - radius, y); this.ctx.lineTo(x + radius, y); this.ctx.quadraticCurveTo(x, y, x, y + radius); },
圆角矩形绘制完成后我们在接着绘制阴影,
setShadow: function (xoffset, yoffset) { var style = this.style; this.ctx.shadowOffsetX = xoffset || 0; this.ctx.shadowOffsetY = yoffset || 5; this.ctx.shadowBlur = 0; this.ctx.shadowColor = style.shadowColor; },
阴影绘制完后我们还要绘制文本,毕竟是canvas,绘制文本不像css那么方便,我们需要计算文字宽度来定位,代码如下:
drawText: function () { var xoffset = this.ctx.measureText(this.text).width; var x = this.x, y = this.y; if (this.state === 'active') { y = y + 5; } this.ctx.save(); this.ctx.beginPath(); this.ctx.font = "30px Micosoft yahei"; this.ctx.fillStyle = this.fontColor; this.ctx.textBaseline = 'middle'; this.ctx.textAlign = 'center'; this.ctx.fillText(this.text, x + (this.width - xoffset) / 2 + 10, y + (this.height - 22) / 2 + 5, this.width); this.ctx.closePath(); this.ctx.restore(); },
另附textAlign和textBaseLine的说明:
textAlign:
textBaseLine:
这样效果就基本大功告成了
canvas事件可以具体看我的代码和我以前的博客
canvas发光效果
上面介绍了如何绘制canvas阴影立体按钮,接下来我们来实现试试更进一步的效果,多层阴影叠加效果,在css中我们的box-shadow可以叠加多层阴影效果,并且通过逗号分隔。那么我们canvas是不是也可以同样实现呢?我们知道canvas是基于状态的,我们如果要绘制多层阴影叠加,那么就需要保存每次绘制的阴影,层叠在一起,那么我们改下代码,每画一层阴影就需要保存一次canvas状态:
drawText: function (shadowx, shadowy, blur, shadowColor) { var xoffset = this.ctx.measureText(this.text).width; var x = this.x, y = this.y; this.ctx.save(); this.ctx.beginPath(); this.setShadow(shadowx, shadowy, blur, shadowColor); this.ctx.font = "300px Micosoft yahei"; this.ctx.fillStyle = this.fontColor; this.ctx.textBaseline = 'middle'; this.ctx.textAlign = 'center'; this.ctx.fillText(this.text, x + (this.width - xoffset) / 2 + 10, y + (this.height - 22) / 2 + 5, this.width); this.ctx.closePath(); this.ctx.restore(); }, setShadow: function (shadowx, shadowy, blur, shadowColor) { this.ctx.shadowOffsetX = shadowx || 0; this.ctx.shadowOffsetY = shadowy || 0; this.ctx.shadowBlur = blur || 10; this.ctx.shadowColor = shadowColor; },
效果如下:
不太完美,有时间在继续优化,动画的发光还是不太柔和,与css比效果还是有点欠缺,以后再优化,先mark一下,不喜勿喷。
总结
知识都是由互通性的,多学习多思考,不能学了这个忘那个,要能融会贯通。
猜你喜欢
- 2024-10-31 ReactNative源码笔记——你知道几条?
- 2024-10-31 Echarts饼图展示车站客流占比图(车站客流分析)
- 2024-10-31 第76节 Canvas绘图(下)-前端开发之JavaScript-王唯
- 2024-10-31 前端开发者如何利用 CSS 实现酷炫的变色方案?
- 2024-10-31 html中滚动字体的设置(html字体滚动效果)
- 2024-10-31 熬夜总结了“HTML5画布”的知识点(共10条)
- 2024-10-31 CSS3线性渐变、阴影、缩放实现动画下雨效果
- 2024-10-31 CSS3被玩儿坏?下雨动画效果CSS就可以搞定
- 2024-10-31 HTML5(五)——Canvas API(h5canvas动画入门教程)
- 2024-10-31 CSS3 box-shadow实现背景动画(css背景视频)
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)