接上回的样式(一):https://blog.csdn.net/gongjianbo1992/article/details/112748866
新增了两种 Loading 样式。效果如下:
代码链接(CustomLoading3 / 4): https://github.com/gongjianbo/QmlComponentStyle
实现代码:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Shapes 1.12
//自定义loading效果
//龚建波 2022-02-09
Item {
id: control
implicitWidth: 160
implicitHeight: 160
property int itemMargin: 5
property int itemBorder: 4
//item的宽度
property int itemWidth: 16
//item的颜色
property color itemColor: "#0486FF"
//
property double _rotate: _from
property double _from: 30
property double _to: 150
//
property bool running: visible
//动画1旋转
RotationAnimation {
target: sp
from: 0
to: 360
loops: Animation.Infinite
running: control.running
duration: 3000
}
//动画2控制长度形变
SequentialAnimation {
loops: Animation.Infinite
running: control.running
NumberAnimation {
target: control
property: "_rotate"
from: _from
to: _to
duration: 2000
}
NumberAnimation {
duration: 2000 //停顿
}
NumberAnimation {
target: control
property: "_rotate"
from: _to
to: _from
duration: 1000
}
NumberAnimation {
duration: 2000 //停顿
}
}
Shape {
id: sp
width: control.width
height: control.height
layer{
enabled: true
smooth: true
samples: 16
}
//底部浅色
ShapePath {
strokeWidth: itemWidth+itemBorder*2
strokeColor: Qt.lighter(itemColor, 1.9)
strokeStyle: ShapePath.SolidLine
fillColor: "transparent"
capStyle: ShapePath.RoundCap
joinStyle: ShapePath.RoundJoin
PathAngleArc {
centerX: width/2
centerY: height/2
radiusX: width/2-itemWidth/2-itemMargin-itemBorder
radiusY: height/2-itemWidth/2-itemMargin-itemBorder
startAngle: 0
sweepAngle: 360
moveToStart: true
}
}
//底部深色
ShapePath {
strokeWidth: itemWidth
strokeColor: Qt.lighter(itemColor, 1.8)
strokeStyle: ShapePath.SolidLine
fillColor: "transparent"
capStyle: ShapePath.RoundCap
joinStyle: ShapePath.RoundJoin
PathAngleArc {
centerX: width/2
centerY: height/2
radiusX: width/2-itemWidth/2-itemMargin-itemBorder
radiusY: height/2-itemWidth/2-itemMargin-itemBorder
startAngle: 0
sweepAngle: 360
moveToStart: true
}
}
//旋转的曲线
ShapePath {
strokeWidth: itemWidth
strokeColor: itemColor
strokeStyle: ShapePath.SolidLine
fillColor: "transparent"
capStyle: ShapePath.RoundCap
joinStyle: ShapePath.RoundJoin
PathAngleArc {
centerX: width/2
centerY: height/2
radiusX: width/2-itemWidth/2-itemMargin-itemBorder
radiusY: height/2-itemWidth/2-itemMargin-itemBorder
startAngle: 0
sweepAngle: control.running ? -_rotate : 360
moveToStart: true
}
PathAngleArc {
centerX: width/2
centerY: height/2
radiusX: width/2-itemWidth/2-itemMargin-itemBorder
radiusY: height/2-itemWidth/2-itemMargin-itemBorder
startAngle: 180
sweepAngle: control.running ? -_rotate : 360
moveToStart: true
}
}
}
}
import QtQuick 2.12
import QtQuick.Controls 2.12
//自定义loading效果
//龚建波 2022-02-08
Item {
id: control
//item的颜色
property color itemColor: "#0486FF"
//当前旋转的x轴还是y轴
property int _transX: 0
//当前旋转的角度,0-180后切换到另一个轴旋转
property double _transRotate: 0
//
property bool running: visible
implicitHeight: 160
implicitWidth: 160
//动画
SequentialAnimation {
loops: Animation.Infinite
running: control.running
NumberAnimation {
target: control
property: "_transRotate"
from: 0
to: 180
duration: 1000
}
NumberAnimation {
target: control
property: "_transX"
from: 0
to: 1
duration: 200
}
NumberAnimation {
target: control
property: "_transRotate"
from: 180
to: 0
duration: 1000
}
NumberAnimation {
target: control
property: "_transX"
from: 1
to: 0
duration: 200
}
}
Item {
id: content
anchors.fill: parent
anchors.margins: 8
//翻转的方块
Rectangle {
id: rect
width: content.width
height: content.height
color: control.itemColor
antialiasing: true
transform: [
Rotation {
angle: control.running ? control._transRotate : 0
axis{
x: control._transX ? 1 : 0
y: control._transX ? 0 : 1
z: 0
}
origin{
x: rect.width / 2
y: rect.height / 2
}
}
]
}
}
}
第一个废弃的逻辑,现在 clip 方式替换成了 Shapes 绘制:
import QtQuick 2.12
import QtQuick.Controls 2.12
Item {
id: control
//item的宽度
property int itemWidth: 16
//item的颜色
property color itemColor: "#0486FF"
//
property double _rotate: _from
property double _from: 30
property double _to: 150
//
property bool running: visible
implicitHeight: 160
implicitWidth: 160
//动画1旋转
RotationAnimation {
target: content
from: 0
to: 360
loops: Animation.Infinite
running: control.running
duration: 3000
}
//动画2控制长度形变
SequentialAnimation {
loops: Animation.Infinite
running: control.running
NumberAnimation {
target: control
property: "_rotate"
from: _from
to: _to
duration: 1000
}
NumberAnimation {
duration: 1000 //停顿
}
NumberAnimation {
target: control
property: "_rotate"
from: _to
to: _from
duration: 2000
}
NumberAnimation {
duration: 3000 //停顿
}
}
//半透明背景
Rectangle {
anchors.fill: parent
anchors.margins: 2
color: "transparent"
border.width: control.itemWidth + 6
border.color: control.itemColor
opacity: 0.1
radius: width / 2
}
Rectangle {
anchors.fill: parent
anchors.margins: 5
color: "transparent"
border.width: control.itemWidth
border.color: control.itemColor
opacity: 0.2
radius: width / 2
}
//整体旋转
Item {
id: content
anchors.fill: parent
anchors.margins: 5
//item 1
Item {
width: parent.width
height: parent.height / 2
clip: true
Item {
width: parent.width
height: parent.height
rotation: _rotate
transformOrigin: Item.Bottom
clip: true
Rectangle {
width: content.width
height: content.height
color: "transparent"
border.width: control.itemWidth
border.color: control.itemColor
radius: width / 2
}
}
}
//item 2
Item {
y: parent.height / 2
width: parent.width
height: parent.height / 2
clip: true
Item {
width: parent.width
height: parent.height
rotation: _rotate
transformOrigin: Item.Top
clip: true
Rectangle {
y: -content.height / 2
width: content.width
height: content.height
color: "transparent"
border.width: control.itemWidth
border.color: control.itemColor
radius: width / 2
}
}
}
//端点四个
Repeater {
model: ListModel {
ListElement { mul: 0; add: 90 }
ListElement { mul: 1; add: -90 }
ListElement { mul: 0; add: 270 }
ListElement { mul: 1; add: 90 }
}
delegate: Rectangle {
x: (content.width/2 - control.itemWidth/2) *
(1 + Math.sin((model.mul*_rotate+model.add)/360*6.283185307179))
y: (content.height/2 - control.itemWidth/2) *
(1 - Math.cos((model.mul*_rotate+model.add)/360*6.283185307179))
width: control.itemWidth
height: width
color: control.itemColor
radius: width / 2
}
}
}
}