animation - Layer masking based on positioning iOS -
i've never worked animations on ios , hoping pointed in right direction. have far animated bunch of pill shaped objects in fashion similar have below, have yet implement correct masking based on y positioning of shape.
the pill shapes uiviews. i'm looking way backgrounds change based on positioning; background not move, pills.
edit:
based on rob's answer below, tying animation device's movement so:
- (void)setanimationtodevicemotion { motionmanager = [[cmmotionmanager alloc] init]; motionmanager.devicemotionupdateinterval = 0.1f; nsoperationqueue *motionqueue = [[nsoperationqueue alloc] init]; [motionmanager startdevicemotionupdatesusingreferenceframe:cmattitudereferenceframexarbitraryzvertical toqueue:motionqueue withhandler:^(cmdevicemotion *motion, nserror *error) { if (!error) { double pitch = motion.attitude.pitch; nslog(@"%f", pitch); [self addmasktoview:self.imageview withadjustment:pitch]; } }]; }
assuming 8 pill shapes reveal single image underneath,
- create
uibezierpath
8 pill shapes - create
cashapelayer
layer usesuibezierpath
(or more accurately,cgpath
) - apply
cashapelayer
mask
layer
uiimageview
if want animate on time, replace mask
(e.g. in response accelerometer event, cadisplaylink
or nstimer
, or uipangesture
), or update path
of cashapelayer
have applied mask uiimageview
's layer.
thus, might have like:
- (void)addmasktoview:(uiview *)view withadjustment:(cgfloat)adjustment { cashapelayer *mask = [cashapelayer layer]; mask.path = [[self pillspathwithadjustment:adjustment forview:view] cgpath]; self.imageview.layer.mask = mask; } - (uibezierpath *)pillspathwithadjustment:(cgfloat)adjustment forview:(uiview *)view { uibezierpath *path = [uibezierpath bezierpath]; (nsinteger = 0; < knumberofpills; i++) [self addpillpathnumber:i forview:view topath:path adjustment:adjustment]; return path; } - (void)addpillpathnumber:(nsinteger)index forview:(uiview *)view topath:(uibezierpath *)path adjustment:(cgfloat)adjustment { cgfloat const pillspacing = 5.0f; cgfloat const pillwidth = view.bounds.size.width / knumberofpills - pillspacing; cgfloat const pillheight = view.bounds.size.height * 0.4; cgfloat const cornerrounding = 10.0f; cgpoint point = cgpointmake(index * (pillwidth + pillspacing) + pillspacing / 2.0, sinf((float) index * m_pi / knumberofpills + adjustment * m_pi * 2.0) * 100.0); // top point.x += cornerrounding; [path movetopoint:point]; point.x += pillwidth - cornerrounding * 2.0; [path addlinetopoint:point]; // top right corner [path addarcwithcenter:cgpointmake(point.x, point.y + cornerrounding) radius:cornerrounding startangle:3 * m_pi_2 endangle:2.0 * m_pi clockwise:yes]; point.x += cornerrounding; point.y += cornerrounding; // right point.y += pillheight - cornerrounding * 2.0; [path addlinetopoint:point]; // lower right corner [path addarcwithcenter:cgpointmake(point.x - cornerrounding, point.y) radius:cornerrounding startangle:0 endangle:m_pi_2 clockwise:yes]; // bottom point.y += cornerrounding; point.x -= cornerrounding; point.x -= pillwidth - cornerrounding * 2.0; [path addlinetopoint:point]; // lower left corner [path addarcwithcenter:cgpointmake(point.x, point.y - cornerrounding) radius:cornerrounding startangle:m_pi_2 endangle:m_pi clockwise:yes]; // left point.y -= cornerrounding; point.x -= cornerrounding; point.y -= pillheight - cornerrounding * 2.0; [path addlinetopoint:point]; // upper left corner [path addarcwithcenter:cgpointmake(point.x + cornerrounding, point.y) radius:cornerrounding startangle:m_pi endangle:3.0 * m_pi_2 clockwise:yes]; [path closepath]; }
by way of illustration, how i'd animate using cadisplaylink
:
- (void)startdisplaylink { self.displaylink = [cadisplaylink displaylinkwithtarget:self selector:@selector(handledisplaylink:)]; self.starttime = cacurrentmediatime(); [self.displaylink addtorunloop:[nsrunloop currentrunloop] formode:nsdefaultrunloopmode]; } - (void)stopdisplaylink { [self.displaylink invalidate]; self.displaylink = nil; } - (void)handledisplaylink:(cadisplaylink *)displaylink { cgfloat seconds; cgfloat fractionsofsecond = modff(cacurrentmediatime() - self.starttime, &seconds); [self addmasktoview:self.imageview withadjustment:fractionsofsecond]; }
Comments
Post a Comment