// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 export component SpinnerBase { in property progress; in property indeterminate; in property stroke-width <=> path.stroke-width; in property stroke <=> path.stroke; path := Path { private property radius: min(self.viewbox-width, self.viewbox-height) / 2; private property start-x: self.viewbox-width / 2; private property start-y: self.viewbox-height / 2; private property start : !indeterminate ? 0 : 1 * mod(animation-tick(), 3s) / 3s; // min is a workaround to get filled circle by 1.0 private property progress: !root.indeterminate ? min(0.9999, root.progress) : min(0.9999, max(0.20, 1 * abs(sin(360deg * animation-tick() / 1.5s)))); viewbox-width: 100; viewbox-height: 100; width: 100%; height: 100%; MoveTo { x: start-x - radius * sin(-(path.start - 0.001) * 360deg); y: start-y - radius * cos(-(path.start - 0.001) * 360deg); } // Workaround for femtovg not filling complete circle LineTo { x: start-x - radius * sin(-path.start * 360deg); y: start-y - radius * cos(-path.start * 360deg); } ArcTo { radius-x: path.radius; radius-y: path.radius; x: start-x - path.radius * sin(-(path.start + path.progress) * 360deg); y: start-y - path.radius * cos(-(path.start + path.progress) * 360deg); sweep: path.progress > 0; large-arc: path.progress > 0.5; } } }