Applying a color gradient on a line using ActionScript 3 / Flash
I am trying to construct a line dynamically, with a start and end gradient. I want to avoid using a GradientBox, as the lines are dynamic. All I want to do is have the line start red, end blue. This code does not work though :(
myLine = new Sh开发者_运维技巧ape();
myLine.graphics.lineStyle(2);
myLine.graphics.lineGradientStyle(GradientType.LINEAR, [0x0000FF, 0xFF0000], [1, 1], [0, 255]);
myLine.graphics.moveTo(itemPoint[i].x, itemPoint[i].y); // Dynamic
myLine.graphics.lineTo(itemPoint[j].x, itemPoint[j].y); // Dynamic
addChild(myLine);
Thanks!
You need to use a matrix to dictate how big the area of the gradient is, and in which direction it should be painted. Try something along these lines:
// Get dimensions (absolute)
var d : Point = itemPoint[j].subtract(itemPoint[i]);
d.x = Math.abs(d.x);
d.y = Math.abs(d.y);
// Create gradient box matrix
var mtx : Matrix = new Matrix;
mtx.createGradientBox(d.x, d.y, Math.atan2(d.y, d.x), itemPoint[j].x, itemPoint[j].y);
myLine.graphics.lineStyle(2);
myLine.graphics.lineGradientStyle(GradientType.LINEAR, [0x0000ff, 0xff0000], [1,1], [0, 0xff], mtx);
myLine.graphics.moveTo(itemPoint[i].x, itemPoint[i].y);
myLine.graphics.lineTo(itemPoint[j].x, itemPoint[j].y);
Basically this will create a gradient box that is the same width and height as the bounding rectangle of the line you will be creating. It should also rotate the gradient according to the angle between your two points, to make sure that the gradient runs from one point to the other.
Richard's answer looks very plausible, unfortunately it didn't work for me (the gradient didn't rotate with the line).
So I have searched the length and breadth of the land looking for a function drawing line from point A to B with gradient. One person did help me, and so now I can share with you dear sir knights the answer to all questions:
// I eliminated most of the variables in order to optimize it
// mtx is matrix, gfx is Graphics
public function LineGradient( pt1 : FlxPoint, pt2 : FlxPoint ) : void
{
var ox : Number = Math.min( pt1.x, pt2.x);
var oy : Number = Math.min( pt1.y, pt2.y);
mtx.createGradientBox(Math.abs( pt2.x - pt1.x ), Math.abs( pt2.y - pt1.y ),
Math.atan2( pt2.y - pt1.y, pt2.x - pt1.x ),
ox, oy );
gfx.lineStyle( thickness, color, alpha);
gfx.lineGradientStyle(GradientType.LINEAR, [0xff0000, 0x0000ff], [0, 1], [0, 255], mtx);
gfx.moveTo( pt1.x, pt1.y );
gfx.lineTo( pt2.x, pt2.y );
}
Now the Flash won't die.
Mostly a fork from richardolsson's answer but this is a more generic form for people who want to achieve this in general and fixes the bug if your line goes straight down (ie start and end point have the same x). The function will stand-alone.
//import flash.geom.Point;
//import flash.display.Shape;
var sp:Point=new Point(10,10); //some starting point - can be anywhere
var ep:Point=new Point(250,250);// some end point - can be anywhere
var myLine:Shape=gradientLine(sp,ep,0xFF0000,0x0000FF,0x00FF00,0xFFFF00); // put in as many colours as you want, the function will evenly space them out
addChild(myLine);
function gradientLine(startPoint:Point,endPoint:Point,...colours):Shape
/*GRADIENT LINE - returns a line from startPoint to endPoint with even gradient of colours*/
{
/*Create matrix - gradient box*/
var d:Point=startPoint.subtract(endPoint);
d.x=Math.abs(d.x);
d.y=Math.abs(d.y);
if(d.x==0)d.x=1; /*corrects for lines going straight down*/
var matrix:Matrix=new Matrix;
matrix.createGradientBox(d.x,d.y,Math.atan2(d.y,d.x),startPoint.x,startPoint.y);
/*Create/populate array of ratios and alphas*/
var l:int=colours.length;
var alphas:Array=new Array();
var ratios:Array=new Array();
for(var i:int=0;i<l;i++)
{
alphas.push(1);
ratios.push((0xFF/l)*i+1); /*evenly spreads ratios of chosen colours*/
}
/*Create shape*/
var s:Shape=new Shape;
s.graphics.lineStyle(2);
s.graphics.lineGradientStyle(GradientType.LINEAR,colours,alphas,ratios,matrix);
s.graphics.moveTo(startPoint.x,startPoint.y);
s.graphics.lineTo(endPoint.x,endPoint.y);
return(s);
}
精彩评论