Tweaked ImagePage behavior

This should made reaction to a single tap more reliable and
flicking back easier.
This commit is contained in:
Slava Monich 2020-10-25 02:15:31 +03:00
parent 5d14d9b000
commit 79e06bd4c4

View file

@ -91,11 +91,9 @@ Page {
} }
SilicaFlickable { SilicaFlickable {
id: imageFlickable
anchors.fill: parent anchors.fill: parent
clip: true flickableDirection: Flickable.VerticalFlick
contentWidth: imagePinchArea.width; interactive: !imageOnly
contentHeight: imagePinchArea.height;
PullDownMenu { PullDownMenu {
visible: !imageOnly && imageUrl visible: !imageOnly && imageUrl
@ -107,76 +105,86 @@ Page {
} }
} }
transitions: Transition {
NumberAnimation { properties: "contentX, contentY"; easing.type: Easing.Linear }
}
AppNotification { AppNotification {
id: imageNotification id: imageNotification
} }
MouseArea { SilicaFlickable {
id: imageFlickable
anchors.fill: parent anchors.fill: parent
visible: singleImage.visible clip: true
onClicked: imageOnly = !imageOnly // Toggle "Image only" mode on tap contentWidth: imagePinchArea.width
} contentHeight: imagePinchArea.height
flickableDirection: Flickable.HorizontalAndVerticalFlick
quickScrollEnabled: false
PinchArea { PinchArea {
id: imagePinchArea id: imagePinchArea
width: Math.max( singleImage.width * singleImage.scale, imageFlickable.width ) width: Math.max( singleImage.width * singleImage.scale, imageFlickable.width )
height: Math.max( singleImage.height * singleImage.scale, imageFlickable.height ) height: Math.max( singleImage.height * singleImage.scale, imageFlickable.height )
enabled: singleImage.visible enabled: singleImage.status === Image.Ready
pinch { pinch {
target: singleImage target: singleImage
minimumScale: 1 minimumScale: 1
maximumScale: 4 maximumScale: 4
} }
onPinchUpdated: { onPinchUpdated: {
imagePage.centerX = pinch.center.x; imagePage.centerX = pinch.center.x
imagePage.centerY = pinch.center.y; imagePage.centerY = pinch.center.y
} imageFlickable.returnToBounds()
}
Image { Image {
id: singleImage id: singleImage
source: imageUrl source: imageUrl
width: imagePage.imageWidth * imagePage.sizingFactor width: imagePage.imageWidth * imagePage.sizingFactor
height: imagePage.imageHeight * imagePage.sizingFactor height: imagePage.imageHeight * imagePage.sizingFactor
anchors.centerIn: parent anchors.centerIn: parent
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
asynchronous: true asynchronous: true
visible: status === Image.Ready ? true : false visible: opacity > 0
opacity: status === Image.Ready ? 1 : 0 opacity: status === Image.Ready ? 1 : 0
Behavior on opacity { NumberAnimation {} } Behavior on opacity { FadeAnimation {} }
onScaleChanged: { onScaleChanged: {
var newWidth = singleImage.width * singleImage.scale; var newWidth = singleImage.width * singleImage.scale;
var newHeight = singleImage.height * singleImage.scale; var newHeight = singleImage.height * singleImage.scale;
var oldWidth = singleImage.width * imagePage.previousScale; var oldWidth = singleImage.width * imagePage.previousScale;
var oldHeight = singleImage.height * imagePage.previousScale; var oldHeight = singleImage.height * imagePage.previousScale;
var widthDifference = newWidth - oldWidth; var widthDifference = newWidth - oldWidth;
var heightDifference = newHeight - oldHeight; var heightDifference = newHeight - oldHeight;
if (oldWidth > imageFlickable.width || newWidth > imageFlickable.width) { if (oldWidth > imageFlickable.width || newWidth > imageFlickable.width) {
var xRatioNew = imagePage.centerX / newWidth; var xRatioNew = imagePage.centerX / newWidth;
var xRatioOld = imagePage.centerX / oldHeight; var xRatioOld = imagePage.centerX / oldHeight;
imageFlickable.contentX = imageFlickable.contentX + ( xRatioNew * widthDifference ); imageFlickable.contentX = imageFlickable.contentX + ( xRatioNew * widthDifference );
} }
if (oldHeight > imageFlickable.height || newHeight > imageFlickable.height) { if (oldHeight > imageFlickable.height || newHeight > imageFlickable.height) {
var yRatioNew = imagePage.centerY / newHeight; var yRatioNew = imagePage.centerY / newHeight;
var yRatioOld = imagePage.centerY / oldHeight; var yRatioOld = imagePage.centerY / oldHeight;
imageFlickable.contentY = imageFlickable.contentY + ( yRatioNew * heightDifference ); imageFlickable.contentY = imageFlickable.contentY + ( yRatioNew * heightDifference );
}
imagePage.previousScale = singleImage.scale;
imagePage.oldCenterX = imagePage.centerX;
imagePage.oldCenterY = imagePage.centerY;
} }
}
imagePage.previousScale = singleImage.scale; MouseArea {
imagePage.oldCenterX = imagePage.centerX; anchors.fill: parent
imagePage.oldCenterY = imagePage.centerY; visible: singleImage.visible
onClicked: imageOnly = !imageOnly // Toggle "Image only" mode on tap
onDoubleClicked: ; // This introduces a delay before onClicked is invoked
} }
} }
}
ScrollDecorator { flickable: imageFlickable }
}
} }
Image { Image {
@ -191,7 +199,7 @@ Page {
asynchronous: true asynchronous: true
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
opacity: 0.15 opacity: visible ? 0.15 : 0
Behavior on opacity { FadeAnimation {} }
} }
} }