mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-27 13:37:48 -04:00
- A new minimal and fun island instance (dot) that gets out of your way to be tossed anywhere on your screen - Dankisland freedom is here too! It can now also be used in anywhere mode and used horizontally or vertically as you see fit!
185 lines
8.3 KiB
QML
185 lines
8.3 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
|
|
QtObject {
|
|
id: root
|
|
|
|
property bool enabled: true
|
|
property bool running: false
|
|
property bool reducedMotion: false
|
|
|
|
property real stiffness: 560
|
|
property real damping: 37
|
|
property real mass: 1
|
|
property real positionEpsilon: 0.035
|
|
property real velocityEpsilon: 0.035
|
|
property real maximumFrameTime: 1 / 30
|
|
property real integrationStep: 1 / 240
|
|
readonly property real timeConstantMs: reducedMotion ? 0 : 2000 * mass / Math.max(1, damping)
|
|
|
|
property real currentWidth: 176
|
|
property real currentHeight: 42
|
|
property real currentOffsetAlong: 0
|
|
property real currentOffsetCross: 8
|
|
property real currentTopLeftRadius: 21
|
|
property real currentTopRightRadius: 21
|
|
property real currentBottomLeftRadius: 21
|
|
property real currentBottomRightRadius: 21
|
|
|
|
property real targetWidth: currentWidth
|
|
property real targetHeight: currentHeight
|
|
property real targetOffsetAlong: currentOffsetAlong
|
|
property real targetOffsetCross: currentOffsetCross
|
|
property real targetTopLeftRadius: currentTopLeftRadius
|
|
property real targetTopRightRadius: currentTopRightRadius
|
|
property real targetBottomLeftRadius: currentBottomLeftRadius
|
|
property real targetBottomRightRadius: currentBottomRightRadius
|
|
|
|
property real velocityWidth: 0
|
|
property real velocityHeight: 0
|
|
property real velocityOffsetAlong: 0
|
|
property real velocityOffsetCross: 0
|
|
property real velocityTopLeftRadius: 0
|
|
property real velocityTopRightRadius: 0
|
|
property real velocityBottomLeftRadius: 0
|
|
property real velocityBottomRightRadius: 0
|
|
|
|
function matchesTarget(target) {
|
|
return targetWidth === target.width && targetHeight === target.height && targetOffsetAlong === target.offsetAlong && targetOffsetCross === target.offsetCross && targetTopLeftRadius === target.topLeftRadius && targetTopRightRadius === target.topRightRadius && targetBottomLeftRadius === target.bottomLeftRadius && targetBottomRightRadius === target.bottomRightRadius;
|
|
}
|
|
|
|
function setTarget(target, seedVelocity) {
|
|
if (matchesTarget(target) && !seedVelocity)
|
|
return;
|
|
targetWidth = target.width;
|
|
targetHeight = target.height;
|
|
targetOffsetAlong = target.offsetAlong;
|
|
targetOffsetCross = target.offsetCross;
|
|
targetTopLeftRadius = target.topLeftRadius;
|
|
targetTopRightRadius = target.topRightRadius;
|
|
targetBottomLeftRadius = target.bottomLeftRadius;
|
|
targetBottomRightRadius = target.bottomRightRadius;
|
|
|
|
if (seedVelocity) {
|
|
velocityOffsetAlong = seedVelocity.offsetAlong ?? velocityOffsetAlong;
|
|
velocityOffsetCross = seedVelocity.offsetCross ?? velocityOffsetCross;
|
|
}
|
|
|
|
if (reducedMotion) {
|
|
settle();
|
|
return;
|
|
}
|
|
|
|
if (!isSettled())
|
|
running = true;
|
|
}
|
|
|
|
function snapTo(target) {
|
|
targetWidth = target.width;
|
|
targetHeight = target.height;
|
|
targetOffsetAlong = target.offsetAlong;
|
|
targetOffsetCross = target.offsetCross;
|
|
targetTopLeftRadius = target.topLeftRadius;
|
|
targetTopRightRadius = target.topRightRadius;
|
|
targetBottomLeftRadius = target.bottomLeftRadius;
|
|
targetBottomRightRadius = target.bottomRightRadius;
|
|
|
|
currentWidth = target.width;
|
|
currentHeight = target.height;
|
|
currentOffsetAlong = target.offsetAlong;
|
|
currentOffsetCross = target.offsetCross;
|
|
currentTopLeftRadius = target.topLeftRadius;
|
|
currentTopRightRadius = target.topRightRadius;
|
|
currentBottomLeftRadius = target.bottomLeftRadius;
|
|
currentBottomRightRadius = target.bottomRightRadius;
|
|
|
|
velocityWidth = 0;
|
|
velocityHeight = 0;
|
|
velocityOffsetAlong = 0;
|
|
velocityOffsetCross = 0;
|
|
velocityTopLeftRadius = 0;
|
|
velocityTopRightRadius = 0;
|
|
velocityBottomLeftRadius = 0;
|
|
velocityBottomRightRadius = 0;
|
|
running = false;
|
|
}
|
|
|
|
function isSettled() {
|
|
const positionSettled = Math.abs(targetWidth - currentWidth) <= positionEpsilon && Math.abs(targetHeight - currentHeight) <= positionEpsilon && Math.abs(targetOffsetAlong - currentOffsetAlong) <= positionEpsilon && Math.abs(targetOffsetCross - currentOffsetCross) <= positionEpsilon && Math.abs(targetTopLeftRadius - currentTopLeftRadius) <= positionEpsilon && Math.abs(targetTopRightRadius - currentTopRightRadius) <= positionEpsilon && Math.abs(targetBottomLeftRadius - currentBottomLeftRadius) <= positionEpsilon && Math.abs(targetBottomRightRadius - currentBottomRightRadius) <= positionEpsilon;
|
|
const velocitySettled = Math.abs(velocityWidth) <= velocityEpsilon && Math.abs(velocityHeight) <= velocityEpsilon && Math.abs(velocityOffsetAlong) <= velocityEpsilon && Math.abs(velocityOffsetCross) <= velocityEpsilon && Math.abs(velocityTopLeftRadius) <= velocityEpsilon && Math.abs(velocityTopRightRadius) <= velocityEpsilon && Math.abs(velocityBottomLeftRadius) <= velocityEpsilon && Math.abs(velocityBottomRightRadius) <= velocityEpsilon;
|
|
return positionSettled && velocitySettled;
|
|
}
|
|
|
|
function settle() {
|
|
currentWidth = targetWidth;
|
|
currentHeight = targetHeight;
|
|
currentOffsetAlong = targetOffsetAlong;
|
|
currentOffsetCross = targetOffsetCross;
|
|
currentTopLeftRadius = targetTopLeftRadius;
|
|
currentTopRightRadius = targetTopRightRadius;
|
|
currentBottomLeftRadius = targetBottomLeftRadius;
|
|
currentBottomRightRadius = targetBottomRightRadius;
|
|
|
|
velocityWidth = 0;
|
|
velocityHeight = 0;
|
|
velocityOffsetAlong = 0;
|
|
velocityOffsetCross = 0;
|
|
velocityTopLeftRadius = 0;
|
|
velocityTopRightRadius = 0;
|
|
velocityBottomLeftRadius = 0;
|
|
velocityBottomRightRadius = 0;
|
|
running = false;
|
|
}
|
|
|
|
function advance(rawFrameTime) {
|
|
if (!enabled || !running || reducedMotion)
|
|
return;
|
|
|
|
const frameTime = Math.min(Math.max(rawFrameTime, 0), maximumFrameTime);
|
|
if (frameTime <= 0)
|
|
return;
|
|
|
|
const steps = Math.max(1, Math.ceil(frameTime / integrationStep));
|
|
const step = frameTime / steps;
|
|
const inverseMass = 1 / Math.max(0.001, mass);
|
|
|
|
for (let i = 0; i < steps; i++) {
|
|
velocityWidth += (stiffness * (targetWidth - currentWidth) - damping * velocityWidth) * inverseMass * step;
|
|
velocityHeight += (stiffness * (targetHeight - currentHeight) - damping * velocityHeight) * inverseMass * step;
|
|
velocityOffsetAlong += (stiffness * (targetOffsetAlong - currentOffsetAlong) - damping * velocityOffsetAlong) * inverseMass * step;
|
|
velocityOffsetCross += (stiffness * (targetOffsetCross - currentOffsetCross) - damping * velocityOffsetCross) * inverseMass * step;
|
|
velocityTopLeftRadius += (stiffness * (targetTopLeftRadius - currentTopLeftRadius) - damping * velocityTopLeftRadius) * inverseMass * step;
|
|
velocityTopRightRadius += (stiffness * (targetTopRightRadius - currentTopRightRadius) - damping * velocityTopRightRadius) * inverseMass * step;
|
|
velocityBottomLeftRadius += (stiffness * (targetBottomLeftRadius - currentBottomLeftRadius) - damping * velocityBottomLeftRadius) * inverseMass * step;
|
|
velocityBottomRightRadius += (stiffness * (targetBottomRightRadius - currentBottomRightRadius) - damping * velocityBottomRightRadius) * inverseMass * step;
|
|
|
|
currentWidth += velocityWidth * step;
|
|
currentHeight += velocityHeight * step;
|
|
currentOffsetAlong += velocityOffsetAlong * step;
|
|
currentOffsetCross += velocityOffsetCross * step;
|
|
currentTopLeftRadius += velocityTopLeftRadius * step;
|
|
currentTopRightRadius += velocityTopRightRadius * step;
|
|
currentBottomLeftRadius += velocityBottomLeftRadius * step;
|
|
currentBottomRightRadius += velocityBottomRightRadius * step;
|
|
}
|
|
|
|
if (isSettled())
|
|
settle();
|
|
}
|
|
|
|
onEnabledChanged: {
|
|
if (!enabled) settle();
|
|
}
|
|
|
|
onReducedMotionChanged: {
|
|
if (reducedMotion)
|
|
settle();
|
|
}
|
|
|
|
property FrameAnimation frameAnimation: FrameAnimation {
|
|
running: root.enabled && root.running && !root.reducedMotion
|
|
onTriggered: root.advance(frameTime)
|
|
}
|
|
}
|