This gist shows how to create a GIF screencast using only free OS X tools: QuickTime, ffmpeg, and gifsicle.
To capture the video (filesize: 19MB), using the free "QuickTime Player" application:
| javascript:(function(){var p=document.createElement("p");p.innerHTML="<strong>Loading…</strong>";p.id="loadingp";p.style.padding="20px";p.style.background="#fff";p.style.left="20px";p.style.top=0;p.style.position="fixed";p.style.zIndex="9999999";p.style.opacity=".85";document.body.appendChild(p);document.body.appendChild(document.createElement("script")).src="https://cdn.rawgit.com/ttscoff/6109434/raw/Bullseye.js?x="+(Math.random());})(); |
| #import <objc/runtime.h> | |
| static void SwizzleClassMethod(Class klass, SEL original, SEL new) | |
| { | |
| Method origMethod = class_getClassMethod(klass, original); | |
| Method newMethod = class_getClassMethod(klass, new); | |
| if (class_addMethod(klass, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { | |
| class_replaceMethod(klass, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); |
| // | |
| // UIImage+vImageScaling.h | |
| // UIImage+vImageScaling | |
| // | |
| // Created by Matt Donnelly on 03/07/2013. | |
| // Copyright (c) 2013 Matt Donnelly. All rights reserved. | |
| // | |
| #import <UIKit/UIKit.h> |
| // Support routines for automatically reporting user timing for common analytics platforms | |
| // Currently supports Google Analytics, Boomerang and SOASTA mPulse | |
| // In the case of boomerang, you will need to map the event names you want reported | |
| // to timer names (for mPulse these need to be custom0, custom1, etc) using a global variable: | |
| // rumMapping = {'aft': 'custom0'}; | |
| (function() { | |
| var wtt = function(n, t, b) { | |
| t = Math.round(t); | |
| if (t >= 0 && t < 3600000) { | |
| // Google Analytics |
| static __inline__ CGRect CGRectFromCGSize( CGSize size ) { | |
| return CGRectMake( 0, 0, size.width, size.height ); | |
| }; | |
| static __inline__ CGRect CGRectMakeWithCenterAndSize( CGPoint center, CGSize size ) { | |
| return CGRectMake( center.x - size.width * 0.5, center.y - size.height * 0.5, size.width, size.height ); | |
| }; | |
| static __inline__ CGRect CGRectMakeWithOriginAndSize( CGPoint origin, CGSize size ) { | |
| return CGRectMake( origin.x, origin.y, size.width, size.height ); |
| /* | |
| Before: | |
| CGRect frame = myView.frame; | |
| frame.origin.x = newX; | |
| myView.frame = frame; | |
| After: | |
| myView.x = newX; | |
| #import <UIKit/UIKit.h> | |
| #import <ImageIO/ImageIO.h> | |
| #import <MobileCoreServices/MobileCoreServices.h> | |
| static UIImage *frameImage(CGSize size, CGFloat radians) { | |
| UIGraphicsBeginImageContextWithOptions(size, YES, 1); { | |
| [[UIColor whiteColor] setFill]; | |
| UIRectFill(CGRectInfinite); | |
| CGContextRef gc = UIGraphicsGetCurrentContext(); | |
| CGContextTranslateCTM(gc, size.width / 2, size.height / 2); |
| $sprites: sprite-map("sprites/*.png"); | |
| $sprites-retina: sprite-map("sprites-retina/*.png"); | |
| @mixin sprite-background($name) { | |
| background-image: sprite-url($sprites); | |
| background-position: sprite-position($sprites, $name); | |
| background-repeat: no-repeat; | |
| display: block; | |
| height: image-height(sprite-file($sprites, $name)); | |
| width: image-width(sprite-file($sprites, $name)); |
| @mixin background-image-retina($file, $type, $width, $height) { | |
| background-image: url($file + '.' + $type); | |
| @media (-webkit-min-device-pixel-ratio: 2), (-moz-min-device-pixel-ratio: 2) { | |
| & { | |
| background-image: url($file + '@2x.' + $type); | |
| -webkit-background-size: $width $height; | |
| } | |
| } | |
| } |