blob: de9e20b8f3732e06393d0545a6973c3e20b123bf [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.9
import QtQuick.Shapes 1.0
Rectangle {
id: root
width: 1024
height: 768
property color col: "lightsteelblue"
gradient: Gradient {
GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
}
Row {
anchors.top: parent.top
anchors.centerIn: parent
spacing: 20
Column {
spacing: 20
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
id: triangle
anchors.fill: parent
ShapePath {
strokeWidth: 4
strokeColor: "red"
fillGradient: LinearGradient {
x1: 0; y1: 0
x2: 200; y2: 100
GradientStop { position: 0; color: "blue" }
GradientStop { position: 0.2; color: "green" }
GradientStop { position: 0.4; color: "red" }
GradientStop { position: 0.6; color: "yellow" }
GradientStop { position: 1; color: "cyan" }
}
fillColor: "blue" // ignored with the gradient set
strokeStyle: ShapePath.DashLine
dashPattern: [ 1, 4 ]
PathLine { x: 200; y: 100 }
PathLine { x: 0; y: 100 }
PathLine { x: 0; y: 0 }
}
transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 }
SequentialAnimation on angle {
NumberAnimation { from: 0; to: 75; duration: 2000 }
NumberAnimation { from: 75; to: -75; duration: 4000 }
NumberAnimation { from: -75; to: 0; duration: 2000 }
loops: Animation.Infinite
}
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
anchors.fill: parent
ShapePath {
id: someCurve
property color sc: "gray"
strokeColor: sc
property color fc: "yellow"
fillColor: fc
startX: 20; startY: 10
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 180; y: 10; controlX: 200; controlY: 80 }
PathLine { x: 20; y: 10 }
// Dynamic changes via property bindings etc. all work but can
// be computationally expense with the generic backend for properties
// that need retriangulating on every change. Should be cheap with NVPR.
NumberAnimation on strokeWidth {
from: 1; to: 20; duration: 10000
}
}
}
// Changing colors for a solid stroke or fill is simple and
// (relatively) cheap. However, changing to/from transparent
// stroke/fill color and stroke width 0 are special as these
// change the scenegraph node tree (with the generic backend).
Timer {
interval: 2000
running: true
repeat: true
onTriggered: someCurve.fillColor = (someCurve.fillColor === someCurve.fc ? "transparent" : someCurve.fc)
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: someCurve.strokeColor = (someCurve.strokeColor === someCurve.sc ? "transparent" : someCurve.sc)
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 300
height: 100
Shape {
id: linesAndMoves
anchors.fill: parent
ShapePath {
strokeColor: "black"
startX: 0; startY: 50
PathLine { relativeX: 100; y: 50 }
PathMove { relativeX: 100; y: 50 }
PathLine { relativeX: 100; y: 50 }
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 120
Shape {
anchors.fill: parent
ShapePath {
id: joinTest
strokeColor: "black"
strokeWidth: 16
fillColor: "transparent"
capStyle: ShapePath.RoundCap
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
}
Timer {
interval: 1000
repeat: true
running: true
property variant styles: [ ShapePath.BevelJoin, ShapePath.MiterJoin, ShapePath.RoundJoin ]
onTriggered: {
for (var i = 0; i < styles.length; ++i)
if (styles[i] === joinTest.joinStyle) {
joinTest.joinStyle = styles[(i + 1) % styles.length];
break;
}
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
anchors.fill: parent
ShapePath {
id: star
strokeColor: "blue"
fillColor: "lightGray"
strokeWidth: 2
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
}
Timer {
interval: 1000
onTriggered: star.fillRule = (star.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill)
repeat: true
running: true
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
anchors.fill: parent
ShapePath {
strokeWidth: 4
strokeColor: "black"
fillColor: "transparent"
startX: 20; startY: 10
PathCubic {
id: cb
x: 180; y: 10
control1X: -10; control1Y: 90; control2Y: 90
NumberAnimation on control2X { from: 400; to: 0; duration: 5000; loops: Animation.Infinite }
}
}
}
}
}
Column {
spacing: 20
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
anchors.fill: parent
ShapePath {
fillColor: "transparent"
strokeColor: "red"
strokeWidth: 4
startX: 10; startY: 40
PathArc {
x: 10; y: 60
radiusX: 40; radiusY: 40
useLargeArc: true
}
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 200
Rectangle {
anchors.centerIn: parent
// have a size smaller than 150x150
width: 100
height: 100
// and enable clipping. Normally this goes via scissoring, unless
// some transform triggers the stencil-based path. Ensure this via rotation.
clip: true
NumberAnimation on rotation {
from: 0; to: 360; duration: 5000; loops: Animation.Infinite
}
Shape {
width: 150
height: 150
ShapePath {
fillColor: "blue"
strokeColor: "red"
strokeWidth: 4
startX: 10; startY: 10
PathLine { x: 140; y: 140 }
PathLine { x: 10; y: 140 }
PathLine { x: 10; y: 10 }
}
}
}
}
// stencil clip test #2, something more complicated:
Rectangle {
border.color: "purple"
color: "transparent"
width: 150
height: 150
Rectangle {
anchors.centerIn: parent
width: 60
height: 60
clip: true
NumberAnimation on rotation {
from: 0; to: 360; duration: 5000; loops: Animation.Infinite
}
Shape {
width: 100
height: 100
ShapePath {
id: clippedStar
strokeColor: "blue"
fillColor: "lightGray"
strokeWidth: 2
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
}
Timer {
interval: 1000
onTriggered: clippedStar.fillRule = (clippedStar.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill)
repeat: true
running: true
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 100
height: 100
Shape {
anchors.fill: parent
ShapePath {
strokeColor: "red"
PathLine { x: 100; y: 100 }
}
ShapePath {
strokeColor: "blue"
startX: 100; startY: 0
PathLine { x: 0; y: 100 }
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
anchors.fill: parent
ShapePath {
strokeWidth: -1
strokeColor: "red"
fillGradient: RadialGradient {
centerX: 100; centerY: 50
focalX: centerX; focalY: centerY
centerRadius: 50
spread: RadialGradient.ReflectSpread
GradientStop { position: 0; color: "blue" }
GradientStop { position: 0.2; color: "green" }
GradientStop { position: 0.4; color: "red" }
GradientStop { position: 0.6; color: "yellow" }
GradientStop { position: 1; color: "cyan" }
}
PathLine { x: 0; y: 100 }
PathLine { x: 200; y: 100 }
PathLine { x: 200; y: 0 }
PathLine { x: 0; y: 0 }
}
}
}
Rectangle {
border.color: "purple"
color: "transparent"
width: 200
height: 100
Shape {
anchors.fill: parent
ShapePath {
strokeWidth: -1
strokeColor: "red"
fillGradient: ConicalGradient {
centerX: 100; centerY: 50
angle: 90
GradientStop { position: 0; color: "blue" }
GradientStop { position: 0.2; color: "green" }
GradientStop { position: 0.4; color: "red" }
GradientStop { position: 0.6; color: "yellow" }
GradientStop { position: 1; color: "cyan" }
}
PathLine { x: 0; y: 100 }
PathLine { x: 200; y: 100 }
PathLine { x: 200; y: 0 }
PathLine { x: 0; y: 0 }
}
}
}
}
}
Rectangle {
id: stackTestRect
SequentialAnimation on opacity {
NumberAnimation { from: 0; to: 1; duration: 5000 }
PauseAnimation { duration: 2000 }
NumberAnimation { from: 1; to: 0; duration: 5000 }
PauseAnimation { duration: 2000 }
loops: Animation.Infinite
id: opAnim
}
color: "blue"
anchors.margins: 10
anchors.fill: parent
}
MouseArea {
anchors.fill: parent
onClicked: stackTestRect.visible = !stackTestRect.visible
}
}