////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package mx.graphics
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.core.mx_internal;
use namespace mx_internal;
/**
* The LinearGradient class lets you specify the fill of a graphical element,
* where a gradient specifies a gradual color transition in the fill color.
* You add a series of GradientEntry objects
* to the LinearGradient object's entries
Array
* to define the colors that make up the gradient fill.
*
*
In MXML, you define a LinearGradient by adding a series * of GradientEntry objects, as the following example shows: *
* <mx:fill> * <mx:LinearGradient> * <mx:entries> * <mx:GradientEntry color="0xC5C551" ratio="0.00" alpha="0.5"/> * <mx:GradientEntry color="0xFEFE24" ratio="0.33" alpha="0.5"/> * <mx:GradientEntry color="0xECEC21" ratio="0.66" alpha="0.5"/> * </mx:entries> * </mx:LinearGradient> * </mx:fill> ** * *
You can also define a LinearGradient as a fill for any graphic element * in ActionScript, as the following example shows: *
* * <?xml version="1.0"?> * <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> * <mx:Script> * import flash.display.Graphics; * import flash.geom.Rectangle; * import mx.graphics.GradientEntry; * import mx.graphics.LinearGradient; * * private function init():void * { * var w:Number = 200; * var h:Number = 200; * * var s:Sprite = new Sprite(); * // Add the new Sprite to the display list. * rawChildren.addChild(s); * * var g:Graphics = s.graphics; * g.lineStyle(1, 0x33CCFF, 1.0); * * var fill:LinearGradient = new LinearGradient(); * * var g1:GradientEntry = new GradientEntry(0xFFCC66, 0.00, 0.5); * var g2:GradientEntry = new GradientEntry(0x000000, 0.33, 0.5); * var g3:GradientEntry = new GradientEntry(0x99FF33, 0.66, 0.5); * * fill.entries = [ g1, g2, g3 ]; * fill.angle = 240; * * // Draw a box and fill it with the LinearGradient. * g.moveTo(0, 0); * fill.begin(g, new Rectangle(0, 0, w, h)); * g.lineTo(w, 0); * g.lineTo(w, h); * g.lineTo(0, h); * g.lineTo(0, 0); * fill.end(g); * } * </mx:Script> * </mx:Application> ** * * @mxml * *
The <mx:LinearGradient>
tag
* inherits all the tag attributes of its superclass,
* and adds the following tag attributes:
* <mx:LinearGradient * Properties * angle="0" * /> ** * @see mx.graphics.GradientEntry * @see mx.graphics.RadialGradient * @see mx.graphics.IFill * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class LinearGradient extends GradientBase implements IFill { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function LinearGradient() { super(); } /** * @private */ private static var commonMatrix:Matrix = new Matrix(); //-------------------------------------------------------------------------- // // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // matrix //---------------------------------- /** * @private */ override public function set matrix(value:Matrix):void { scaleX = NaN; super.matrix = value; } //---------------------------------- // scaleX //---------------------------------- private var _scaleX:Number; [Bindable("propertyChange")] [Inspectable(category="General")] /** * The horizontal scale of the gradient transform, which defines the width of the (unrotated) gradient * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get scaleX():Number { return compoundTransform ? compoundTransform.scaleX : _scaleX; } /** * @private */ public function set scaleX(value:Number):void { if (value != scaleX) { var oldValue:Number = scaleX; if (compoundTransform) { // If we have a compoundTransform, only non-NaN values are allowed if (!isNaN(value)) compoundTransform.scaleX = value; } else { _scaleX = value; } dispatchGradientChangedEvent("scaleX", oldValue, value); } } //-------------------------------------------------------------------------- // // // Methods // //-------------------------------------------------------------------------- /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function begin(target:Graphics, targetBounds:Rectangle, targetOrigin:Point):void { commonMatrix.identity(); if (!compoundTransform) { var tx:Number = x; var ty:Number = y; var length:Number = scaleX; if (isNaN(length)) { // Figure out the two sides if (rotation % 90 != 0) { // Normalize angles with absolute value > 360 var normalizedAngle:Number = rotation % 360; // Normalize negative angles if (normalizedAngle < 0) normalizedAngle += 360; // Angles wrap at 180 normalizedAngle %= 180; // Angles > 90 get mirrored if (normalizedAngle > 90) normalizedAngle = 180 - normalizedAngle; var side:Number = targetBounds.width; // Get the hypotenuse of the largest triangle that can fit in the bounds var hypotenuse:Number = Math.sqrt(targetBounds.width * targetBounds.width + targetBounds.height * targetBounds.height); // Get the angle of that largest triangle var hypotenuseAngle:Number = Math.acos(targetBounds.width / hypotenuse) * 180 / Math.PI; // If the angle is larger than the hypotenuse angle, then use the height // as the adjacent side of the triangle if (normalizedAngle > hypotenuseAngle) { normalizedAngle = 90 - normalizedAngle; side = targetBounds.height; } // Solve for the hypotenuse given an adjacent side and an angle. length = side / Math.cos(normalizedAngle / 180 * Math.PI); } else { // Use either width or height based on the rotation length = (rotation % 180) == 0 ? targetBounds.width : targetBounds.height; } } // If only x or y is defined, force the other to be set to 0 if (!isNaN(tx) && isNaN(ty)) ty = 0; else if (isNaN(tx) && !isNaN(ty)) tx = 0; // If x and y are specified, then move the gradient so that the // top left corner is at 0,0 if (!isNaN(tx) && !isNaN(ty)) commonMatrix.translate(GRADIENT_DIMENSION / 2, GRADIENT_DIMENSION / 2); // 1638.4 / 2 // Force the length to a absolute minimum of 2. Values of 0, 1, or -1 have undesired behavior if (length >= 0 && length < 2) length = 2; else if (length < 0 && length > -2) length = -2; // Scale the gradient in the x direction. The natural size is 1638.4px. No need // to scale the y direction because it is infinite commonMatrix.scale (length / GRADIENT_DIMENSION, 1 / GRADIENT_DIMENSION); commonMatrix.rotate (!isNaN(_angle) ? _angle : rotationInRadians); if (isNaN(tx)) tx = targetBounds.left + targetBounds.width / 2; else tx += targetOrigin.x; if (isNaN(ty)) ty = targetBounds.top + targetBounds.height / 2; else ty += targetOrigin.y; commonMatrix.translate(tx, ty); } else { commonMatrix.translate(GRADIENT_DIMENSION / 2, GRADIENT_DIMENSION / 2); commonMatrix.scale(1 / GRADIENT_DIMENSION, 1 / GRADIENT_DIMENSION); commonMatrix.concat(compoundTransform.matrix); commonMatrix.translate(targetOrigin.x, targetOrigin.y); } target.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, commonMatrix, spreadMethod, interpolationMethod); } /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function end(target:Graphics):void { target.endFill(); } } }