SXSimpleClippedImage

type:
extension
author:
mnem
description:
Simple extension of SPImage which allows you to clip a rectangular area within the SPImage.
lastupdate:
2011-07-06
compatible:
v1.2
tag:
clip, image, clipped, mask
homepage:
https://github.com/mnem/SXSimpleClippedImage
download:
https://github.com/mnem/SXSimpleClippedImage/tarball/master

Usage

To use, just create it instead of an SPImage and then set the area of the image you want to clip:

waterfall = [SXSimpleClippedImage imageWithTexture:waterfallTexture];
// Or you can use imageWithContentsOfFile:(NSString *)
 
[waterfall setClipX:0 Y:0 Width:16 Height:16];
 
[container addChild:waterfall];

Each point of the clipping rectangle is a property, so you can easily tween them for different effects. For example, a simple vanish/reveal wipe of the image:

- (void)playTween
{
	SPTween *tween = [SPTween tweenWithTarget:waterfall time:3.0];
 
	[tween animateProperty:@"x" targetValue:waterfall.originalWidth/2];
	[tween animateProperty:@"y" targetValue:waterfall.originalHeight/2];
 
	[tween animateProperty:@"clipX" targetValue:waterfall.originalWidth/2];
	[tween animateProperty:@"clipY" targetValue:waterfall.originalHeight/2];
 
	[tween animateProperty:@"clipWidth" targetValue:0];
	[tween animateProperty:@"clipHeight" targetValue:0];
 
	tween.loop = SPLoopTypeReverse;
 
	[self.stage.juggler addObject:tween];
}

Changelog

  • 2011/07/08 07:37: First public version

Source Code

SXSimpleClippedImage.h
/**
 * Licensed under the MIT license:
 * 
 *     http://www.opensource.org/licenses/mit-license.php
 * 
 * (c) Copyright 2011 David Wagner.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
#import "SPImage.h"
 
/** --------------------------------------------------------------------------
 An SXSimpleClippedImage displays an image, clipped by the clip dimensions
 specified.
 
 Any part of the image within the clipping rectangle's dimensions will be
 visible. The coordinates of the clipping rectangle are relative to the image
 itself, so 0,0 is the top left of the image. The clip rectangle cannot be 
 larger than the original size of the image, or outside the image.
 
 Or, for the more mathematically minded:
 
 - 0 ≤ clipX ≤ originalWidth
 - 0 ≤ clipY ≤ originalHeight
 - 0 ≤ clipWidth ≤ (originalWidth - clipX)
 - 0 ≤ clipHeight ≤ (originalHeight - clipY)
 
 In order to not mess with tweens, you can set values other than those
 specified above, but the class will internally limit the values to those.
 Basically, that means you can use things like elastic tweens and not have
 to worry about them never finishing because they can't set values outside
 that range.
--------------------------------------------------------------------------- */
 
@interface SXSimpleClippedImage : SPImage
{
@private
	float originalWidth;
	float originalHeight;
 
	float clipX;
	float clipY;
	float clipWidth;
	float clipHeight;
 
	SPPoint *topLeft;
	SPPoint *topRight;
	SPPoint *bottomLeft;
	SPPoint *bottomRight;
}
 
/// --------------------
/// @name Initialization
/// --------------------
 
/// Initialize with a texture. _Designated Initializer_.
- (id)initWithTexture:(SPTexture *)texture;
 
/// Initialize  with a texture loaded from a file.
- (id)initWithContentsOfFile:(NSString*)path;
 
/// Set the clip rectangle
- (void)setClipX:(float)x Y:(float)y Width:(float)width Height:(float)height;
 
/// Factory method
+ (SXSimpleClippedImage*)imageWithTexture:(SPTexture *)texture;
 
/// Factory method
+ (SXSimpleClippedImage*)imageWithContentsOfFile:(NSString*)path;
 
/// ----------------
/// @name Properties
/// ----------------
 
/// The original width of the image
@property (nonatomic, readonly) float originalWidth;
 
/// The original height of the image
@property (nonatomic, readonly) float originalHeight;
 
/// The clipping rectangle's X origin
@property (nonatomic, assign) float clipX;
 
/// The clipping rectangle's Y origin
@property (nonatomic, assign) float clipY;
 
/// The width of the clipping rectangle
@property (nonatomic, assign) float clipWidth;
 
// The height of the clipping rectangle
@property (nonatomic, assign) float clipHeight;
 
@end
SXSimpleClippedImage.m
/**
 * Licensed under the MIT license:
 * 
 *     http://www.opensource.org/licenses/mit-license.php
 * 
 * (c) Copyright 2011 David Wagner.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
#import "SXSimpleClippedImage.h"
 
#define CLAMP(n, min, max) ((n) < (min) ? (min) : (n) > (max) ? (max) : (n))
 
@interface SXSimpleClippedImage () 
 
- (void)updateTextureCoordinates;
- (void)storeInitialValues;
 
@end
 
@implementation SXSimpleClippedImage
 
@synthesize	clipX;
@synthesize	clipY;
@synthesize	clipWidth;
@synthesize	clipHeight;
@synthesize	originalWidth;
@synthesize	originalHeight;
 
+ (SXSimpleClippedImage *)imageWithTexture:(SPTexture *)texture 
{
    return [[[SXSimpleClippedImage alloc] initWithTexture:texture] autorelease];
}
 
+ (SXSimpleClippedImage*)imageWithContentsOfFile:(NSString*)path
{
    return [[[SXSimpleClippedImage alloc] initWithContentsOfFile:path] autorelease];
}
 
- (void)storeInitialValues
{
	originalWidth = self.width;
	originalHeight = self.height;
 
	topLeft = [[SPPoint alloc] initWithX: 0.0 y:0.0];
	topRight = [[SPPoint alloc] initWithX: 1.0 y:0.0];
	bottomLeft = [[SPPoint alloc] initWithX: 0.0 y:1.0];
	bottomRight = [[SPPoint alloc] initWithX: 1.0 y:1.0];
 
	clipX = 0;
	clipY = 0;
	clipWidth = originalWidth;
	clipHeight = originalHeight;
}
 
- (id)initWithTexture:(SPTexture *)texture
{
    self = [super initWithTexture:texture];
    if (self) 
	{
		[self storeInitialValues];
    }
 
    return self;
}
 
- (id)initWithContentsOfFile:(NSString*)path
{
    self = [super initWithContentsOfFile:path];
    if (self) 
	{
		[self storeInitialValues];
    }
 
    return self;
}
 
- (void)dealloc 
{
	[topLeft release];
	[topRight release];
	[bottomLeft release];
	[bottomRight release];
 
    [super dealloc];
}
 
- (void)setClipX:(float)x
{
	clipX = x;
	[self updateTextureCoordinates];
}
 
- (void)setClipY:(float)y
{
	clipY = y;
	[self updateTextureCoordinates];
}
 
- (void)setClipWidth:(float)width
{
	clipWidth = width;
	[self updateTextureCoordinates];
}
 
- (void)setClipHeight:(float)height
{
	clipHeight = height;
	[self updateTextureCoordinates];
}
 
- (void)setClipX:(float)x Y:(float)y Width:(float)width Height:(float)height
{
	clipX = x;
	clipY = y;
	clipWidth = width;
	clipHeight = height;
 
	[self updateTextureCoordinates];
}
 
- (void)updateTextureCoordinates
{
	float cX = CLAMP(clipX, 0, originalWidth);
	float cY = CLAMP(clipY, 0, originalHeight);
	float cWidth = CLAMP(clipWidth, 0, originalWidth - cX);
	float cHeight = CLAMP(clipHeight, 0, originalHeight - cY);
 
	// Normalise the values for use as texture coordinates
	cX /= originalWidth;
	cY /= originalHeight;
	cWidth /= originalWidth;
	cHeight /= originalHeight;
 
	// Setup the cached point values
	topLeft.x = cX;
	topLeft.y = cY;
 
	topRight.x = cX + cWidth;
	topRight.y = cY;
 
	bottomLeft.x = cX;
	bottomLeft.y = cY + cHeight;
 
	bottomRight.x = cX + cWidth;
	bottomRight.y = cY + cHeight;
 
	// Copy them to the texture vertices
	[self setTexCoords:topLeft ofVertex:0];
	[self setTexCoords:topRight ofVertex:1];
	[self setTexCoords:bottomLeft ofVertex:2];
	[self setTexCoords:bottomRight ofVertex:3];
 
	// Update our scale so we are the correct width and height
	self.scaleX = cWidth;
	self.scaleY = cHeight;
}
 
@end

Discussion

No comments so far. Feel free to edit this part of the page.

  extensions/sxsimpleclippedimage.txt · Last modified: 2015/09/14 11:14 by 127.0.0.1
 
Powered by DokuWiki