mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-16 07:31:28 +00:00
Support any angle in CPGradient drawInRect:angle:.
This commit is contained in:
+31
-4
@@ -68,16 +68,43 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
|
||||
|
||||
- (void)drawInRect:(CGRect)rect angle:(float)angle
|
||||
{
|
||||
if (angle !== 0)
|
||||
[CPException raise:CPInvalidArgumentException reason:@"angle != 0 not yet implemented"];
|
||||
|
||||
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
CGContextSaveGState(ctx);
|
||||
CGContextClipToRect(ctx, rect);
|
||||
CGContextAddRect(ctx, rect);
|
||||
|
||||
[self drawFromPoint:rect.origin toPoint:CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect)) options:CPGradientDrawsBeforeStartingLocation | CPGradientDrawsAfterEndingLocation];
|
||||
var startPoint,
|
||||
endPoint;
|
||||
|
||||
// Modulo of negative values doesn't work as expected in JS.
|
||||
angle = ((angle % 360.0) + 360.0) % 360.0;
|
||||
|
||||
if (angle < 90.0)
|
||||
startPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
|
||||
else if (angle < 180.0)
|
||||
startPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
|
||||
else if (angle < 270.0)
|
||||
startPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
|
||||
else
|
||||
startPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
|
||||
|
||||
// A line segment comes out of the starting point at the given angle, with the first colour
|
||||
// at the starting point and the last at the end. To do what drawInRect: is supposed to do
|
||||
// we want the opposite corner of the starting corner to just reach the final colour stop.
|
||||
// So when the angle isn't a right angle, the segment has to extend beyond the edge of the
|
||||
// rectangle just far enough. This is hard to describe without a picture but if we place
|
||||
// another line through the opposite corner at -90 degrees, it'll cross through our
|
||||
// gradient segment just where it should end and form a right triangle with the right edge.
|
||||
// of the rect. One leg of this triangle is how far the gradient line should stick out,
|
||||
// and the length of that leg is (in the first quadrant) width * cos(a) + height * sin(a).
|
||||
var radians = PI * angle / 180.0,
|
||||
length = ABS(CGRectGetWidth(rect) * COS(radians)) + ABS(CGRectGetHeight(rect) * SIN(radians));
|
||||
|
||||
endPoint = CGPointMake(startPoint.x + length * COS(radians),
|
||||
startPoint.y + length * SIN(radians));
|
||||
|
||||
[self drawFromPoint:startPoint toPoint:endPoint options:CPGradientDrawsBeforeStartingLocation | CPGradientDrawsAfterEndingLocation];
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
@outlet CustomDrawView gradientView0;
|
||||
@outlet CustomDrawView gradientView1;
|
||||
@outlet CustomDrawView gradientView2;
|
||||
@outlet CustomDrawView gradientView3;
|
||||
}
|
||||
|
||||
- (void)awakeFromCib
|
||||
@@ -29,6 +31,12 @@
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
innerRect;
|
||||
|
||||
var grad0 = aView == gradientView0,
|
||||
grad1 = aView == gradientView1,
|
||||
grad2 = aView == gradientView2,
|
||||
grad3 = aView == gradientView3,
|
||||
isGradient = (grad0 || grad1 || grad2 || grad3);
|
||||
|
||||
if (aView === view1 || aView === view2)
|
||||
{
|
||||
var bounds = [aView bounds],
|
||||
@@ -64,29 +72,49 @@
|
||||
|
||||
innerRect = CPDrawColorTiledRects(bounds, bounds, sides, colors);
|
||||
}
|
||||
else if (aView === gradientView0 || aView === gradientView1)
|
||||
else if (isGradient)
|
||||
{
|
||||
var bounds = [aView bounds],
|
||||
locations,
|
||||
colors;
|
||||
colors,
|
||||
gradient;
|
||||
|
||||
if (aView === gradientView0)
|
||||
if (grad1 || grad3)
|
||||
{
|
||||
locations = [0.0, 0.25, 0.50, 0.75, 1.0];
|
||||
colors = [[CPColor blackColor], [CPColor redColor], [CPColor greenColor], [CPColor blueColor], [CPColor whiteColor]];
|
||||
// Draw a pattern for the gradient to blend with.
|
||||
strokeGrid(bounds);
|
||||
}
|
||||
|
||||
if (grad0)
|
||||
{
|
||||
var locationsGrad0 = [ 0.0, 0.25, 0.50, 0.75, 1.0 ];
|
||||
colors = [CPArray arrayWithObjects:[CPColor blackColor], [CPColor redColor], [CPColor greenColor], [CPColor blueColor], [CPColor whiteColor]];
|
||||
gradient = [[CPGradient alloc] initWithColors:colors atLocations:locationsGrad0 colorSpace:[CPColorSpace sRGBColorSpace]];
|
||||
[gradient drawInRect:bounds angle:0];
|
||||
}
|
||||
else if (grad1)
|
||||
{
|
||||
var mainColor = [CPColor orangeColor],
|
||||
locationsGrad1 = [ 0.0, 0.45, 0.56, 1.0 ];
|
||||
colors = [CPArray arrayWithObjects:[mainColor colorWithAlphaComponent:0.0], mainColor, mainColor, [mainColor colorWithAlphaComponent:0.0]];
|
||||
gradient = [[CPGradient alloc] initWithColors:colors atLocations:locationsGrad1 colorSpace:[CPColorSpace sRGBColorSpace]];
|
||||
[gradient drawInRect:bounds angle:90];
|
||||
}
|
||||
else if (grad2)
|
||||
{
|
||||
colors = [CPArray arrayWithObjects:[CPColor cyanColor], [CPColor magentaColor], [CPColor yellowColor], [CPColor blackColor]];
|
||||
gradient = [[CPGradient alloc] initWithColors:colors];
|
||||
[gradient drawInRect:bounds angle:225];
|
||||
}
|
||||
else
|
||||
{
|
||||
locations = [0.0, 0.35, 0.66, 1.0];
|
||||
var mainColor = [CPColor blackColor];
|
||||
colors = [[mainColor colorWithAlphaComponent:0.0], mainColor, mainColor, [mainColor colorWithAlphaComponent:0.0]];
|
||||
}
|
||||
|
||||
var gradient = [[CPGradient alloc] initWithColors:colors atLocations:locations colorSpace:[CPColorSpace sRGBColorSpace]];
|
||||
[gradient drawInRect:bounds angle:0];
|
||||
colors = [CPArray arrayWithObjects:[[CPColor cyanColor] colorWithAlphaComponent:0.5], [CPColor magentaColor], [CPColor clearColor], [CPColor whiteColor]];
|
||||
gradient = [[CPGradient alloc] initWithColors:colors];
|
||||
[gradient drawInRect:bounds angle:-20];
|
||||
}
|
||||
}
|
||||
|
||||
if (!(aView === gradientView0 || aView === gradientView1))
|
||||
if (!isGradient)
|
||||
{
|
||||
CGContextSetFillColor(context, [CPColor colorWithHexString:@"E1EAFF"]);
|
||||
CGContextFillRect(context, innerRect);
|
||||
@@ -108,3 +136,22 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
function strokeGrid(/* CGRect */ rect)
|
||||
{
|
||||
[CPBezierPath setDefaultLineWidth:1];
|
||||
[[CPColor whiteColor] setFill];
|
||||
[[[CPColor blueColor] colorWithAlphaComponent:0.5] setStroke];
|
||||
|
||||
var mx = CGRectGetMaxX(rect),
|
||||
my = CGRectGetMaxY(rect);
|
||||
|
||||
[CPBezierPath fillRect:rect];
|
||||
|
||||
for (var x = rect.origin.x; x < mx; x += 6)
|
||||
[CPBezierPath strokeLineFromPoint:CGPointMake(x + 0.5, rect.origin.y + 0.5) toPoint:CGPointMake(x + 0.5, my - 0.5)];
|
||||
|
||||
for (var y = rect.origin.y; y < my; y += 6)
|
||||
[CPBezierPath strokeLineFromPoint:CGPointMake(rect.origin.x + 0.5, y + 0.5) toPoint:CGPointMake(mx - 0.5, y + 0.5)];
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user