Commit ff210ebf by Daniel Dahan

localizing pulse animation to MaterialAnimation

parent c76aef59
......@@ -17,6 +17,8 @@
9663F94E1C7A74EA00AF0965 /* AppLeftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */; };
9663F9501C7A74FC00AF0965 /* AppRightViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */; };
9663F9521C7A751D00AF0965 /* ItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9663F9511C7A751D00AF0965 /* ItemViewController.swift */; };
968F171F1C9273ED008CA3F6 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 968F171E1C9273ED008CA3F6 /* Material.framework */; };
968F17201C9273ED008CA3F6 /* Material.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 968F171E1C9273ED008CA3F6 /* Material.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
96CC08881C7FEBD60034FF84 /* RecipesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */; };
/* End PBXBuildFile section */
......@@ -27,6 +29,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
968F17201C9273ED008CA3F6 /* Material.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
......@@ -46,6 +49,7 @@
9663F94D1C7A74EA00AF0965 /* AppLeftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppLeftViewController.swift; sourceTree = "<group>"; };
9663F94F1C7A74FC00AF0965 /* AppRightViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppRightViewController.swift; sourceTree = "<group>"; };
9663F9511C7A751D00AF0965 /* ItemViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemViewController.swift; sourceTree = "<group>"; };
968F171E1C9273ED008CA3F6 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Material.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/Material-hbpnflxhoouqxebjcyhbbhqyesjd/Build/Products/Debug-iphoneos/Material.framework"; sourceTree = "<absolute>"; };
96CC08871C7FEBD60034FF84 /* RecipesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipesViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -54,6 +58,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
968F171F1C9273ED008CA3F6 /* Material.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -63,6 +68,7 @@
9663F9251C7A744500AF0965 = {
isa = PBXGroup;
children = (
968F171E1C9273ED008CA3F6 /* Material.framework */,
9663F9301C7A744600AF0965 /* App */,
9663F92F1C7A744600AF0965 /* Products */,
);
......
......@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
968F17241C94B5AD008CA3F6 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 968F17231C94B5AD008CA3F6 /* Material.framework */; };
968F17251C94B5AD008CA3F6 /* Material.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 968F17231C94B5AD008CA3F6 /* Material.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
96DB1C5F1C14AA2800825BE6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96DB1C5E1C14AA2800825BE6 /* AppDelegate.swift */; };
96DB1C611C14AA2800825BE6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96DB1C601C14AA2800825BE6 /* ViewController.swift */; };
96DB1C661C14AA2800825BE6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96DB1C651C14AA2800825BE6 /* Assets.xcassets */; };
......@@ -20,6 +22,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
968F17251C94B5AD008CA3F6 /* Material.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
......@@ -27,6 +30,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
968F17231C94B5AD008CA3F6 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Material.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/Material-hbpnflxhoouqxebjcyhbbhqyesjd/Build/Products/Debug-iphoneos/Material.framework"; sourceTree = "<absolute>"; };
96DB1C5B1C14AA2800825BE6 /* MaterialPulseView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MaterialPulseView.app; sourceTree = BUILT_PRODUCTS_DIR; };
96DB1C5E1C14AA2800825BE6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
96DB1C601C14AA2800825BE6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
......@@ -40,6 +44,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
968F17241C94B5AD008CA3F6 /* Material.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -49,6 +54,7 @@
96DB1C521C14AA2800825BE6 = {
isa = PBXGroup;
children = (
968F17231C94B5AD008CA3F6 /* Material.framework */,
96DB1C5D1C14AA2800825BE6 /* MaterialPulseView */,
96DB1C5C1C14AA2800825BE6 /* Products */,
);
......
......@@ -63,16 +63,16 @@ class ViewController: UIViewController {
// Add pulseView to UIViewController.
view.addSubview(pulseView)
// Trigger the pulse animation.
MaterialAnimation.delay(4) {
pulseView.pulse(CGPointMake(30, 30))
}
pulseView.animate(MaterialAnimation.animationGroup([
MaterialAnimation.rotate(rotation: 0.5),
MaterialAnimation.rotateX(rotation: 2),
MaterialAnimation.translateY(200)
], duration: 4))
// // Trigger the pulse animation.
// MaterialAnimation.delay(4) {
// pulseView.pulse(CGPointMake(30, 30))
// }
//
// pulseView.animate(MaterialAnimation.animationGroup([
// MaterialAnimation.rotate(rotation: 0.5),
// MaterialAnimation.rotateX(rotation: 2),
// MaterialAnimation.translateY(200)
// ], duration: 4))
}
}
Pod::Spec.new do |s|
s.name = 'Material'
s.version = '1.36.0'
s.version = '1.36.1'
s.license = 'BSD'
s.summary = 'Express your creativity with Material, an animation and graphics framework for Google\'s Material Design and Apple\'s Flat UI in Swift.'
s.homepage = 'http://cosmicmind.io'
......
......@@ -59,6 +59,7 @@
968F171B1C9266D0008CA3F6 /* NavigationController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96334EF91C8B849A0083986B /* NavigationController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
968F171C1C9266D0008CA3F6 /* NavigationBarView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 968F16F51C9260EC008CA3F6 /* NavigationBarView.swift */; settings = {ATTRIBUTES = (Public, ); }; };
968F171D1C9266D0008CA3F6 /* NavigationBarViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 968F16F71C92612E008CA3F6 /* NavigationBarViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
968F17221C94B10B008CA3F6 /* MaterialPulseAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 968F17211C94B10B008CA3F6 /* MaterialPulseAnimation.swift */; };
96A71E911C6FBC2200C0C4AE /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71E901C6FBC2200C0C4AE /* MenuView.swift */; };
96A71EB81C6FCFA300C0C4AE /* Material+UIImage+Color.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96DBA7351C61198400844821 /* Material+UIImage+Color.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96A71EB91C6FCFA300C0C4AE /* Grid.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9656CD0B1C6BD33700EBCEF1 /* Grid.swift */; settings = {ATTRIBUTES = (Public, ); }; };
......@@ -191,6 +192,7 @@
966F57B71C226D75009185B7 /* TextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
968F16F51C9260EC008CA3F6 /* NavigationBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBarView.swift; sourceTree = "<group>"; };
968F16F71C92612E008CA3F6 /* NavigationBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBarViewController.swift; sourceTree = "<group>"; };
968F17211C94B10B008CA3F6 /* MaterialPulseAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialPulseAnimation.swift; sourceTree = "<group>"; };
96A71E901C6FBC2200C0C4AE /* MenuView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = "<group>"; };
96A71EC61C6FFF0500C0C4AE /* MaterialSwitch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialSwitch.swift; sourceTree = "<group>"; };
96A71EF51C71127100C0C4AE /* SearchBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBarView.swift; sourceTree = "<group>"; };
......@@ -491,6 +493,7 @@
96D88BFF1C1328D800B91418 /* MaterialAnimation.swift */,
96D88C001C1328D800B91418 /* MaterialBasicAnimation.swift */,
96D88C081C1328D800B91418 /* MaterialKeyframeAnimation.swift */,
968F17211C94B10B008CA3F6 /* MaterialPulseAnimation.swift */,
);
name = Animation;
sourceTree = "<group>";
......@@ -797,6 +800,7 @@
96D88C361C1328D800B91418 /* MaterialPulseView.swift in Sources */,
960B23301C383EAA00E96216 /* Material+UIImage+Network.swift in Sources */,
96D88C1E1C1328D800B91418 /* CaptureView.swift in Sources */,
968F17221C94B10B008CA3F6 /* MaterialPulseAnimation.swift in Sources */,
96D88C2D1C1328D800B91418 /* MaterialDepth.swift in Sources */,
968F16F81C92612E008CA3F6 /* NavigationBarViewController.swift in Sources */,
96CC08941C7FEC170034FF84 /* MaterialCollectionViewDataSource.swift in Sources */,
......
......@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.36.0</string>
<string>1.36.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
......
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Material nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
internal extension MaterialAnimation {
/**
Triggers the pulse animation.
- Parameter point: A point to pulse from.
- Returns: A Ooptional CFTimeInternal if the point exists within
the view. The time internal represents the animation time.
*/
internal static func pulseAnimation(layer: CALayer, visualLayer: CALayer, color: UIColor, opacity: CGFloat, point: CGPoint, width: CGFloat, height: CGFloat, duration: NSTimeInterval) {
let r: CGFloat = (width < height ? height : width) / 2
let f: CGFloat = 3
let v: CGFloat = r / f
let d: CGFloat = 2 * f
let pulseLayer: CAShapeLayer = CAShapeLayer()
pulseLayer.hidden = true
pulseLayer.zPosition = 1
pulseLayer.backgroundColor = color.colorWithAlphaComponent(opacity).CGColor
visualLayer.addSublayer(pulseLayer)
MaterialAnimation.animationDisabled {
pulseLayer.bounds = CGRectMake(0, 0, v, v)
pulseLayer.position = point
pulseLayer.cornerRadius = r / d
pulseLayer.hidden = false
}
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: duration), forKey: nil)
MaterialAnimation.delay(duration) {
MaterialAnimation.animateWithDuration(duration, animations: {
pulseLayer.hidden = true
}) {
pulseLayer.removeFromSuperlayer()
}
}
}
internal static func expandAnimation(layer: CALayer, scale: CGFloat, duration: NSTimeInterval) {
layer.addAnimation(MaterialAnimation.scale(scale, duration: duration), forKey: nil)
}
internal static func shrinkAnimation(layer: CALayer, width: CGFloat, duration: NSTimeInterval) {
layer.addAnimation(MaterialAnimation.scale(1, duration: duration), forKey: nil)
}
internal static func pulseDuration(width: CGFloat) -> NSTimeInterval {
var t: CFTimeInterval = CFTimeInterval(1.5 * width / MaterialDevice.width)
if 0.55 < t || 0.25 > t {
t = 0.55
}
t /= 1.3
return t
}
}
\ No newline at end of file
......@@ -41,6 +41,34 @@ public class MaterialPulseView : MaterialView {
public var pulseColor: UIColor?
/**
Triggers the pulse animation.
- Parameter point: A Optional point to pulse from, otherwise pulses
from the center.
*/
public func pulse(var point: CGPoint? = nil) {
if nil == point {
point = CGPointMake(CGFloat(width / 2), CGFloat(height / 2))
}
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if let v: UIColor = pulseColor {
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v, opacity: pulseColorOpacity, point: point!, width: width, height: height, duration: duration)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
MaterialAnimation.delay(duration) { [weak self] in
if let l: CALayer = self?.layer {
if let w: CGFloat = self?.width {
MaterialAnimation.shrinkAnimation(l, width: w, duration: duration)
}
}
}
}
}
/**
A delegation method that is executed when the view has began a
touch event.
- Parameter touches: A set of UITouch objects.
......@@ -48,7 +76,17 @@ public class MaterialPulseView : MaterialView {
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
pulseAnimation(layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer))
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if let v: UIColor = pulseColor {
let point: CGPoint = layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v, opacity: pulseColorOpacity, point: point, width: width, height: height, duration: duration)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
}
}
/**
......@@ -59,7 +97,8 @@ public class MaterialPulseView : MaterialView {
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
shrinkAnimation()
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: duration)
}
/**
......@@ -70,24 +109,8 @@ public class MaterialPulseView : MaterialView {
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
shrinkAnimation()
}
/**
Triggers the pulse animation.
- Parameter point: A Optional point to pulse from, otherwise pulses
from the center.
*/
public func pulse(var point: CGPoint? = nil) {
if nil == point {
point = CGPointMake(CGFloat(width / 2), CGFloat(height / 2))
}
if let v: CFTimeInterval = pulseAnimation(point!) {
MaterialAnimation.delay(v) { [weak self] in
self?.shrinkAnimation()
}
}
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: duration)
}
/**
......@@ -101,70 +124,4 @@ public class MaterialPulseView : MaterialView {
super.prepareView()
pulseColor = MaterialColor.white
}
/**
Triggers the pulse animation.
- Parameter point: A point to pulse from.
- Returns: A Ooptional CFTimeInternal if the point exists within
the view. The time internal represents the animation time.
*/
internal func pulseAnimation(point: CGPoint) -> CFTimeInterval? {
if true == layer.containsPoint(point) {
let r: CGFloat = (width < height ? height : width) / 2
let f: CGFloat = 3
let v: CGFloat = r / f
let d: CGFloat = 2 * f
let s: CGFloat = 1.05
var t: CFTimeInterval = CFTimeInterval(1.5 * width / MaterialDevice.width)
if 0.55 < t || 0.25 > t {
t = 0.55
}
t /= 1.3
if nil != pulseColor && 0 < pulseColorOpacity {
let pulseLayer: CAShapeLayer = CAShapeLayer()
pulseLayer.hidden = true
pulseLayer.zPosition = 1
pulseLayer.backgroundColor = pulseColor?.colorWithAlphaComponent(pulseColorOpacity).CGColor
visualLayer.addSublayer(pulseLayer)
MaterialAnimation.animationDisabled {
pulseLayer.bounds = CGRectMake(0, 0, v, v)
pulseLayer.position = point
pulseLayer.cornerRadius = r / d
pulseLayer.hidden = false
}
pulseLayer.addAnimation(MaterialAnimation.scale(3 * d, duration: t), forKey: nil)
MaterialAnimation.delay(t) { [weak self] in
if nil != self?.pulseColor && 0 < self?.pulseColorOpacity {
MaterialAnimation.animateWithDuration(t, animations: {
pulseLayer.hidden = true
}) {
pulseLayer.removeFromSuperlayer()
}
}
}
}
if pulseScale {
layer.addAnimation(MaterialAnimation.scale(s, duration: t), forKey: nil)
return t
}
}
return nil
}
/// Executes the shrink animation for the pulse effect.
internal func shrinkAnimation() {
if pulseScale {
var t: CFTimeInterval = CFTimeInterval(1.5 * width / MaterialDevice.width)
if 0.55 < t || 0.25 > t {
t = 0.55
}
t /= 1.3
layer.addAnimation(MaterialAnimation.scale(1, duration: t), forKey: nil)
}
}
}
\ No newline at end of file
}
......@@ -803,8 +803,8 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
if nil == tapGesture {
tapGesture = UITapGestureRecognizer(target: self, action: "handleTapGesture:")
tapGesture!.cancelsTouchesInView = false
tapGesture!.delegate = self
tapGesture!.cancelsTouchesInView = false
view.addGestureRecognizer(tapGesture!)
}
}
......@@ -900,14 +900,6 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
userInteractionEnabled = false
container.depth = depth
container.hidden = false
container.layer.shouldRasterize = true
container.layer.rasterizationScale = MaterialDevice.scale
mainViewController.view.layer.shouldRasterize = true
mainViewController.view.layer.rasterizationScale = MaterialDevice.scale
leftViewController?.view.layer.shouldRasterize = true
leftViewController?.view.layer.rasterizationScale = MaterialDevice.scale
rightViewController?.view.layer.shouldRasterize = true
rightViewController?.view.layer.rasterizationScale = MaterialDevice.scale
}
/**
......@@ -918,10 +910,6 @@ public class SideNavigationViewController: UIViewController, UIGestureRecognizer
userInteractionEnabled = true
container.depth = .None
container.hidden = true
container.layer.shouldRasterize = false
mainViewController.view.layer.shouldRasterize = false
leftViewController?.view.layer.shouldRasterize = false
rightViewController?.view.layer.shouldRasterize = false
}
/// Layout subviews.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment