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 相关文章推荐
[全兼容哦]--实用、简洁、炫酷的页面转入效果loing
May 07 Javascript
JavaScript Archive Network 集合
May 12 Javascript
js中的前绑定和后绑定详解
Aug 01 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 Javascript
addEventListener 的用法示例介绍
May 07 Javascript
ExtJS中设置下拉列表框不可编辑的方法
May 07 Javascript
Angularjs中使用指令绑定点击事件的方法
Mar 30 Javascript
vue.js的安装方法
May 12 Javascript
实例讲解Vue.js中router传参
Apr 22 Javascript
学习RxJS之JavaScript框架Cycle.js
Jun 17 Javascript
webpack HappyPack实战详解
Oct 08 Javascript
javascript之Object.assign()的痛点分析
Mar 03 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
《超神学院》霸气归来, 天使彦上演维多利亚的秘密
2020/03/02 国漫
新闻分类录入、显示系统
2006/10/09 PHP
2个比较经典的PHP加密解密函数分享
2014/07/01 PHP
thinkphp3.0输出重复两次的解决方法
2014/12/19 PHP
ecshop实现smtp发送邮件
2015/02/03 PHP
typecho插件编写教程(二):写一个新插件
2015/05/28 PHP
学习php设计模式 php实现模板方法模式
2015/12/08 PHP
php 文件下载 出现下载文件内容乱码损坏的解决方法(推荐)
2016/11/16 PHP
yii2利用自带UploadedFile实现上传图片的示例
2017/02/16 PHP
PHP7新功能总结
2019/04/14 PHP
基于JQuery的数字改变的动画效果--可用来做计数器
2010/08/11 Javascript
js动态给table添加/删除tr的方法
2013/08/02 Javascript
AngularJS Phonecat实例讲解
2016/11/21 Javascript
Vue工程模板文件 webpack打包配置方法
2017/12/26 Javascript
Angular父组件调用子组件的方法
2018/04/02 Javascript
详解Nuxt.js部署及踩过的坑
2018/08/07 Javascript
详解vue.js移动端配置flexible.js及注意事项
2019/04/10 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
Node.js系列之发起get/post请求(2)
2019/08/30 Javascript
如何阻止小程序遮罩层下方图层滚动
2019/09/05 Javascript
vue cli4下环境变量和模式示例详解
2020/04/09 Javascript
如何使用Javascript中的this关键字
2020/05/28 Javascript
Python使用Django实现博客系统完整版
2020/09/29 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
python实现机器学习之多元线性回归
2018/09/06 Python
Python Gluon参数和模块命名操作教程
2019/12/18 Python
3种python调用其他脚本的方法
2020/01/06 Python
python通过安装itchat包实现微信自动回复收到的春节祝福
2020/01/19 Python
Python之Matplotlib文字与注释的使用方法
2020/06/18 Python
微信端html5页面调用分享接口示例
2018/03/14 HTML / CSS
中国综合性网上购物商城:当当(网上卖书起家)
2016/11/16 全球购物
大学生年度自我鉴定
2013/10/31 职场文书
毕业生自荐书
2014/02/02 职场文书
土地转让协议书范本
2014/04/15 职场文书
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
2021/07/16 Java/Android
Windows Server 2008 修改远程登录端口以及配置防火墙
2022/04/28 Servers