ios - Cutting an image to a CALayers content during an animation -
i have created subclass of calayer draw slice of pie chart custom color (color
), startangle (actualstartangle
), endangle (actualendangle
) , image (image
)[this image should in middle of slice] animating not possible normal cashapelayer. layer drawn this:
- (void)drawincontext:(cgcontextref)ctx{ cgcontextbeginpath(ctx); cgcontextmovetopoint(ctx, self.center.x, self.center.y); cgcontextaddarc(ctx, self.center.x, self.center.y, self.radius, self.actualendangle, self.actualstartangle, yes); cgcontextclosepath(ctx); cgcontextsetfillcolorwithcolor(ctx, self.color); cgcontextsetlinewidth(ctx, 0); cgcontextdrawpath(ctx, kcgpathfillstroke); if (self.image) { cgcontextdrawimage(ctx, [self getframeforimglayerwithstartangle:self.actualstartangle andendangle:self.actualendangle], self.image); } }
these individual slices animated by:
[catransaction begin]; cabasicanimation *coloranimation = [cabasicanimation animationwithkeypath:@"color"]; coloranimation.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctioneaseineaseout]; coloranimation.duration = duration; coloranimation.fromvalue = (id)self.color; coloranimation.tovalue = (id)colortu.cgcolor; cabasicanimation *startangleanimation = [cabasicanimation animationwithkeypath:@"actualstartangle"]; startangleanimation.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctioneaseineaseout]; startangleanimation.duration = duration; startangleanimation.fromvalue = [self valueforkey:@"actualstartangle"]; startangleanimation.tovalue = [[nsnumber alloc] initwithfloat:newstartangle]; cabasicanimation *endangleanimation = [cabasicanimation animationwithkeypath:@"actualendangle"]; endangleanimation.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctioneaseineaseout]; endangleanimation.duration = duration; endangleanimation.fromvalue = [self valueforkey:@"actualendangle"]; endangleanimation.tovalue = [[nsnumber alloc] initwithfloat:newendangle]; if (completionblock) { [catransaction setcompletionblock:completionblock]; } if (colortu && colortu.cgcolor != self.color) { [self addanimation:coloranimation forkey:@"color"]; } if (newstartangle != self.actualstartangle) { [self addanimation:startangleanimation forkey:@"actualstartangle"]; } if (newendangle != self.actualendangle) { [self addanimation:endangleanimation forkey:@"actualendangle"]; } [catransaction commit];
the problem have image take space individual layer takes (resp. shape in it). solved in general method:
- (bool)imagefitsintoslicewithstartangle:(float)sa andendangle:(float)ea{ bool fits = yes; cgrect recttouse = [self getframeforimglayerwithstartangle:sa andendangle:ea]; uibezierpath *path = [uibezierpath bezierpath]; [path movetopoint:self.center]; [path addarcwithcenter:self.center radius:self.deg startangle:sa endangle:ea clockwise:yes]; (int w = 0; w <= 1; w++) { if (fits) { (int h = 0; h <= 1; h++) { if (![path containspoint:cgpointmake(recttouse.origin.x + recttouse.size.width * w, recttouse.origin.y + recttouse.size.height * h)]) { fits = no; break; } } } } return fits; }
the problem may fit in end , not @ beginning of animation, have cut image big slice when happens.
i have tried following:
- set mask slice instead of drawing directly -> firstly bad coding , have found energy inefficient, created error (
expecting model layer not copy
) me.
any ideas on how solve issue? (not tried problem in general, don't think should tried above)
thanks
don't know if it'll help, here drawing code pie chart part :
- (void)drawchartwithframe:(cgrect)frame startangle:(cgfloat)startangle endangle:(cgfloat)endangle fillcolor:(uicolor *)fillcolor strokecolor:(uicolor *)strokecolor { //// oval drawing cgrect ovalrect = cgrectmake(cgrectgetminx(frame),cgrectgetminy(frame), cgrectgetwidth(frame), cgrectgetheight(frame)); uibezierpath* ovalpath = uibezierpath.bezierpath; [ovalpath addarcwithcenter: cgpointmake(cgrectgetmidx(ovalrect), cgrectgetmidy(ovalrect)) radius: cgrectgetwidth(ovalrect) / 2 startangle: -(startangle - 25) * m_pi/180 endangle: -(endangle - 93) * m_pi/180 clockwise: yes]; [ovalpath addlinetopoint: cgpointmake(cgrectgetmidx(ovalrect), cgrectgetmidy(ovalrect))]; [ovalpath closepath];ansform ovaltransform = cgaffinetransformmaketranslation(cgrectgetmidx(ovalrect), cgrectgetmidy(ovalrect)); ovaltransform = cgaffinetransformscale(ovaltransform, 1, cgrectgetheight(ovalrect) / cgrectgetwidth(ovalrect)); [ovalpath applytransform: ovaltransform]; [fillcolor setfill]; [ovalpath fill]; [strokecolor setstroke]; ovalpath.linewidth = 1; [ovalpath stroke]; }
it's lighter animate real image.
Comments
Post a Comment