そんな話題があったので試しに作ってみました。
通常はこんな感じ。
Rectangle {
width: 100; height: 100
gradient: Gradient {
GradientStop { position: 0.0; color: "red" }
GradientStop { position: 0.33; color: "yellow" }
GradientStop { position: 1.0; color: "green" }
}
}
/// ポイント ///
・グラデをかけたい四角をクリップ設定にして、中にグラデをかけた四角を置く
・rotationで中の四角を回転させる(使い勝手がいい)
・親のサイズに合わせて調度良くリサイズをする
・関数でもバインドが働く
・もっと効率いい計算方法あったら教えて下さい
サンプルコード(拡張エレメント込)はこんなかんじです。
エレメント名がMSっぽいとかは気にしたらダメです。
サンプルはウインドウサイズを変更するとグラデの角度が変わります。
実際に使用するときは、親のエレメントのclipをtrueにします。
サンプルのスクリーンショット
呼び出し元
import QtQuick 2.0
Rectangle {
width: 600
height: 400
color: "black"
Rectangle{
anchors.centerIn: parent
width: parent.width / 3
height: parent.height / 3
// clip: true
GradientEx{
id: grad
gradient: Gradient{
GradientStop { position: 0.0; color: "red" }
GradientStop { position: 0.33; color: "yellow" }
GradientStop { position: 1.0; color: "green" }
}
rotation: (2 * (parent.x - 400)) % 360
}
//ちゃんとグラデの四角が良いサイズになってるか確認する用の四角(親のclipは解除して確認する)
Rectangle{
anchors.fill: parent
opacity: 0.5
}
}
Text{
text: "angle=" + grad.rotation
color: "white"
}
}
拡張したグラデ
import QtQuick 2.0
Rectangle{
anchors.centerIn: parent
width: calcWidth()
height: calcHeight()
//ラジアンを予め計算しておく
property real rad: calcRad()
//角度は0~90にしないと面倒なので
function calcRad(){
var r = rotation;
while(r > 90){
r -= 90;
}
while(r < 0){
r += 90;
}
return r * Math.PI / 180;
}
//0~90度を基準に90度ごとにwidthとheightにかけるcosとsinが入れ替わる
//なのでマイナス側の-90~0は、入れ替わりになるように90度ずらして判定する
function calcWidth(){
var len = 0;
var r = rotation >= 0 ? rotation : -(rotation - 90)
if((0 <= r && r <= 90) || (180 < r && r <= 270)){
len = parent.width * Math.cos(rad) + parent.height * Math.sin(rad);
}else if((90 < r && r <= 180) || (270 < r && r <= 360)){
len = parent.width * Math.sin(rad) + parent.height * Math.cos(rad);
}else{
len = parent.width * Math.cos(rad) + parent.height * Math.sin(rad);
}
return len;
}
function calcHeight(){
var len = 0;
var r = rotation >= 0 ? rotation : -(rotation - 90)
if((0 <= r && r <= 90) || (180 < r && r <= 270)){
len = parent.width * Math.sin(rad) + parent.height * Math.cos(rad);
}else if((90 < r && r <= 180) || (270 < r && r <= 360)){
len = parent.width * Math.cos(rad) + parent.height * Math.sin(rad);
}else{
len = parent.width * Math.sin(rad) + parent.height * Math.cos(rad);
}
return len;
}
}
コメント