swift - iOS Animate Mask Over UIImage -
i using swift 1.2 , goal animate image mask on static uiimage. have implemented swift version of masking image found in objective-c.
func maskimage(image: uiimage, mask: uiimage) -> uiimage! { let maskref = mask.cgimage; let mask = cgimagemaskcreate( cgimagegetwidth(maskref), cgimagegetheight(maskref), cgimagegetbitspercomponent(maskref), cgimagegetbitsperpixel(maskref), cgimagegetbytesperrow(maskref), cgimagegetdataprovider(maskref), nil, false); let masked = cgimagecreatewithmask(image.cgimage, mask); let retimage = uiimage(cgimage: masked); return retimage; } it works great! however, putting in motion challenge.
is there way either iteratively apply mask different horizontal offset or better way approach problem entirely - perhaps calayer implementation?
thanks help!
edit: based on posted answer, added this:
let image = uiimage(named: "clouds"); let imageview = uiimageview(image: image); let layer = calayer(); layer.contents = uiimage(named: "alpha-mask")?.cgimage; layer.bounds = cgrectmake(0, 0, image.size.width, image.size.height); // other folks learning, did not work //let animation = cabasicanimation(keypath: "bounds.origin.x"); // work let animation = cabasicanimation(keypath: "position.x"); animation.duration = 2; animation.delegate = self; animation.fillmode = kcafillmodeforwards; animation.repeatcount = 0; animation.fromvalue = 0.0; animation.tovalue = image.size.width; animation.timingfunction = camediatimingfunction(name: kcamediatimingfunctionlinear); animation.removedoncompletion = false; layer.addanimation(animation, forkey: "transform"); imageview.layer.mask = layer; self.addsubview(imageview); i able see alpha mask properly, animation not work. ideas?
edit: modified code above , works! needed make keypath position.x. see above
you indeed want use calayer - or rather, cashapelayer.
you can create cashapelayer , install as mask on layer.
you can create caanimation animates changes shape layer's path, or can animate changes layer's strokestart and/or strokeend properties.
if animate path, 1 rule want follow make sure starting , ending path have same number , type of control points. otherwise animation "undefined", , results can strange.
i have development blog post outlines how it's done:
http://wareto.com/using-core-animation-groups-to-create-animation-sequences-2
it's using caanimationgroups, includes working example of animating changes cashapelayer that's used mask of image view's layer.
below gif of mask animation creates - "clock wipe" shows , hides image view:

unfortunately it's written in objective-c, core animation calls identical in swift. let me know if have problems figuring out how adapt it.
the meat of animation code method:
- (ibaction)domaskanimation:(id)sender; { waretologolarge.hidden = false;//show image view //create shape layer use mask waretologolarge image view cashapelayer *masklayer = [cashapelayer layer]; cgfloat maskheight = waretologolarge.layer.bounds.size.height; cgfloat maskwidth = waretologolarge.layer.bounds.size.width; cgpoint centerpoint; centerpoint = cgpointmake( maskwidth/2, maskheight/2); //make radius of our arc large enough reach corners of image view. cgfloat radius = sqrtf(maskwidth * maskwidth + maskheight * maskheight)/2; //don't fill path, stroke in black. masklayer.fillcolor = [[uicolor clearcolor] cgcolor]; masklayer.strokecolor = [[uicolor blackcolor] cgcolor]; masklayer.linewidth = radius; //make line thick enough fill circle we're drawing cgmutablepathref arcpath = cgpathcreatemutable(); //move starting point of arc there no initial line connecting arc cgpathmovetopoint(arcpath, nil, centerpoint.x, centerpoint.y-radius/2); //create arc @ 1/2 our circle radius, line thickess of full circle radius cgpathaddarc(arcpath, nil, centerpoint.x, centerpoint.y, radius/2, 3*m_pi/2, -m_pi/2, yes); masklayer.path = arcpath; //start empty mask path (draw 0% of arc) masklayer.strokeend = 0.0; cfrelease(arcpath); //install mask layer out image view's layer. waretologolarge.layer.mask = masklayer; //set our mask layer's frame parent layer's bounds. waretologolarge.layer.mask.frame = waretologolarge.layer.bounds; //create animation increases stroke length 1, reverses zero. cabasicanimation *swipe = [cabasicanimation animationwithkeypath:@"strokeend"]; swipe.duration = 2; swipe.delegate = self; [swipe setvalue: theblock forkey: kanimationcompletionblock]; swipe.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctionlinear]; swipe.fillmode = kcafillmodeforwards; swipe.removedoncompletion = no; swipe.autoreverses = yes; swipe.tovalue = [nsnumber numberwithfloat: 1.0]; [masklayer addanimation: swipe forkey: @"strokeend"]; } i have blog entry is in swift shows how create , animate pie chart using cashapelayer. project animates shape, not mask, real difference whether install shape layer regular content layer or mask on layer backing layer of image view.
you can check out project @ link:
Comments
Post a Comment