QML实现圆环颜色选择器


Posted in Javascript onSeptember 25, 2019

本文实例为大家分享了QML实现圆环颜色选择器的具体代码,供大家参考,具体内容如下

话不多说,先上效果图:

QML实现圆环颜色选择器

ColorSelector组件代码如下,有问题可以留言:

import QtQuick 2.0
import QtQuick.Controls 2.2
Item {
 id:baseItem
 width: 350
 height: width
 signal colorChanged(string newColor);
 property int circleWidth: 40;//圆环宽度
 property var curColor: undefined;

 Rectangle {
  id: control
  width: baseItem.width
  height: width
  color: "transparent"
  border.width: 1
  border.color: "black"
  anchors.margins: 10

  // 根据角度获取颜色值
  function getAngleColor(angle) {
   var color, d;
   if (angle < Math.PI * 2 / 5) { // angle: 0-72
    d = 255 / (Math.PI * 2 / 5) * angle;
    color = '255,' + Math.round(d) + ',0'; // color: 255,0,0 - 255,255,0
   } else if (angle < Math.PI * 4 / 5) { // angle: 72-144
    d = 255 / (Math.PI * 2 / 5) * (angle - Math.PI * 2 / 5);
    color = (255 - Math.round(d)) + ',255,0'; // color: 255,255,0 - 0,255,0
   } else if (angle < Math.PI * 6 / 5) { // angle: 144-216
    d = 255 / (Math.PI * 2 / 5) * (angle - Math.PI * 4 / 5);
    color = '0,255,' + Math.round(d); // color: 0,255,0 - 0,255,255
   } else if (angle < Math.PI * 8 / 5) { // angle: 216-288
    d = 255 / (Math.PI * 2 / 5) * (angle - Math.PI * 6 / 5);
    color = '0,'+(255 - Math.round(d)) + ',255'; // color: 0,255,255 - 0,0,255
   } else { // angle: 288-360
    d = 255 / (Math.PI * 2 / 5) * (angle - Math.PI * 8 / 5);
    color = Math.round(d) + ',0,' + (255 - Math.round(d)) ; // color: 0,0,255 - 255,0,0
   }
   return color;
  }

  // 获取旋转角度
  function getRotateAngle (mouseX, mouseY) {
   var yPosOffset = mouseY - control.width/2; // 计算角度 : tan(x) = (y2-y1)/(x2-x1);
   var xPosOffset = mouseX - control.height/2;
   // 旋转的弧度 hudu, 角度angle
   var hudu = 0, angle = 0;
   if (xPosOffset != 0 && yPosOffset != 0) {
    hudu = Math.atan(Math.abs(yPosOffset / xPosOffset));
   }

   if (xPosOffset === 0 && yPosOffset === 0) {
    return angle;
   } else if (xPosOffset < 0 && yPosOffset < 0) {
    angle = hudu * 180 / Math.PI;     // 左上
   } else if (xPosOffset === 0 && yPosOffset < 0) {
    angle = 90;          // 上 中间
   } else if (xPosOffset > 0 && yPosOffset < 0) {
    angle = 180 - hudu * 180 / Math.PI;    // 右上
   } else if (xPosOffset > 0 && yPosOffset === 0) {
    angle = 180;         // 上 下 中间
   } else if (xPosOffset > 0 && yPosOffset > 0) {
    angle = 180 + hudu * 180 / Math.PI;    // 右下
   } else if (xPosOffset === 0 && yPosOffset > 0) {
    angle = 270;         // 下 中间
   } else if (xPosOffset < 0 && yPosOffset > 0) {
    angle = 360 - hudu * 180 / Math.PI;    // 左下
   }
   return angle;
  }


  // 通过鼠标所在点更新Canvas画图信息
  function updateCanvasByMousePos(x, y){
   var currentAngle = control.getRotateAngle(x, y);
   console.log(x, y, currentAngle);
   updateCanvasByAngle(currentAngle);
  }


  //通过角度更新Canvas画图信息位置
  function updateCanvasByAngle(angle){
   var newX = control.width/2 + - Math.cos(angle*Math.PI/180) * (control.width/2-baseItem.circleWidth/2-2*control.anchors.margins);
   var newY = control.height/2 - Math.sin(angle* Math.PI/180) * (control.height/2-baseItem.circleWidth/2-2*control.anchors.margins);

   console.log("new : ", newX, newY,"\ncur color is :" + baseItem.curColor);
   handle.xDrawPos = newX;
   handle.yDrawPos = newY;
   handle.requestPaint();

   baseItem.curColor='rgb('+control.getAngleColor(((angle+180)%360)/180 * Math.PI)+')';
   baseItem.colorChanged(baseItem.curColor);//发信号
  }

  // 鼠标选择圆环按钮
  Canvas {
   id:handle
   width : parent.width;
   height : width

   property int xDrawPos: 0
   property int yDrawPos: 0

   onPaint: {
    var ctx = getContext("2d")
    ctx.clearRect(0,0,width,height);
    ctx.beginPath();
    ctx.arc(xDrawPos, yDrawPos, baseItem.circleWidth/2 + 10, 0, 2 * Math.PI, false);
    ctx.fillStyle = 'lightblue';
    ctx.fill();
    ctx.strokeStyle = 'transparent';
    ctx.stroke();
    ctx.closePath();

    ctx.beginPath();
    ctx.arc(xDrawPos, yDrawPos, baseItem.circleWidth/2 - 2, 0, 2 * Math.PI, false);
    ctx.fillStyle = baseItem.curColor;
    ctx.fill();
    ctx.strokeStyle = 'transparent';
    ctx.stroke();
    ctx.closePath();
   }

   z:1000
  }

  // 圆环画布
  Canvas {
   id: canvas
   width: parent.width-4*control.anchors.margins;
   height: parent.height
   anchors.centerIn: parent

   onPaint: {
    var ctx = getContext("2d")
    var iSectors = 360;
    var iSectorAngle = (360/iSectors)/180 * Math.PI; // in radians
    ctx.translate(width/2, height/2);
    for (var i = 0; i< iSectors; i++) {
     var startAngle = 0;
     var endAngle = startAngle + iSectorAngle;
     var radius = (width/2-1);
     var color = control.getAngleColor(iSectorAngle * i);
     ctx.beginPath();
     ctx.moveTo(0, 0);
     ctx.arc(0, 0, radius, startAngle, endAngle, false);
     ctx.closePath();
     ctx.strokeStyle = 'rgb('+color+')';
     ctx.stroke();
     ctx.fillStyle = 'rgb('+color+')';
     ctx.fill();
     ctx.rotate(iSectorAngle);
    }
    ctx.restore();

    ctx.save();
    ctx.translate(0,0);
    ctx.beginPath();
    ctx.arc(0, 0, width/2-baseItem.circleWidth, 0, 2 * Math.PI, false);
    ctx.fillStyle = 'white';
    ctx.fill();
    ctx.strokeStyle = 'transparent';
    ctx.stroke();
    ctx.restore();
   }

   MouseArea {
    id:colorSelectorMouseArea
    anchors.fill: parent;
    onMouseXChanged: {
     control.updateCanvasByMousePos(mouseX, mouseY);
    }
   }

   Component.onCompleted:{
    control.updateCanvasByAngle(0);
   }
  }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js四舍五入数学函数round使用实例
May 09 Javascript
多个$(document).ready()的执行顺序实例分析
Jul 26 Javascript
分享经典的JavaScript开发技巧
Nov 21 Javascript
JS平滑无缝滚动效果的实现代码
May 06 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
Sep 09 Javascript
JavaScript DOM节点操作实例小结(新建,删除HTML元素)
Jan 19 Javascript
JavaScript正则表达式和级联效果
Sep 14 Javascript
详解ES6语法之可迭代协议和迭代器协议
Jan 13 Javascript
vue弹窗消息组件的使用方法
Sep 24 Javascript
js canvas画布实现高斯模糊效果
Nov 27 Javascript
Vue源码中要const _toStr = Object.prototype.toString的原因分析
Dec 09 Javascript
js设计模式之单例模式原理与用法详解
Aug 15 Javascript
解决layer 关闭当前弹窗 关闭遮罩层 input值获取不到的问题
Sep 25 #Javascript
微信小程序实现一张或多张图片上传(云开发)
Sep 25 #Javascript
Layer组件多个iframe弹出层打开与关闭及参数传递的方法
Sep 25 #Javascript
layer 关闭指定弹出层的例子
Sep 25 #Javascript
layer关闭弹出窗口触发表单提交问题的处理方法
Sep 25 #Javascript
layer弹窗在键盘按回车将反复刷新的实现方法
Sep 25 #Javascript
Vue 实现一个命令式弹窗组件功能
Sep 25 #Javascript
You might like
php配置php-fpm启动参数及配置详解
2013/11/04 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
2014/12/15 PHP
DWZ+ThinkPHP开发时遇到的问题分析
2016/12/12 PHP
PHP排序算法之基数排序(Radix Sort)实例详解
2018/04/21 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
避免 showModalDialog 弹出新窗体的原因分析
2010/05/31 Javascript
根据选择不同的下拉值出现相对应的文本输入框
2013/08/01 Javascript
浏览器缩放检测的js代码
2014/09/28 Javascript
jquery判断当前浏览器的实现代码
2015/11/07 Javascript
canvas 实现中国象棋
2017/02/17 Javascript
Vue制作Todo List网页
2017/04/26 Javascript
ExtJs异步无法向外传值和赋值的完美解决办法
2017/06/14 Javascript
JS实现的走迷宫小游戏完整实例
2017/07/19 Javascript
AngularJS中控制器函数的定义与使用方法示例
2017/10/10 Javascript
javascript字体颜色控件的开发 JS实现字体控制
2017/11/27 Javascript
vue-cli开发环境实现跨域请求的方法
2018/04/07 Javascript
js实现倒计时器自定义时间和暂停
2019/02/25 Javascript
js实现点击按钮随机生成背景颜色
2020/09/05 Javascript
Python常用模块介绍
2014/11/21 Python
Python中列表的一些基本操作知识汇总
2015/05/20 Python
urllib和BeautifulSoup爬取维基百科的词条简单实例
2018/01/17 Python
使用Python处理Excel表格的简单方法
2018/06/07 Python
Python实现的建造者模式示例
2018/08/06 Python
基于Python实现定时自动给微信好友发送天气预报
2018/10/25 Python
python内存管理机制原理详解
2019/08/12 Python
基于pytorch的保存和加载模型参数的方法
2019/08/17 Python
Python3将jpg转为pdf文件的方法示例
2019/12/13 Python
Tech21美国/加拿大:英国NO.1防摔保护壳品牌
2018/01/20 全球购物
莱德杯高尔夫欧洲官方商店:Ryder Cup Shop
2019/08/14 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)
2014/09/05 面试题
计算机数据库专业职业生涯规划书
2014/02/08 职场文书
财产保全担保书范文
2014/04/01 职场文书
安全技术说明书
2014/05/09 职场文书
公安机关查摆剖析材料
2014/10/10 职场文书