前言
用 QML 做图片倒影,主要是用ShaderEffect组件来实现,先来看看实际效果,如下:
还可以用同样的方式来做其他控件的倒影,例如:
正文
直接来看源码
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle {
id: window
width: 600
height: 500
gradient: Gradient {
GradientStop { position: 0; color: "lightsteelblue" }
GradientStop { position: 1; color: "black" }
}
Image {
id: img
width: 300
height: 170
source: "car.png"
anchors.centerIn: parent
}
ShaderEffect {
anchors.top: img.bottom
width: img.width
height: img.height
anchors.left: img.left
property variant source: img
property size sourceSize: Qt.size(0.5 / img.width, 0.5 / img.height)
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform lowp sampler2D source;
uniform lowp vec2 sourceSize;
uniform lowp float qt_Opacity;
void main() {
lowp vec2 tc = qt_TexCoord0 * vec2(1, -1) + vec2(0, 1);
lowp vec4 col = 0.25 * (texture2D(source, tc + sourceSize)
+ texture2D(source, tc- sourceSize)
+ texture2D(source, tc + sourceSize * vec2(1, -1))
+ texture2D(source, tc + sourceSize * vec2(-1, 1))
);
gl_FragColor = col * qt_Opacity * (1.0 - qt_TexCoord0.y) * 0.2;
}"
}
}
若要拓展做其他控件的倒影,只需要修改property variant source: img 对象即可.
还有一种比较简单的容易理解的方式来实现同样的效果
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle {
id: window
width: 600
height: 500
gradient: Gradient {
GradientStop { position: 0; color: "lightsteelblue" }
GradientStop { position: 1; color: "black" }
}
Image {
id: img
width: 300
height: 170
source: "car.png"
anchors.centerIn: parent
}
Item{
width: img.width
height: img.height
Image{
source: img.source
anchors.fill: parent
transform: Scale{
yScale: -1
origin.y:img.height/2.
}
}
LinearGradient{
width: img.width
height: img.height
gradient: Gradient{
GradientStop{position: 0.0;color:Qt.rgba(0,0,0,0.1)}
GradientStop{position: 0.4;color:Qt.rgba(0,0,0,1)}
}
}
}
}
原理是先通过设置一张倒着的图片,然后在图片上添加一个渐变层,代码很简单,不再赘述。