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 相关文章推荐
jquery multiSelect 多选下拉框
Jul 09 Javascript
jQuery学习笔记之Helloworld
Dec 22 Javascript
Angular中$compile源码分析
Jan 28 Javascript
jQuery使用正则表达式限制文本框只能输入数字
Jun 18 Javascript
BootStrap入门教程(三)之响应式原理
Sep 19 Javascript
浅谈AngularJS中ng-class的使用方法
Nov 11 Javascript
BootStrapTable服务器分页实例解析
Dec 20 Javascript
jquery实现手机端单店铺购物车结算删除功能
Feb 22 Javascript
JavaScript基于activexobject连接远程数据库SQL Server 2014的方法
Jul 12 Javascript
详解javascript常用工具类的封装
Jan 30 Javascript
解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题
Oct 25 Javascript
在vue中实现echarts随窗体变化
Jul 27 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
BBS(php &amp; mysql)完整版(一)
2006/10/09 PHP
PHP中header和session_start前不能有输出原因分析
2013/01/11 PHP
深入php中var_dump方法的使用详解
2013/06/24 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
PHP实现文字写入图片功能
2019/02/18 PHP
PHP大文件分块上传功能实例详解
2019/07/22 PHP
Javascript String对象扩展HTML编码和解码的方法
2009/06/02 Javascript
jquery load()在firefox(火狐)下显示不正常的解决方法
2011/04/05 Javascript
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
如何屏蔽防止别的网站嵌入框架代码
2015/08/24 Javascript
Jquery zTree 树控件异步加载操作
2016/02/25 Javascript
基于JavaScript Array数组方法(新手必看篇)
2016/08/20 Javascript
AngularJS辅助库browserTrigger用法示例
2016/11/03 Javascript
给easyui的datebox控件添加清空按钮的实现方法
2016/11/09 Javascript
JS实现把一个页面层数据传递到另一个页面的两种方式
2018/08/13 Javascript
python网络编程学习笔记(一)
2014/06/09 Python
Python检测网站链接是否已存在
2016/04/07 Python
Python标准库之collections包的使用教程
2017/04/27 Python
Python实现复杂对象转JSON的方法示例
2017/06/22 Python
python负载均衡的简单实现方法
2018/02/04 Python
python单例模式实例解析
2018/08/28 Python
numpy实现神经网络反向传播算法的步骤
2019/12/24 Python
Python如何输出百分比
2020/07/31 Python
HTML5的表单(绝对特别强大的功能)使用示例
2013/06/20 HTML / CSS
boostrap modal 闪现问题的解决方法
2020/09/01 HTML / CSS
JDK安装目录下有哪些内容
2014/08/25 面试题
高校教师自荐信范文
2014/03/13 职场文书
学校安全防火方案
2014/06/07 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
毕业论文致谢怎么写
2015/05/14 职场文书
企业法人代表证明书
2015/06/18 职场文书
退休职工欢送会致辞
2015/08/01 职场文书
2016毕业实习单位评语大全
2015/12/01 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
MySQL不使用order by实现排名的三种思路总结
2021/06/02 MySQL
分析SQL窗口函数之聚合窗口函数
2022/04/21 Oracle