Created
June 4, 2014 00:22
-
-
Save xrl/3c6fdee0210c262d3fe2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Put your CSS here */ | |
html, body { | |
margin: 20px; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Ember Starter Kit</title> | |
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css"> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> | |
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script> | |
<script src="http://builds.emberjs.com/tags/v1.5.1/ember.js"></script> | |
<script src="http://s3-us-west-1.amazonaws.com/xrl/talks/sdjs-deal-with-it/gif.js"></script> | |
<script src="http://s3-us-west-1.amazonaws.com/xrl/talks/sdjs-deal-with-it/gif.worker.js"></script> | |
</head> | |
<body> | |
<img id="sunglasses" src="https://s3-us-west-1.amazonaws.com/xrl/talks/sdjs-deal-with-it/sunglasses.png" style="display: none"/> | |
<img id="background" src="https://s3-us-west-1.amazonaws.com/xrl/talks/sdjs-deal-with-it/xavier-deuces.jpeg" style="display: none"/> | |
<script type="text/x-handlebars"> | |
<h2>Hello SDJS</h2> | |
{{outlet}} | |
</script> | |
<script type="text/x-handlebars" data-template-name="index"> | |
<p> | |
Steps: {{ view.canvas.steps.length }} | |
<br/> | |
Timing (ms): {{ input value=view.animationSpeed }} | |
<br/> | |
Font: {{ input value=view.font }} | |
<br/> | |
<br/> | |
<button {{action 'startAnimation' target=view}}>Start Animation</button> | |
<button {{action 'cancelAnimation' target=view}}>Cancel Animation</button> | |
<button {{action 'toggleLine' target=view}}>Toggle Line</button> | |
<button {{action 'clearSteps' target=view}}>Clear Steps</button> | |
<button {{action 'generateGIF' target=view}}>GIF IT</button> | |
</p> | |
{{view App.CanvasView}} | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
App = Ember.Application.create(); | |
App.Router.map(function() { | |
}); | |
App.IndexRoute = Ember.Route.extend({ | |
model: function() { | |
return ['brown', 'red', 'yellow', 'blue']; | |
} | |
}); | |
App.IndexView = Ember.View.extend({ | |
canvas: null, | |
actions: { | |
startAnimation: function(){ | |
this.get('canvas').startAnimation(); | |
}, | |
cancelAnimation: function(){ | |
this.get('canvas').cancelAnimation(); | |
}, | |
toggleLine: function(){ | |
this.get('canvas').toggleLine(); | |
}, | |
clearSteps: function(){ | |
this.get('canvas').clearSteps(); | |
}, | |
generateGIF: function(){ | |
this.get('canvas').generateGIF(); | |
} | |
}, | |
setCanvasView: function(){ | |
self = this; | |
this.get('childViews').forEach(function(item){ | |
if(item instanceof App.CanvasView){ | |
self.set('canvas',item); | |
} | |
}); | |
}.on('didInsertElement'), | |
animationSpeedBinding: 'canvas.animationSpeed', | |
fontBinding: 'canvas.font' | |
}); | |
App.CanvasView = Ember.View.extend({ | |
frameTimers: [], | |
tagName: "canvas", | |
attributeBindings: ['style','height','width'], | |
style: 'border: 1px solid black', | |
height: 533, | |
width: 800, | |
canvas: function(){ | |
return this.$()[0]; | |
}.property(), | |
sunglasses: $("img#sunglasses")[0], | |
sunglassesScale: 0.25, | |
background: $("img#background")[0], | |
backgroundScale: 1.0, | |
isMouseDown: false, | |
mouseDown: function(){ | |
this.set('isMouseDown',true); | |
}, | |
mouseUp: function(){ | |
this.set('isMouseDown',false); | |
this.startAnimation(); | |
}, | |
mouseMove: function(event,view){ | |
if(this.get('isMouseDown')){ | |
this.drawBackground(); | |
var point = this.relMouseCoords(event,this.get('canvas')); | |
this.get('steps').pushObject(point); | |
this.drawLine(); | |
this.drawGlasses(point); | |
} | |
}, | |
steps: [], | |
clearSteps: function(){ | |
this.cancelAnimation(); | |
this.set('steps',[]); | |
this.drawBackground(); | |
this.drawLine(); | |
this.drawGlasses(); | |
}, | |
displayText: "Deal With It", | |
font: "40pt Arial", | |
animationSpeed: 30, | |
startAnimation: function(){ | |
this.cancelAnimation(); | |
this.drawBackground(); | |
var steps = this.get('steps'), frame=0; | |
var self = this; | |
for(var i=0; i < steps.length; i=i+1){ | |
var timer = window.setTimeout(function(){ | |
var point = steps[frame]; | |
self.drawBackground(); | |
self.drawLine(); | |
self.drawGlasses(point); | |
frame = frame + 1; | |
}, self.get('animationSpeed')*i); | |
self.get('frameTimers').pushObject(timer); | |
} | |
// Generate text | |
window.setTimeout(function(){ | |
var text = self.get('displayText'); | |
self.setFont(self.get('font')); | |
self.drawText(text,400,50); | |
},self.get('animationSpeed')*steps.length); | |
}, | |
cancelAnimation: function(){ | |
this.get('frameTimers').forEach(window.clearTimeout); | |
this.set('frameTimers',[]); | |
this.drawBackground(); | |
}, | |
generateGIF: function(){ | |
var gif = new GIF({quality: 10}), | |
steps = this.get('steps'), | |
canvas = this.get('canvas'); | |
for(var i=0; i < steps.length; i=i+1){ | |
var point = steps[i]; | |
this.drawBackground(); | |
this.drawLine(); | |
this.drawGlasses(point); | |
gif.addFrame(canvas, {delay: this.get('animationSpeed')}); | |
} | |
var self=this; | |
gif.on('finished',function(blob){ | |
console.log(blob); | |
}); | |
gif.render(); | |
}, | |
showLine: false, | |
toggleLine: function(){ | |
this.toggleProperty('showLine'); | |
this.drawBackground(); | |
this.drawLine(); | |
}, | |
drawLine: function(){ | |
var lineArr = this.get('steps'); | |
if(!this.get('showLine')){ | |
return; | |
} | |
var cvas = this.get('canvas'); | |
var ctx = cvas.getContext("2d"); | |
ctx.beginPath(); | |
for(var i=0; i<lineArr.length; i++){ | |
var point = lineArr[i]; | |
ctx.lineTo(point.x,point.y); | |
} | |
ctx.stroke(); | |
}, | |
drawGlasses: function(point){ | |
var img = this.get('sunglasses'), scale = this.get('sunglassesScale'); | |
var cvas = this.get('canvas'); | |
var ctx = cvas.getContext("2d"); | |
ctx.drawImage(this.get('sunglasses'),point.x,point.y,img.width*scale,img.height*scale); | |
}, | |
drawBackground: function(){ | |
var cvas = this.get('canvas'); | |
var ctx = cvas.getContext("2d"); | |
ctx.drawImage(this.get('background'),0,0); | |
}.on('didInsertElement'), | |
setFont: function(font){ | |
var cvas = this.get('canvas'); | |
var ctx = cvas.getContext('2d'); | |
ctx.font = font; | |
}, | |
drawText: function(){ | |
var cvas = this.get('canvas'); | |
var ctx = cvas.getContext('2d'); | |
ctx.strokeText.apply(ctx,arguments); | |
}, | |
// http://jsbin.com/ApuJOSA/1/edit | |
relMouseCoords: function(e) { | |
var el=e.target, c=el; | |
var scaleX = c.width/c.offsetWidth || 1; | |
var scaleY = c.height/c.offsetHeight || 1; | |
if (!isNaN(e.offsetX)) | |
return { x:e.offsetX*scaleX, y:e.offsetY*scaleY }; | |
var x=e.pageX, y=e.pageY; | |
do { | |
x -= el.offsetLeft; | |
y -= el.offsetTop; | |
el = el.offsetParent; | |
} while (el); | |
return { x: x*scaleX, y: y*scaleY }; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment