Skip to content

Instantly share code, notes, and snippets.

@robertpenner
Forked from johnlindquist/config.js
Created April 12, 2016 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertpenner/2cac3d72e59938da1e0c5444b37f1bbf to your computer and use it in GitHub Desktop.
Save robertpenner/2cac3d72e59938da1e0c5444b37f1bbf to your computer and use it in GitHub Desktop.
SystemJS.config({
transpiler: "typescript",
typescriptOptions: {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
map: {
"rxjs": "https://npmcdn.com/rxjs",
"angular2": "https://npmcdn.com/angular2",
"@ngrx": "https://npmcdn.com/@ngrx",
"typescript": "https://npmcdn.com/typescript/lib/typescript.js"
},
packages: {
"rxjs": { "defaultExtension": "js" },
"angular2": { "defaultExtension": "js" },
"@ngrx/store":{
"main":"dist/index.js"
},
"src": { "defaultExtension": "ts" },
"build": { "defaultExtension": "ts" }
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Angular 2 App</title>
<script src="https://npmcdn.com/angular2/bundles/angular2-polyfills.js"></script>
<script src="https://npmcdn.com/systemjs/dist/system.js"></script>
</head>
<body>
<app></app>
<h2>Click one or more balls then click anywhere in the white box to move them</h2>
<script src="config.js"></script>
<script>System.import('src/main');</script>
</body>
</html>
import {Component, DynamicComponentLoader, ElementRef} from 'angular2/core';
import {Ball} from './components/ball.component';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/withLatestFrom';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/concatAll';
import 'rxjs/add/operator/delay';
import 'rxjs/add/operator/buffer';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/interval';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/share';
import {Subject} from 'rxjs/Subject';
@Component({
selector: 'app',
directives: [Ball],
template: `
<style>
.container{
border: 10px solid black;
width: 200px;
height: 200px;
}
</style>
<div class="container"
(click)="container$.next($event)"
>
<div #container></div>
</div>
`
})
export class App {
container$ = new Subject();
constructor(private _loader:DynamicComponentLoader,
private _ref:ElementRef) {
}
ngOnInit() {
const loadBall$ = Observable.interval(500)
.take(20)
.switchMap(()=> Observable
.fromPromise(this._loader.loadIntoLocation(Ball, this._ref, 'container')),
(_, {instance:ball})=> ball)
.share();
const placeBall$ = loadBall$
.do((ball:Ball) => {
ball.transform = `translateX(85px) translateY(85px)`;
});
const initFormat$ = placeBall$
.delay(10)
.map(ball => {
return {
ball,
transform: `translateX(${Math.random() * 180}px) translateY(${Math.random() * 180}px)`,
duration: `.25s`
}
});
const select$ = loadBall$
.mergeMap((ball:Ball) => ball.select)
const buffer$ = select$.buffer(this.container$)
.concatAll()
.withLatestFrom(this.container$,
({ball, event:ballEvent}, containerEvent)=>(
{ball, ballEvent, containerEvent}
)
);
const bufferFormat$ = buffer$
.map(({ball, ballEvent, containerEvent})=> {
const {clientX:x, clientY:y} = containerEvent;
const {offsetLeft:left, offsetTop:top, offsetWidth:w, offsetHeight:h} = ballEvent.target;
const targetX = x - left - w / 2;
const targetY = y - top - h / 2;
return {
ball,
transform: `translateX(${targetX}px) translateY(${targetY}px)`,
duration: `${Math.random() + .5}s`
}
});
Observable.merge(
initFormat$,
bufferFormat$
)
.subscribe(({ball, transform, duration})=> {
Object.assign(ball, {transform, duration});
})
}
}
import {Component, Input, EventEmitter, Output} from 'angular2/core';
@Component({
selector: 'ball',
template: `
<style>
.ball{
border: 3px solid black;
position: absolute;
border-radius: 50%;
}
</style>
<div
class="ball"
[style.transform]="transform"
[style.transition-duration]="duration"
[style.width]="width"
[style.height]="height"
[style.left]="left"
[style.top]="top"
(click)="onClick($event)"
[style.background-color]="randomColor"
>
</div>
`
})
export class Ball {
randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
@Input() transform;
@Input() duration;
@Input() left = 20 + "px";
@Input() top = 20 + "px";
@Input() width = 20 + "px";
@Input() height = 20 + "px";
@Output() select = new EventEmitter();
onClick($event) {
$event.preventDefault();
$event.stopPropagation();
this.select.emit({ball:this, event:$event})
}
}
import {bootstrap} from 'angular2/platform/browser';
import {App} from './app';
bootstrap(App)
.catch(console.log.bind(console));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment