原文:qml扇形角度动态渲染控件封装
import QtQuick 2.0
Item {
id:root
property url imagePath
property alias effectWidth:displayEffect.width
property alias effectHeight: displayEffect.height
property alias curOffset: displayEffect.offsetVal
property real originX:effectWidth/2
property real originY:effectHeight/2
property real beginAngle:360.0
property real endAngle:0.0
property int durTime:2000
property real curentAngle:0
property real derection: endAngle-beginAngle
property alias angle: animation.angle
Image {
id: srcImg
visible: false
source: imagePath
}
ShaderEffect {
id: displayEffect
width: srcImg.width
height: srcImg.height
blending: true
visible: true
cullMode: ShaderEffect.BackFaceCulling
property real degre : endAngle
property real bAngle :beginAngle
property variant src: srcImg
property real offsetVal: 1
property real angleDerection: derection
vertexShader: "
uniform highp mat4 qt_Matrix;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 coord;
void main() {
coord = qt_MultiTexCoord0;
gl_Position = qt_Matrix * qt_Vertex;
}"
fragmentShader: "
varying highp vec2 coord;
uniform sampler2D src;
uniform lowp float qt_Opacity;
uniform highp float degre;
uniform highp float bAngle;
uniform highp float offsetVal;
uniform lowp float angleDerection;
void main() {
float angle = radians(degre);
float bangle = radians(bAngle);
float m = tan(angle)*offsetVal;
float bm = tan(bangle)*offsetVal;
lowp vec4 tex = texture2D(src, coord);
if(angleDerection > 0.0)
{
if(degre <=90.0 && degre>=0.0 )
{if(coord.y<=0.5 && coord.x>=0.5 && coord.y< (0.5*m+0.5-coord.x*m) || coord.y>0.5||coord.x<0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(degre > 90.0 && degre <= 180.0)
{if(coord.x<=0.5 && coord.y<=0.5 && coord.y > (0.5*m+0.5-coord.x*m) || coord.y>0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(degre > 180.0 && degre < 270.0)
{if(coord.y>=0.5 && coord.x<=0.5 && coord.y > (0.5*m+0.5-coord.x*m) || (coord.x>0.5 && coord.y>0.5)) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(degre >=270.0 && degre<=360.0)
{if(coord.y>=0.5 && coord.x>=0.5 && coord.y < (0.5*m+0.5-coord.x*m)) {tex = vec4(0.0,0.0,0.0,0.0);}}
if(bAngle <=90.0 && bAngle>=0.0 )
{if(coord.y> (0.5*bm+0.5-coord.x*bm) && coord.x>=0.5 && coord.y<=0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(bAngle > 90.0 && bAngle <= 180.0)
{if(coord.y< (0.5*bm+0.5-coord.x*bm) && coord.x<=0.5 && coord.y<=0.5 ||(coord.x>=0.5 && coord.y<=0.5)) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(bAngle > 180.0 && bAngle < 270.0)
{if(coord.y< (0.5*bm+0.5-coord.x*bm) && coord.x<=0.5 && coord.y>=0.5 || coord.y<=0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(bAngle >=270.0 && bAngle<=360.0)
{if(coord.y> (0.5*bm+0.5-coord.x*bm) && coord.x>=0.5 && coord.y>=0.5 || coord.x<=0.5 || coord.y<=0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
}
else
{
if(degre <=90.0 && degre>=0.0 )
{if(coord.y<=0.5 && coord.x>=0.5 && coord.y > (0.5*m+0.5-coord.x*m)) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(degre > 90.0 && degre <= 180.0)
{if(coord.y<=0.5 && coord.x<=0.5 && coord.y < (0.5*m+0.5-coord.x*m) || (coord.x>0.5 && coord.y<0.5)) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(degre > 180.0 && degre < 270.0)
{if(coord.y>=0.5 && coord.x<=0.5 && coord.y < (0.5*m+0.5-coord.x*m) || coord.y<0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(degre >=270.0 && degre<=360.0)
{if(coord.y>=0.5 && coord.x>=0.5 && coord.y > (0.5*m+0.5-coord.x*m) || coord.x<0.5||coord.y<0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
if(bAngle <=90.0 && bAngle>=0.0 )
{if(coord.y< (0.5*bm+0.5-coord.x*bm) && coord.x>=0.5 && coord.y<=0.5 ||coord.x<=0.5 ||coord.y>=0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(bAngle > 90.0 && bAngle <= 180.0)
{if(coord.y> (0.5*bm+0.5-coord.x*bm) && coord.x<=0.5 && coord.y<=0.5||coord.y>=0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(bAngle > 180.0 && bAngle < 270.0)
{if(coord.y> (0.5*bm+0.5-coord.x*bm) && coord.x<=0.5 ||(coord.y>=0.5 && coord.x>=0.5)) {tex = vec4(0.0,0.0,0.0,0.0);}}
else if(bAngle >=270.0 && bAngle<=360.0)
{if(coord.y< (0.5*bm+0.5-coord.x*bm) && coord.x>=0.5 && coord.y>=0.5) {tex = vec4(0.0,0.0,0.0,0.0);}}
}
gl_FragColor = tex;
}"
transform: Rotation {
id: animation
origin.x:displayEffect.width/2
origin.y:displayEffect.height/2
angle: 0
}
}
}
使用方法:
上面的代码保存成任意名称的.qml,此处是RealPix.qml
RealPie{
x:0
y:0
// width:60
// height: 124
imagePath:"qrc:/Image/11_.png"
beginAngle: 215
endAngle: 320
}
效果如下:
下面的白色渐变是一个图片,目的是在Ready位置的时候不显示该图片,所以使用上面的控件剪裁了一个扇形区域。
正下方就是是一个扇形区域(x1000rpm那一块),对其下面的控件遮罩,以达到控件的抽出效果。