mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-12 06:17:22 -04:00
- New Spring Motion settings (bounce character, reduce motion) - Reorganize Typography & Motion tab
100 lines
2.8 KiB
QML
100 lines
2.8 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import qs.Common
|
|
|
|
QtObject {
|
|
id: root
|
|
|
|
property bool enabled: true
|
|
property bool reducedMotion: false
|
|
readonly property bool systemReducedMotion: typeof SettingsData !== "undefined" && SettingsData.reduceMotion === true
|
|
readonly property bool effectiveReducedMotion: reducedMotion || systemReducedMotion
|
|
|
|
property real stiffness: 100
|
|
property real damping: 16
|
|
property real mass: 1
|
|
property real positionEpsilon: 0.01
|
|
property real velocityEpsilon: 0.01
|
|
property real maximumFrameTime: 1 / 30
|
|
property real integrationStep: 1 / 240
|
|
|
|
property real value: 0
|
|
property real target: value
|
|
property real velocity: 0
|
|
|
|
property bool _running: false
|
|
readonly property bool running: _running
|
|
readonly property bool settled: !_running
|
|
readonly property real timeConstantMs: effectiveReducedMotion ? 0 : 2000 * mass / Math.max(1, damping)
|
|
property int settleDurationMs: 0
|
|
|
|
function isSettled() {
|
|
return Math.abs(target - value) <= positionEpsilon && Math.abs(velocity) <= velocityEpsilon;
|
|
}
|
|
|
|
function snapTo(v) {
|
|
target = v;
|
|
value = v;
|
|
velocity = 0;
|
|
_running = false;
|
|
}
|
|
|
|
function retarget(v) {
|
|
if (!enabled || effectiveReducedMotion) {
|
|
snapTo(v);
|
|
return;
|
|
}
|
|
if (target === v && !_running)
|
|
return;
|
|
target = v;
|
|
const tau = timeConstantMs;
|
|
const distance = Math.abs(target - value);
|
|
settleDurationMs = tau > 0 ? Math.round(Math.max(tau * 3, tau * Math.log(Math.max(distance, positionEpsilon) / positionEpsilon))) : 0;
|
|
if (!isSettled())
|
|
_running = true;
|
|
}
|
|
|
|
function advance(rawFrameTime) {
|
|
if (!enabled || !_running || effectiveReducedMotion)
|
|
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++) {
|
|
velocity += (stiffness * (target - value) - damping * velocity) * inverseMass * step;
|
|
value += velocity * step;
|
|
}
|
|
|
|
if (isSettled()) {
|
|
value = target;
|
|
velocity = 0;
|
|
_running = false;
|
|
}
|
|
}
|
|
|
|
onEffectiveReducedMotionChanged: {
|
|
if (effectiveReducedMotion)
|
|
snapTo(target);
|
|
}
|
|
|
|
onEnabledChanged: {
|
|
if (!enabled) {
|
|
snapTo(target);
|
|
return;
|
|
}
|
|
retarget(target);
|
|
}
|
|
|
|
property FrameAnimation driver: FrameAnimation {
|
|
running: root.enabled && root._running && !root.effectiveReducedMotion
|
|
onTriggered: root.advance(frameTime)
|
|
}
|
|
}
|