基于 HTML5 Canvas 的可交互旋钮组件
前言
此次的 Demo 效果如下:
Demo 链接:https://hightopo.com/demo/comp-knob/
整体思路
- 组件参数
- 绘制旋钮
- 绘制刻度
- 绘制指针
- 绘制标尺
- 绘制文本
- 交互效果
1.组件参数
以下是下文会使用到的部分变量,在此先贴出来
var origin, // 原点percent, // 显示刻度占总刻度的百分比partAngle, // 每个刻度所占的角度startAngle, //刻度起始的角度calibrationPoints, // 每个刻度的信息pointer, // 指针的信息scaleLine, // 标尺的信息calibrationColors // 刻度渐变色
2.绘制旋钮
这里主要就使用了 canvas api 中的 arc() 和 createRadialGradient() 。
主要代码:
g.beginPath(); var ringRadial = g.createRadialGradient(origin.x, origin.y, 0, origin.x, origin.y, ringRadio); ringRadial.addColorStop(0, ht.Default.brighter(ringColor, 20)); ringRadial.addColorStop(0.95, ht.Default.brighter(ringColor, 40)); ringRadial.addColorStop(1, ht.Default.darker(ringColor, 20));var borderRadial = g.createRadialGradient(origin.x, origin.y, ringRadio - ringBorderWidth / 2, origin.x, origin.y, ringRadio + ringBorderWidth / 2); borderRadial.addColorStop(0, ht.Default.brighter(ringBorderColor, 2)); borderRadial.addColorStop(0.5, ht.Default.brighter(ringBorderColor, 4)); borderRadial.addColorStop(1, ht.Default.darker(ringBorderColor, 4)); g.fillStyle = ringRadial; g.lineWidth = ringBorderWidth; g.strokeStyle = borderRadial; g.arc(origin.x, origin.y, ringRadio, 0, 2 * Math.PI); g.closePath(); g.fill(); g.stroke();
效果图:
3.绘制刻度
这里绘制每个刻度采用的是绘制路径的方法,所以声明了一个变量 calibrationPoints 用来存放每个刻度的起始点坐标,根据配置的参数去计算 calibrationPoints 的信息。
首先根据参数 calibrationPercent 计算第一个刻度的起始角度 startAngle ,然后根绝 calibrationCount 的值去计算每个刻度所占用的角度 partAngle ,最后根据三角函数和相应的角度,转化为对应的坐标。
主要代码:
var calibrationPoints = []; for (var i = 0; i < calibrationCount + 1; i++) {var point = {startx: origin.x + (ringRadio + ringBorderWidth + 0 * calibrationHeight) * Math.cos(startAngle - i * partAngle),starty: origin.y - (ringRadio + ringBorderWidth + 0 * calibrationHeight) * Math.sin(startAngle - i * partAngle),endx: origin.x + (ringRadio + ringBorderWidth + 1 * calibrationHeight) * Math.cos(startAngle - i * partAngle),endy: origin.y - (ringRadio + ringBorderWidth + 1 * calibrationHeight) * Math.sin(startAngle - i * partAngle)};if (i <= (calibrationCount * percent) && percent > 0) {point.show = true;} else {point.show = false;}calibrationPoints.push(point); }
有了每个刻度的信息后,接下来就开始绘制刻度。
主要代码:
calibrationPoints.forEach(function (i, index) {g.beginPath();if (calibrationColorWheelShow) {calibrationBrightColor = calibrationColors[index];}g.lineWidth = 1.2 * calibrationWidth;g.strokeStyle = i.show ? calibrationBrightColor : ht.Default.brighter(calibrationDarkColor, 10);g.moveTo(i.startx, i.starty);g.lineTo(i.endx, i.endy);g.closePath();g.stroke(); })calibrationPoints.forEach(function (i, index) {g.beginPath();if (calibrationColorWheelShow) {calibrationBrightColor = calibrationColors[index];}g.lineWidth = calibrationWidth;g.strokeStyle = i.show ? calibrationBrightColor : calibrationDarkColor;g.moveTo(i.startx, i.starty);g.lineTo(i.endx, i.endy);g.closePath();g.stroke(); })
效果图:
考虑到一种高亮颜色太单调,于是加了个色轮。思路:给每个刻度都添加了颜色的标识。
每个刻度的颜色计算方法:把颜色值转换成 rgb 方式,设定多少秒改变完成,每次改变多少值,计算需要多少次,比如 rba(x,y,z) 到 rgb(a,b,c),假设需要 100 次,那么每次设定 rgb((a - x) / 100 + x, (b - y) / 100 + y, (c - z) / 100 + z) 。
主要代码:
if (calibrationColorWheelShow) { // 显示刻度色轮var colors = [];calibrationColorWheel.forEach(function (i) {colors.push(ht.Default.toColorData(i))})// 把颜色值转换成rgb方式,设定多少秒改变完成,每次改变多少值,计算需要多少次// ,比如rba(x,y,z)到rgb(a,b,c),假设需要100次,那么每次设定// rgb((a-x)/100+x,(b-y)/100+y,(c-z)/100+z)var count = Math.ceil(calibrationCount / (calibrationColorWheel.length - 1)); // 渐变次数calibrationColors = [];for (var i = 0; i < colors.length - 1; i++) {for (var j = 1; j <= count; j++) {var item = 'rgb('+ Math.round((colors[i + 1][0] - colors[i][0]) / j + colors[i][0])+ ','+ Math.round((colors[i + 1][1] - colors[i][1]) / j + colors[i][1])+ ','+ Math.round((colors[i + 1][2] - colors[i][2]) / j + colors[i][2])+ ')';calibrationColors.push(item)}} }
效果图:
4.绘制指针
这个主要是根据三角函数去计算相对圆心的偏移角度,按照当前值和刻度最大值的比例来计算偏移量,然后换算成对应的坐标。
主要代码:
pointer = {x: origin.x + (ringRadio - pointerRadio - ringBorderWidth) * Math.cos(startAngle - Math.PI * 2 * calibrationPercent * percent),y: origin.y - (ringRadio - pointerRadio - ringBorderWidth) * Math.sin(startAngle - Math.PI * 2 * calibrationPercent * percent),r: pointerRadio,color: percent > 0 ? calibrationBrightColor : calibrationDarkColor,show: true, }if (pointerShow) {g.beginPath();g.fillStyle = pointer.color;g.arc(pointer.x, pointer.y, pointer.r, 0, Math.PI * 2);g.closePath();g.fill(); }
效果图:
5.绘制标尺
计算标尺角度的算法同指针。
主要代码:
scaleLine = {startx: origin.x,starty: origin.y,endx: origin.x + (ringRadio + ringBorderWidth + 2 * calibrationHeight) * Math.cos(startAngle - Math.PI * 2 * calibrationPercent * percent),endy: origin.y - (ringRadio + ringBorderWidth + 2 * calibrationHeight) * Math.sin(startAngle - Math.PI * 2 * calibrationPercent * percent),color: percent > 0 ? calibrationBrightColor : calibrationDarkColor,show: scaleLineShow, } if (scaleLine) {g.beginPath();g.strokeStyle = 'red';g.setLineDash([1, 2]);g.lineWidth = 0.5 * calibrationWidth;g.moveTo(scaleLine.startx, scaleLine.starty);g.lineTo(scaleLine.endx, scaleLine.endy);g.closePath();g.stroke(); }
效果图:
6.绘制文本
这里主要的就是确定文本所要绘制的位置,然后根据 ht.Default.getTextSize() 来获取文本长度,方便设置文本居中。
主要代码:
if (labelShow) {var text = ht.Default.getTextSize(font, value);g.fillStyle = labelColor;g.font = font;g.fillText(value.toFixed(2), labelDot.x, labelDot.y); }
效果图:
到这就完成了基本的旋钮组件,下面继续做一些细节上的优化。
例如加一些阴影效果,颜色渐变,配色调整等。
主要代码:
var backgroundRadial = g.createRadialGradient(x + 0.5 * width, y + 0.2 * height, 0, x + 0.5 * width, y + 0.2 * height, Math.sqrt(Math.pow(width / 2, 2) + Math.pow(height, 2))); backgroundRadial.addColorStop(0, 'rgba(220,220,220,1)'); backgroundRadial.addColorStop(1, backgroundColor); g.fillStyle = backgroundRadial; g.fillRect(x, y, width, height);g.beginPath(); var ringRadial = g.createRadialGradient(origin.x, origin.y - ringRadio / 2, 0, origin.x, origin.y - ringRadio / 2, 1.5 * ringRadio); ringRadial.addColorStop(0, ht.Default.brighter(ringColor, 40)); // ringRadial.addColorStop(0.25, ht.Default.brighter(ringColor, 40)); ringRadial.addColorStop(1, ht.Default.darker(ringColor, 20));var borderRadial = g.createRadialGradient(origin.x, origin.y, ringRadio - ringBorderWidth / 2, origin.x, origin.y, ringRadio + ringBorderWidth / 2); borderRadial.addColorStop(0, ht.Default.brighter(ringBorderColor, 2)); borderRadial.addColorStop(0.5, ht.Default.brighter(ringBorderColor, 4)); borderRadial.addColorStop(1, ht.Default.darker(ringBorderColor, 4)); g.fillStyle = ringRadial;g.lineWidth = ringBorderWidth; g.strokeStyle = borderRadial; g.arc(origin.x, origin.y, ringRadio, 0, 2 * Math.PI); g.closePath(); g.fill(); g.shadowBlur = 20; g.shadowColor = shadowColor; g.shadowOffsetY = ringBorderWidth; g.stroke(); g.shadowBlur = 0; g.shadowOffsetY = 0;
效果图:
7.交互效果
以上就是绘制好了一张静态图,最后就只要再加上一些交互效果就可以了。
这里我采用的是 HT for Web 的矢量来实现。可参考 → 戳这
监听 onUp 和 onDraw 事件。
onUp:
当鼠标抬起时,获取当前旋钮显示的值,然后四舍五入,取其最近的刻度校准,使用 ht.Default.startAnim() 添加动画效果。
onDraw:
根据当前鼠标停留的位置,以旋钮原点为参照点,根据三角函数来计算指针和起始刻度的夹角 A ,计算 A 占总刻度的百分比 p ,然后设置当前值为 max * p 。
最后使用 HT 实现:
var gv = new ht.graph.GraphView();dm = gv.dm();dm.a('pannable', true);dm.a('zoomable', true);dm.a('rectSelectable', true);ht.Default.setCompType('knob',func); //注册组件ht.Default.setImage('iconKnob', data); //注册图片var node = new ht.Node();node.setImage('iconKnob');node.s('2d.movable', false);dm.add(node);gv.fitContent();gv.addToDOM();window.addEventListener('resize',function(e) {gv.invalidate();gv.fitContent();},false);
转载于:https://www.cnblogs.com/htdaydayup/p/11258689.html
基于 HTML5 Canvas 的可交互旋钮组件相关推荐
- 基于html5 Canvas图表库 : ECharts
基于html5 Canvas图表库 : ECharts 分类 编程技术 ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生 ...
- echart图片库_基于html5 Canvas图表库 : ECharts
ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值 ...
- HTML绘制交互图,基于 HTML5 Canvas 的交互式地铁线路图
原标题:基于 HTML5 Canvas 的交互式地铁线路图 作者:xhload3d my.oschina.net/xhload3d/blog/1629064 摘要:感觉目前地铁上的地铁线路图也不是很人 ...
- php项目网页音乐播放器插件,基于HTML5 canvas和Web Audio的音频播放器插件
wavesurfer.js是一款基于HTML5 canvas和Web Audio的音频播放器插件.通过wavesurfer.js你可以使用它来制作各种HTML5音频播放器,它可以在各种支持 Web A ...
- php仪表盘,基于HTML5 canvas的仪表盘插件
简要教程 canvas-gauges是一款基于HTML5 Canvas的仪表盘插件.该仪表盘插件使用纯js来驱动动画,可以制作圆形和线性的仪表盘组件. 安装 可以通过npm来安装该仪表盘插件$ npm ...
- 基于HTML5 Canvas和jQuery 的画图工具的实现
简介 HTML5 提供了强大的Canvas元素,使用Canvas并结合Javascript 可以实现一些非常强大的功能.本文就介绍一下基于HTML5 Canvas 的画图工具的实现.废话少说,先看成品 ...
- html5 can,基于html5 can-vas实现漫天飞雪效果实例
本文实例讲述了基于html5 canvas实现漫天飞雪效果的方法,运行该实例可以看到很棒的下雪效果.如下图所示: 主要代码如下:代码如下:ttp://www.w3.org/TR/xhtml1/DTD/ ...
- html5游戏开发马赛克对比,基于HTML5 Canvas的纯JS图片马赛克效果插件
这是一款基于HTML5 canvas的图片马赛克js插件.该图片马赛克插件使用简单,可调整马赛克的大小,透明度等属性,适合用于制作一些特殊的图片效果. 基于HTML5 Canvas的纯JS图片马赛克效 ...
- html圆圈倒计时,基于HTML5 canvas圆形倒计时器jQuery插件
这是一款基于html5 canvas的圆形倒计时器jQuery插件.它可以使你非常轻松的创建圆形的倒计时器.该jQuery倒计时器插件有12种themes,它们基于 HTML5 canvas 来渲染各 ...
- 推荐18个基于 HTML5 Canvas 开发的图表库 - 梦想天空(山边小溪) - 博客园
推荐18个基于 HTML5 Canvas 开发的图表库 - 梦想天空(山边小溪) - 博客园 推荐18个基于 HTML5 Canvas 开发的图表库
最新文章
- 网站导航栏如何设置更利于提升SEO优化效果?
- 简述一下extern C的小作用
- poj 2421 Constructing Roads
- CentOS 7 DIG命令工具打上EDNS补丁
- 中高级JavaScript易错面试题
- 滴滴 KDD 2018 论文详解:基于强化学习技术的智能派单模型
- 安卓应用安全指南 5.1 创建密码输入界面
- TurboMail邮件服务器帮你应付电子邮件归档危机
- webpack vue-cli 常见问题总结
- 一文了解 Serverless 2021 大事件
- I-Deas TMG 培训资料 (7)
- baidupcsgo安卓_GitHub - orenbek2019/BaiduPCS-Go: 百度网盘客户端 - Go语言编写
- java小程序体重监测,一个计算标准体重的小程序
- 4维俄罗斯方块 java_烧脑的方块:解析“俄罗斯方块”4种不同的基础模块
- 手机指纹识别测试软件,指纹测算-指纹照相机 扫描识别指纹评分
- MSCNN论文解读-A Unified Multi-scale Deep Convolutional Neural Network for Fast Object Detection
- 输入年月日实现计算这是一年的第几天
- 【学习笔记】OFDM中信道估计技术分析与实现
- Metasploit工具使用(下)
- CXF框架发布WebService服务的例子
热门文章
- TIME-WAIT状态
- 字符串资源的内部格式
- CCIE试验备考之交换security
- 子页面赋值给父页面的控件方法
- Windows® Server 2003 SP1 Platform SDK Web Install
- mifare classic 2.2.3中文_西班牙人为什么学中文?他们是这么说的……
- 华为5g鸿蒙麒麟,华为5G亮王牌:鸿蒙系统+7800W+麒麟990+防水,钱包按耐不住!
- Linux系统编程——vfork() 函数详解
- [转载]i++是否是线程安全的?
- 蓝桥杯试题开灯游戏c语言,[蓝桥杯][算法提高VIP]开灯游戏 (C++代码)