/
aserger
/
cutcalcut
Обзор
Документация
Войти
/
aserger
/
cutcalcut
Код
Запросы
2
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
Calcul/GradientButton.qml
218 строк
8 KB
SergeyParkhachevIP-415
create base buttons and structure + js for gradient
09 дек 2025, 19:17
09 дек 2025, 19:17
e50a450
Код
Авторство
О чём код?
// GradientButton.qml с MultiEffect import QtQuick import QtQuick.Controls import QtQuick.Effects // Импортируем Effects для MultiEffect import "RadialGradient.js" as GradientJS Button { id: root // Свойства для настройки property color baseColor: "#6c757d" property string gradientStyle: "metallic" property var customGradient: null // Настройки тени/свечения через MultiEffect property bool enableShadow: true property color shadowColor: "#40000000" property real shadowOpacity: 0.3 property real shadowBlur: 0.5 property real shadowHorizontalOffset: 2 property real shadowVerticalOffset: 2 // Внутреннее свойство для градиента property var currentGradient: null // Инициализация градиента Component.onCompleted: { updateGradient(); } // Обновление градиента при изменении свойств onBaseColorChanged: updateGradient() onGradientStyleChanged: updateGradient() onCustomGradientChanged: updateGradient() // Функция обновления градиента function updateGradient() { if (customGradient && typeof customGradient === 'object') { currentGradient = GradientJS.create(customGradient); } else { var preset = GradientJS.presets[gradientStyle]; if (preset) { currentGradient = preset(baseColor); } else { currentGradient = GradientJS.presets.metallic(baseColor); } } if (canvas) canvas.requestPaint(); } // Основной контент кнопки background: Item { id: buttonBackground // Canvas для отрисовки градиента Canvas { id: canvas anchors.fill: parent onPaint: { var ctx = getContext("2d"); ctx.clearRect(0, 0, width, height); if (!root.currentGradient) return; // Создаем градиент через JS var gradient = root.currentGradient.createCanvasCommands( ctx, width, height ); // Рисуем закругленный прямоугольник var radius = 8; var strokeWidth = 2; // Путь для закругленного прямоугольника ctx.beginPath(); ctx.moveTo(radius, 0); ctx.lineTo(width - radius, 0); ctx.arcTo(width, 0, width, radius, radius); ctx.lineTo(width, height - radius); ctx.arcTo(width, height, width - radius, height, radius); ctx.lineTo(radius, height); ctx.arcTo(0, height, 0, height - radius, radius); ctx.lineTo(0, radius); ctx.arcTo(0, 0, radius, 0, radius); ctx.closePath(); // Заполняем градиентом ctx.fillStyle = gradient; ctx.fill(); // Рисуем обводку var borderColor = GradientJS.darken(root.baseColor, 1.3); ctx.strokeStyle = borderColor; ctx.lineWidth = strokeWidth; ctx.stroke(); // Добавляем блик сверху if (root.gradientStyle === "glass" || root.gradientStyle === "metallic") { var highlight = ctx.createLinearGradient(0, 0, 0, height * 0.3); highlight.addColorStop(0, "rgba(255, 255, 255, 0.3)"); highlight.addColorStop(1, "transparent"); ctx.beginPath(); ctx.moveTo(radius, 0); ctx.lineTo(width - radius, 0); ctx.arcTo(width, 0, width, radius, radius); ctx.lineTo(width, height * 0.3); ctx.lineTo(0, height * 0.3); ctx.lineTo(0, radius); ctx.arcTo(0, 0, radius, 0, radius); ctx.closePath(); ctx.fillStyle = highlight; ctx.fill(); } } } // MultiEffect для тени и свечения MultiEffect { id: buttonEffect anchors.fill: canvas source: canvas // Настройки тени shadowEnabled: root.enableShadow shadowColor: root.shadowColor shadowOpacity: root.shadowOpacity shadowBlur: root.shadowBlur shadowHorizontalOffset: root.shadowHorizontalOffset shadowVerticalOffset: root.shadowVerticalOffset // Дополнительные эффекты (опционально) brightness: root.down ? -0.1 : 0.0 contrast: 1.0 saturation: 1.0 // Для неонового эффекта добавляем свечение colorization: root.gradientStyle === "neon" ? 0.3 : 0.0 colorizationColor: root.baseColor // Анимация эффектов Behavior on brightness { NumberAnimation { duration: 100 } } Behavior on shadowBlur { NumberAnimation { duration: 150 } } Behavior on shadowOpacity { NumberAnimation { duration: 150 } } } // Эффект нажатия states: [ State { name: "PRESSED" when: root.down PropertyChanges { target: buttonBackground; scale: 0.95 } // Усиливаем тень при нажатии PropertyChanges { target: buttonEffect; shadowBlur: root.shadowBlur * 1.5 shadowOpacity: root.shadowOpacity * 1.2 shadowVerticalOffset: root.shadowVerticalOffset * 0.7 } }, State { name: "HOVERED" when: root.hovered && !root.down // Легкое свечение при наведении PropertyChanges { target: buttonEffect; shadowBlur: root.shadowBlur * 1.2 shadowOpacity: root.shadowOpacity * 1.1 } } ] transitions: Transition { NumberAnimation { properties: "scale, shadowBlur, shadowOpacity, shadowVerticalOffset"; duration: 150; easing.type: Easing.InOutQuad } } } contentItem: Text { text: root.text color: "white" font: root.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter // MultiEffect для текста вместо старого DropShadow layer.enabled: true layer.effect: MultiEffect { shadowEnabled: true shadowColor: "#60000000" shadowOpacity: 0.6 shadowBlur: 0.3 shadowHorizontalOffset: 1 shadowVerticalOffset: 1 shadowScale: 1.0 // Для лучшей читаемости на светлом фоне brightness: 0.0 contrast: 1.2 } } }