前言

此次的 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 的可交互旋钮组件相关推荐

  1. 基于html5 Canvas图表库 : ECharts

    基于html5 Canvas图表库 : ECharts 分类 编程技术 ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生 ...

  2. echart图片库_基于html5 Canvas图表库 : ECharts

    ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值 ...

  3. HTML绘制交互图,基于 HTML5 Canvas 的交互式地铁线路图

    原标题:基于 HTML5 Canvas 的交互式地铁线路图 作者:xhload3d my.oschina.net/xhload3d/blog/1629064 摘要:感觉目前地铁上的地铁线路图也不是很人 ...

  4. php项目网页音乐播放器插件,基于HTML5 canvas和Web Audio的音频播放器插件

    wavesurfer.js是一款基于HTML5 canvas和Web Audio的音频播放器插件.通过wavesurfer.js你可以使用它来制作各种HTML5音频播放器,它可以在各种支持 Web A ...

  5. php仪表盘,基于HTML5 canvas的仪表盘插件

    简要教程 canvas-gauges是一款基于HTML5 Canvas的仪表盘插件.该仪表盘插件使用纯js来驱动动画,可以制作圆形和线性的仪表盘组件. 安装 可以通过npm来安装该仪表盘插件$ npm ...

  6. 基于HTML5 Canvas和jQuery 的画图工具的实现

    简介 HTML5 提供了强大的Canvas元素,使用Canvas并结合Javascript 可以实现一些非常强大的功能.本文就介绍一下基于HTML5 Canvas 的画图工具的实现.废话少说,先看成品 ...

  7. html5 can,基于html5 can-vas实现漫天飞雪效果实例

    本文实例讲述了基于html5 canvas实现漫天飞雪效果的方法,运行该实例可以看到很棒的下雪效果.如下图所示: 主要代码如下:代码如下:ttp://www.w3.org/TR/xhtml1/DTD/ ...

  8. html5游戏开发马赛克对比,基于HTML5 Canvas的纯JS图片马赛克效果插件

    这是一款基于HTML5 canvas的图片马赛克js插件.该图片马赛克插件使用简单,可调整马赛克的大小,透明度等属性,适合用于制作一些特殊的图片效果. 基于HTML5 Canvas的纯JS图片马赛克效 ...

  9. html圆圈倒计时,基于HTML5 canvas圆形倒计时器jQuery插件

    这是一款基于html5 canvas的圆形倒计时器jQuery插件.它可以使你非常轻松的创建圆形的倒计时器.该jQuery倒计时器插件有12种themes,它们基于 HTML5 canvas 来渲染各 ...

  10. 推荐18个基于 HTML5 Canvas 开发的图表库 - 梦想天空(山边小溪) - 博客园

    推荐18个基于 HTML5 Canvas 开发的图表库 - 梦想天空(山边小溪) - 博客园 推荐18个基于 HTML5 Canvas 开发的图表库

最新文章

  1. 网站导航栏如何设置更利于提升SEO优化效果?
  2. 简述一下extern C的小作用
  3. poj 2421 Constructing Roads
  4. CentOS 7 DIG命令工具打上EDNS补丁
  5. 中高级JavaScript易错面试题
  6. 滴滴 KDD 2018 论文详解:基于强化学习技术的智能派单模型
  7. 安卓应用安全指南 5.1 创建密码输入界面
  8. TurboMail邮件服务器帮你应付电子邮件归档危机
  9. webpack vue-cli 常见问题总结
  10. 一文了解 Serverless 2021 大事件
  11. I-Deas TMG 培训资料 (7)
  12. baidupcsgo安卓_GitHub - orenbek2019/BaiduPCS-Go: 百度网盘客户端 - Go语言编写
  13. java小程序体重监测,一个计算标准体重的小程序
  14. 4维俄罗斯方块 java_烧脑的方块:解析“俄罗斯方块”4种不同的基础模块
  15. 手机指纹识别测试软件,指纹测算-指纹照相机 扫描识别指纹评分
  16. MSCNN论文解读-A Unified Multi-scale Deep Convolutional Neural Network for Fast Object Detection
  17. 输入年月日实现计算这是一年的第几天
  18. 【学习笔记】OFDM中信道估计技术分析与实现
  19. Metasploit工具使用(下)
  20. CXF框架发布WebService服务的例子

热门文章

  1. TIME-WAIT状态
  2. 字符串资源的内部格式
  3. CCIE试验备考之交换security
  4. 子页面赋值给父页面的控件方法
  5. Windows® Server 2003 SP1 Platform SDK Web Install
  6. mifare classic 2.2.3中文_西班牙人为什么学中文?他们是这么说的……
  7. 华为5g鸿蒙麒麟,华为5G亮王牌:鸿蒙系统+7800W+麒麟990+防水,钱包按耐不住!
  8. Linux系统编程——vfork() 函数详解
  9. [转载]i++是否是线程安全的?
  10. 蓝桥杯试题开灯游戏c语言,[蓝桥杯][算法提高VIP]开灯游戏 (C++代码)