Skip to content

Instantly share code, notes, and snippets.

@xrl
Created June 4, 2014 00:22
Show Gist options
  • Save xrl/3c6fdee0210c262d3fe2 to your computer and use it in GitHub Desktop.
Save xrl/3c6fdee0210c262d3fe2 to your computer and use it in GitHub Desktop.
/* Put your CSS here */
html, body {
margin: 20px;
}
<!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>
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