1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the Qt Graphical Effects module. 7** 8** $QT_BEGIN_LICENSE:BSD$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact form at https://www.qt.io/contact-us. 16** 17** BSD License Usage 18** Alternatively, you may use this file under the terms of the BSD license 19** as follows: 20** 21** "Redistribution and use in source and binary forms, with or without 22** modification, are permitted provided that the following conditions are 23** met: 24** * Redistributions of source code must retain the above copyright 25** notice, this list of conditions and the following disclaimer. 26** * Redistributions in binary form must reproduce the above copyright 27** notice, this list of conditions and the following disclaimer in 28** the documentation and/or other materials provided with the 29** distribution. 30** * Neither the name of The Qt Company Ltd nor the names of its 31** contributors may be used to endorse or promote products derived 32** from this software without specific prior written permission. 33** 34** 35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46** 47** $QT_END_LICENSE$ 48** 49****************************************************************************/ 50 51import QtQuick 2.0 52import "private" 53 54/*! 55 \qmltype ConicalGradient 56 \inqmlmodule QtGraphicalEffects 1.0 57 \since QtGraphicalEffects 1.0 58 \inherits QtQuick2::Item 59 \ingroup qtgraphicaleffects-gradient 60 \brief Draws a conical gradient. 61 62 A gradient is defined by two or more colors, which are blended seamlessly. 63 The colors start from the specified angle and end at 360 degrees larger 64 angle value. 65 66 \table 67 \header 68 \li Effect applied 69 \row 70 \li \image ConicalGradient.png 71 \endtable 72 73 \section1 Example 74 75 The following example shows how to apply the effect. 76 \snippet ConicalGradient-example.qml example 77 78*/ 79Item { 80 id: rootItem 81 82 /*! 83 This property allows the effect output pixels to be cached in order to 84 improve the rendering performance. 85 86 Every time the source or effect properties are changed, the pixels in 87 the cache must be updated. Memory consumption is increased, because an 88 extra buffer of memory is required for storing the effect output. 89 90 It is recommended to disable the cache when the source or the effect 91 properties are animated. 92 93 By default, the property is set to \c false. 94 95 */ 96 property bool cached: false 97 98 /*! 99 This property defines the starting angle where the color at the gradient 100 position of 0.0 is rendered. Colors at larger position values are 101 rendered into larger angle values and blended seamlessly. Angle values 102 increase clockwise. 103 104 \table 105 \header 106 \li Output examples with different angle values 107 \li 108 \li 109 \row 110 \li \image ConicalGradient_angle1.png 111 \li \image ConicalGradient_angle2.png 112 \li \image ConicalGradient_angle3.png 113 \row 114 \li \b { angle: 0 } 115 \li \b { angle: 45 } 116 \li \b { angle: 185 } 117 \row 118 \li \l horizontalOffset: 0 119 \li \l horizontalOffset: 0 120 \li \l horizontalOffset: 0 121 \row 122 \li \l verticalOffset: 0 123 \li \l verticalOffset: 0 124 \li \l verticalOffset: 0 125 \endtable 126 127 */ 128 property real angle: 0.0 129 130 /*! 131 \qmlproperty real QtGraphicalEffects1::ConicalGradient::horizontalOffset 132 \qmlproperty real QtGraphicalEffects1::ConicalGradient::verticalOffset 133 134 The horizontalOffset and verticalOffset properties define the offset in 135 pixels for the center point of the gradient compared to the item center. 136 137 The value ranges from -inf to inf. By default, the properties are set to \c 138 0. 139 140 \table 141 \header 142 \li Output examples with different horizontalOffset values 143 \li 144 \li 145 \row 146 \li \image ConicalGradient_horizontalOffset1.png 147 \li \image ConicalGradient_horizontalOffset2.png 148 \li \image ConicalGradient_horizontalOffset3.png 149 \row 150 \li \b { horizontalOffset: -50 } 151 \li \b { horizontalOffset: 0 } 152 \li \b { horizontalOffset: 50 } 153 \row 154 \li \l angle: 0 155 \li \l angle: 0 156 \li \l angle: 0 157 \row 158 \li \l verticalOffset: 0 159 \li \l verticalOffset: 0 160 \li \l verticalOffset: 0 161 \endtable 162 */ 163 property real horizontalOffset: 0.0 164 property real verticalOffset: 0.0 165 166 /*! 167 This property defines the item that is going to be filled with gradient. 168 Source item gets rendered into an intermediate pixel buffer and the 169 alpha values from the result are used to determine the gradient's pixels 170 visibility in the display. The default value for source is undefined and 171 in that case whole effect area is filled with gradient. 172 173 \table 174 \header 175 \li Output examples with different source values 176 \li 177 \row 178 \li \image ConicalGradient_maskSource1.png 179 \li \image ConicalGradient_maskSource2.png 180 \row 181 \li \b { source: undefined } 182 \li \b { source: } 183 \row 184 \li \l angle: 0 185 \li \l angle: 0 186 \row 187 \li \l horizontalOffset: 0 188 \li \l horizontalOffset: 0 189 \row 190 \li \l verticalOffset: 0 191 \li \l verticalOffset: 0 192 \endtable 193 194 195 \note It is not supported to let the effect include itself, for 196 instance by setting source to the effect's parent. 197 */ 198 property variant source 199 200/*! 201 A gradient is defined by two or more colors, which are blended seamlessly. 202 The colors are specified as a set of GradientStop child items, each of which 203 defines a position on the gradient (from 0.0 to 1.0), and a color. 204 The position of each GradientStop is defined by the position property. 205 The color is defined by the color property. 206 207 \table 208 \header 209 \li Output examples with different gradient values 210 \li 211 \li 212 \row 213 \li \image ConicalGradient_gradient1.png 214 \li \image ConicalGradient_gradient2.png 215 \li \image ConicalGradient_gradient3.png 216 \row 217 \li \b {gradient:} \code 218Gradient { 219 GradientStop { position: 0.000 220 color: Qt.rgba(1, 0, 0, 1) } 221 GradientStop { position: 0.167; 222 color: Qt.rgba(1, 1, 0, 1) } 223 GradientStop { position: 0.333; 224 color: Qt.rgba(0, 1, 0, 1) } 225 GradientStop { position: 0.500; 226 color: Qt.rgba(0, 1, 1, 1) } 227 GradientStop { position: 0.667; 228 color: Qt.rgba(0, 0, 1, 1) } 229 GradientStop { position: 0.833; 230 color: Qt.rgba(1, 0, 1, 1) } 231 GradientStop { position: 1.000; 232 color: Qt.rgba(1, 0, 0, 1) } 233} 234 \endcode 235 \li \b {gradient:} \code 236Gradient { 237 GradientStop { position: 0.0 238 color: "#F0F0F0" 239 } 240 GradientStop { position: 0.5 241 color: "#000000" 242 } 243 GradientStop { position: 1.0 244 color: "#F0F0F0" 245 } 246} 247 \endcode 248 \li \b {gradient:} \code 249Gradient { 250 GradientStop { position: 0.0 251 color: "#00000000" 252 } 253 GradientStop { position: 1.0 254 color: "#FF000000" 255 } 256} 257 \endcode 258 \row 259 \li \l angle: 0 260 \li \l angle: 0 261 \li \l angle: 0 262 \row 263 \li \l horizontalOffset: 0 264 \li \l horizontalOffset: 0 265 \li \l horizontalOffset: 0 266 \row 267 \li \l verticalOffset: 0 268 \li \l verticalOffset: 0 269 \li \l verticalOffset: 0 270 \endtable 271 272*/ 273 property Gradient gradient: Gradient { 274 GradientStop { position: 0.0; color: "white" } 275 GradientStop { position: 1.0; color: "black" } 276 } 277 278 SourceProxy { 279 id: maskSourceProxy 280 input: rootItem.source 281 } 282 283 Rectangle { 284 id: gradientRect 285 width: 16 286 height: 256 287 gradient: rootItem.gradient 288 smooth: true 289 } 290 291 ShaderEffectSource { 292 id: cacheItem 293 anchors.fill: parent 294 visible: rootItem.cached 295 smooth: true 296 rotation: shaderItem.rotation 297 sourceItem: shaderItem 298 live: true 299 hideSource: visible 300 } 301 302 ShaderEffect { 303 id: shaderItem 304 property variant gradientSource: ShaderEffectSource { 305 sourceItem: gradientRect 306 smooth: true 307 hideSource: true 308 visible: false 309 } 310 property variant maskSource: maskSourceProxy.output 311 property real startAngle: (rootItem.angle - 90) * Math.PI/180 312 property variant center: Qt.point(0.5 + horizontalOffset / width, 0.5 + verticalOffset / height) 313 314 anchors.fill: parent 315 316 fragmentShader: maskSource == undefined ? noMaskShader : maskShader 317 318 onFragmentShaderChanged: startAngleChanged() 319 320 property string noMaskShader: " 321 varying mediump vec2 qt_TexCoord0; 322 uniform lowp sampler2D gradientSource; 323 uniform highp float qt_Opacity; 324 uniform highp float startAngle; 325 uniform highp vec2 center; 326 327 void main() { 328 const highp float PI = 3.14159265; 329 const highp float PIx2inv = 0.1591549; 330 highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv; 331 gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * qt_Opacity; 332 } 333 " 334 335 property string maskShader: " 336 varying mediump vec2 qt_TexCoord0; 337 uniform lowp sampler2D gradientSource; 338 uniform lowp sampler2D maskSource; 339 uniform highp float qt_Opacity; 340 uniform highp float startAngle; 341 uniform highp vec2 center; 342 343 void main() { 344 lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a; 345 const highp float PI = 3.14159265; 346 const highp float PIx2inv = 0.1591549; 347 highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv; 348 gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * maskAlpha * qt_Opacity; 349 } 350 " 351 } 352} 353