refactor(playground): make playground great again
This commit is contained in:

committed by
Victor Berchet

parent
69f87ca075
commit
3d9d839c6c
@ -6,7 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
declare module 'B64' {
|
||||
export function fromByteArray(arr: Uint8Array): string;
|
||||
export function toByteArray(str: string): Uint8Array;
|
||||
}
|
||||
declare namespace base64js {
|
||||
function fromByteArray(arr: Uint8Array): string;
|
||||
function toByteArray(str: string): Uint8Array;
|
||||
}
|
||||
|
||||
export = base64js;
|
||||
|
@ -1,16 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
declare class Bitmap {
|
||||
constructor(width: number, height: number);
|
||||
|
||||
subsample(n: number): void;
|
||||
dataURL(): string;
|
||||
|
||||
pixel: [any];
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
Copyright 2011 Andrey Zholos
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
function Bitmap(width, height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pixel = new Array(width);
|
||||
for (var x = 0; x < width; x++) {
|
||||
this.pixel[x] = new Array(height);
|
||||
for (var y = 0; y < height; y++) this.pixel[x][y] = [0, 0, 0, 0];
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap.prototype.subsample =
|
||||
function(n) {
|
||||
var width = ~~(this.width / n);
|
||||
var height = ~~(this.height / n);
|
||||
var pixel = new Array(width);
|
||||
for (var x = 0; x < width; x++) {
|
||||
pixel[x] = new Array(height);
|
||||
for (var y = 0; y < height; y++) {
|
||||
var q = [0, 0, 0, 0];
|
||||
for (var i = 0; i < n; i++)
|
||||
for (var j = 0; j < n; j++) {
|
||||
var r = this.pixel[x * n + i][y * n + j];
|
||||
q[0] += r[3] * r[0];
|
||||
q[1] += r[3] * r[1];
|
||||
q[2] += r[3] * r[2];
|
||||
q[3] += r[3];
|
||||
}
|
||||
if (q[3]) {
|
||||
q[0] /= q[3];
|
||||
q[1] /= q[3];
|
||||
q[2] /= q[3];
|
||||
q[3] /= n * n;
|
||||
}
|
||||
pixel[x][y] = q;
|
||||
}
|
||||
}
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pixel = pixel;
|
||||
}
|
||||
|
||||
Bitmap.prototype.dataURL = function() {
|
||||
function sample(v) { return ~~(Math.max(0, Math.min(1, v)) * 255); }
|
||||
|
||||
function gamma(v) { return sample(Math.pow(v, .45455)); }
|
||||
|
||||
function row(pixel, width, y) {
|
||||
var data = '\0';
|
||||
for (var x = 0; x < width; x++) {
|
||||
var r = pixel[x][y];
|
||||
data += String.fromCharCode(gamma(r[0]), gamma(r[1]), gamma(r[2]), sample(r[3]));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function rows(pixel, width, height) {
|
||||
var data = '';
|
||||
for (var y = 0; y < height; y++) data += row(pixel, width, y);
|
||||
return data;
|
||||
}
|
||||
|
||||
function adler(data) {
|
||||
var s1 = 1, s2 = 0;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
s1 = (s1 + data.charCodeAt(i)) % 65521;
|
||||
s2 = (s2 + s1) % 65521;
|
||||
}
|
||||
return s2 << 16 | s1;
|
||||
}
|
||||
|
||||
function hton(i) { return String.fromCharCode(i >>> 24, i >>> 16 & 255, i >>> 8 & 255, i & 255); }
|
||||
|
||||
function deflate(data) {
|
||||
var len = data.length;
|
||||
return '\170\1\1' + String.fromCharCode(len & 255, len >>> 8, ~len & 255, (~len >>> 8) & 255) +
|
||||
data + hton(adler(data));
|
||||
}
|
||||
|
||||
function crc32(data) {
|
||||
var c = ~0;
|
||||
for (var i = 0; i < data.length; i++)
|
||||
for (var b = data.charCodeAt(i) | 0x100; b != 1; b >>>= 1)
|
||||
c = (c >>> 1) ^ ((c ^ b) & 1 ? 0xedb88320 : 0);
|
||||
return ~c;
|
||||
}
|
||||
|
||||
function chunk(type, data) { return hton(data.length) + type + data + hton(crc32(type + data)); }
|
||||
|
||||
function base64(data) {
|
||||
enc = '';
|
||||
for (var i = 5, n = data.length * 8 + 5; i < n; i += 6)
|
||||
enc += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
[(data.charCodeAt(~~(i / 8) - 1) << 8 | data.charCodeAt(~~(i / 8))) >> 7 - i % 8 & 63];
|
||||
for (; enc.length % 4; enc += '=')
|
||||
;
|
||||
return enc;
|
||||
}
|
||||
|
||||
var png = '\211PNG\r\n\32\n' +
|
||||
chunk('IHDR', hton(this.width) + hton(this.height) + '\10\6\0\0\0') +
|
||||
chunk('IDAT', deflate(rows(this.pixel, this.width, this.height))) + chunk('IEND', '');
|
||||
|
||||
return 'data:image/png;base64,' + base64(png);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
var _FileReader = FileReader;
|
||||
export {_FileReader as FileReader};
|
||||
|
||||
export class Uint8ArrayWrapper {
|
||||
static create(buffer: ArrayBuffer) { return new Uint8Array(buffer); }
|
||||
}
|
@ -8,20 +8,19 @@
|
||||
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
import {FileReader, Uint8ArrayWrapper} from './file_api';
|
||||
import {BitmapService} from './services/bitmap';
|
||||
|
||||
|
||||
@Component({selector: 'image-demo', viewProviders: [BitmapService], templateUrl: 'image_demo.html'})
|
||||
export class ImageDemo {
|
||||
images: any[] /** TODO #9100 */ = [];
|
||||
images: {src: string, buffer: ArrayBuffer, filtering: boolean}[] = [];
|
||||
fileInput: String;
|
||||
|
||||
constructor(private _bitmapService: BitmapService) {}
|
||||
|
||||
uploadFiles(files: any /** TODO #9100 */) {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var reader = new FileReader();
|
||||
uploadFiles(files: FileList) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', this.handleReaderLoad(reader));
|
||||
reader.readAsArrayBuffer(files[i]);
|
||||
}
|
||||
@ -29,9 +28,9 @@ export class ImageDemo {
|
||||
|
||||
handleReaderLoad(reader: FileReader): EventListener {
|
||||
return (e) => {
|
||||
var buffer = reader.result;
|
||||
const buffer = reader.result as ArrayBuffer;
|
||||
this.images.push({
|
||||
src: this._bitmapService.arrayBufferToDataUri(Uint8ArrayWrapper.create(reader.result)),
|
||||
src: this._bitmapService.arrayBufferToDataUri(new Uint8Array(buffer)),
|
||||
buffer: buffer,
|
||||
filtering: false
|
||||
});
|
||||
@ -39,16 +38,16 @@ export class ImageDemo {
|
||||
}
|
||||
|
||||
applyFilters() {
|
||||
for (var i = 0; i < this.images.length; i++) {
|
||||
for (let i = 0; i < this.images.length; i++) {
|
||||
this.images[i].filtering = true;
|
||||
|
||||
setTimeout(this._filter(i), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private _filter(i: number): (...args: any[]) => void {
|
||||
private _filter(i: number): () => void {
|
||||
return () => {
|
||||
var imageData = this._bitmapService.convertToImageData(this.images[i].buffer);
|
||||
let imageData = this._bitmapService.convertToImageData(this.images[i].buffer);
|
||||
imageData = this._bitmapService.applySepia(imageData);
|
||||
this.images[i].src = this._bitmapService.toDataUri(imageData);
|
||||
this.images[i].filtering = false;
|
||||
|
@ -22,6 +22,7 @@ System.config({
|
||||
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-webworker': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-webworker-dynamic': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
|
||||
|
@ -6,31 +6,25 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/// <reference path="../bitmap.d.ts" /> /// <reference path="../b64.d.ts" />
|
||||
import {Injectable} from '@angular/core';
|
||||
declare var base64js: any /** TODO #9100 */;
|
||||
|
||||
// Temporary fix for Typescript issue #4220 (https://github.com/Microsoft/TypeScript/issues/4220)
|
||||
// var _ImageData: (width: number, height: number) => void = <any>postMessage;
|
||||
var _ImageData: {prototype: ImageData, new (width: number, height: number): ImageData;} = ImageData;
|
||||
import * as base64js from '../b64';
|
||||
|
||||
// This class is based on the Bitmap examples at:
|
||||
// http://www.i-programmer.info/projects/36-web/6234-reading-a-bmp-file-in-javascript.html
|
||||
// and
|
||||
// http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
|
||||
// and http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
|
||||
@Injectable()
|
||||
export class BitmapService {
|
||||
convertToImageData(buffer: ArrayBuffer): ImageData {
|
||||
var bmp = this._getBMP(buffer);
|
||||
const bmp = this._getBMP(buffer);
|
||||
return this._BMPToImageData(bmp);
|
||||
}
|
||||
|
||||
applySepia(imageData: ImageData): ImageData {
|
||||
var buffer = imageData.data;
|
||||
for (var i = 0; i < buffer.length; i += 4) {
|
||||
var r = buffer[i];
|
||||
var g = buffer[i + 1];
|
||||
var b = buffer[i + 2];
|
||||
const buffer = imageData.data;
|
||||
for (let i = 0; i < buffer.length; i += 4) {
|
||||
const r = buffer[i];
|
||||
const g = buffer[i + 1];
|
||||
const b = buffer[i + 2];
|
||||
buffer[i] = (r * .393) + (g * .769) + (b * .189);
|
||||
buffer[i + 1] = (r * .349) + (g * .686) + (b * .168);
|
||||
buffer[i + 2] = (r * .272) + (g * .534) + (b * .131);
|
||||
@ -39,7 +33,7 @@ export class BitmapService {
|
||||
}
|
||||
|
||||
toDataUri(imageData: ImageData): string {
|
||||
var header = this._createBMPHeader(imageData);
|
||||
const header = this._createBMPHeader(imageData);
|
||||
imageData = this._imageDataToBMP(imageData);
|
||||
return 'data:image/bmp;base64,' + btoa(header) + base64js.fromByteArray(imageData.data);
|
||||
}
|
||||
@ -51,14 +45,14 @@ export class BitmapService {
|
||||
|
||||
// returns a UInt8Array in BMP order (starting from the bottom)
|
||||
private _imageDataToBMP(imageData: ImageData): ImageData {
|
||||
var width = imageData.width;
|
||||
var height = imageData.height;
|
||||
const width = imageData.width;
|
||||
const height = imageData.height;
|
||||
|
||||
var data = imageData.data;
|
||||
for (var y = 0; y < height / 2; ++y) {
|
||||
var topIndex = y * width * 4;
|
||||
var bottomIndex = (height - y) * width * 4;
|
||||
for (var i = 0; i < width * 4; i++) {
|
||||
const data = imageData.data;
|
||||
for (let y = 0; y < height / 2; ++y) {
|
||||
let topIndex = y * width * 4;
|
||||
let bottomIndex = (height - y) * width * 4;
|
||||
for (let i = 0; i < width * 4; i++) {
|
||||
this._swap(data, topIndex, bottomIndex);
|
||||
topIndex++;
|
||||
bottomIndex++;
|
||||
@ -69,7 +63,7 @@ export class BitmapService {
|
||||
}
|
||||
|
||||
private _swap(data: Uint8Array|Uint8ClampedArray|number[], index1: number, index2: number) {
|
||||
var temp = data[index1];
|
||||
const temp = data[index1];
|
||||
data[index1] = data[index2];
|
||||
data[index2] = temp;
|
||||
}
|
||||
@ -77,9 +71,9 @@ export class BitmapService {
|
||||
// Based on example from
|
||||
// http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
|
||||
private _createBMPHeader(imageData: ImageData): string {
|
||||
var numFileBytes = this._getLittleEndianHex(imageData.width * imageData.height);
|
||||
var w = this._getLittleEndianHex(imageData.width);
|
||||
var h = this._getLittleEndianHex(imageData.height);
|
||||
const numFileBytes = this._getLittleEndianHex(imageData.width * imageData.height);
|
||||
const w = this._getLittleEndianHex(imageData.width);
|
||||
const h = this._getLittleEndianHex(imageData.height);
|
||||
return 'BM' + // Signature
|
||||
numFileBytes + // size of the file (bytes)*
|
||||
'\x00\x00' + // reserved
|
||||
@ -99,18 +93,18 @@ export class BitmapService {
|
||||
}
|
||||
|
||||
private _BMPToImageData(bmp: BitmapFile): ImageData {
|
||||
var width = bmp.infoHeader.biWidth;
|
||||
var height = bmp.infoHeader.biHeight;
|
||||
var imageData = new _ImageData(width, height);
|
||||
const width = bmp.infoHeader.biWidth;
|
||||
const height = bmp.infoHeader.biHeight;
|
||||
const imageData = new ImageData(width, height);
|
||||
|
||||
var data = imageData.data;
|
||||
var bmpData = bmp.pixels;
|
||||
var stride = bmp.stride;
|
||||
const data = imageData.data;
|
||||
const bmpData = bmp.pixels;
|
||||
const stride = bmp.stride;
|
||||
|
||||
for (var y = 0; y < height; ++y) {
|
||||
for (var x = 0; x < width; ++x) {
|
||||
var index1 = (x + width * (height - y)) * 4;
|
||||
var index2 = x * 3 + stride * y;
|
||||
for (let y = 0; y < height; ++y) {
|
||||
for (let x = 0; x < width; ++x) {
|
||||
const index1 = (x + width * (height - y)) * 4;
|
||||
const index2 = x * 3 + stride * y;
|
||||
data[index1] = bmpData[index2 + 2];
|
||||
data[index1 + 1] = bmpData[index2 + 1];
|
||||
data[index1 + 2] = bmpData[index2];
|
||||
@ -121,8 +115,8 @@ export class BitmapService {
|
||||
}
|
||||
|
||||
private _getBMP(buffer: ArrayBuffer): BitmapFile {
|
||||
var datav = new DataView(buffer);
|
||||
var bitmap: BitmapFile = {
|
||||
const datav = new DataView(buffer);
|
||||
const bitmap: BitmapFile = {
|
||||
fileHeader: {
|
||||
bfType: datav.getUint16(0, true),
|
||||
bfSize: datav.getUint32(2, true),
|
||||
@ -146,7 +140,7 @@ export class BitmapService {
|
||||
stride: null,
|
||||
pixels: null
|
||||
};
|
||||
var start = bitmap.fileHeader.bfOffBits;
|
||||
const start = bitmap.fileHeader.bfOffBits;
|
||||
bitmap.stride =
|
||||
Math.floor((bitmap.infoHeader.biBitCount * bitmap.infoHeader.biWidth + 31) / 32) * 4;
|
||||
bitmap.pixels = new Uint8Array(datav.buffer, start);
|
||||
@ -156,9 +150,9 @@ export class BitmapService {
|
||||
// Based on example from
|
||||
// http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
|
||||
private _getLittleEndianHex(value: number): string {
|
||||
var result: any[] /** TODO #9100 */ = [];
|
||||
const result: string[] = [];
|
||||
|
||||
for (var bytes = 4; bytes > 0; bytes--) {
|
||||
for (let bytes = 4; bytes > 0; bytes--) {
|
||||
result.push(String.fromCharCode(value & 255));
|
||||
value >>= 8;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export class InputCmp {
|
||||
inputVal = '';
|
||||
textareaVal = '';
|
||||
|
||||
inputChanged(e: any /** TODO #9100 */) { this.inputVal = e.target.value; }
|
||||
inputChanged(e: Event) { this.inputVal = (e.target as HTMLInputElement).value; }
|
||||
|
||||
textAreaChanged(e: any /** TODO #9100 */) { this.textareaVal = e.target.value; }
|
||||
textAreaChanged(e: Event) { this.textareaVal = (e.target as HTMLTextAreaElement).value; }
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ export class RedDec {
|
||||
constructor(el: ElementRef, renderer: Renderer) {
|
||||
renderer.setElementStyle(el.nativeElement, 'color', 'red');
|
||||
}
|
||||
// constructor(renderer: Renderer) {}
|
||||
}
|
||||
|
||||
// Angular 2.0 supports 2 basic types of directives:
|
||||
@ -54,7 +53,5 @@ export class HelloCmp {
|
||||
|
||||
changeGreeting(): void { this.greeting = 'howdy'; }
|
||||
|
||||
onKeyDown(event: any /** TODO #9100 */): void {
|
||||
this.lastKey = String.fromCharCode(event.keyCode);
|
||||
}
|
||||
onKeyDown(event: KeyboardEvent): void { this.lastKey = String.fromCharCode(event.keyCode); }
|
||||
}
|
||||
|
@ -18,15 +18,15 @@ export class TodoApp {
|
||||
hideCompleted: boolean = false;
|
||||
isComplete: boolean = false;
|
||||
|
||||
constructor(public todoStore: Store, public factory: TodoFactory) {}
|
||||
constructor(public todoStore: Store<Todo>, public factory: TodoFactory) {}
|
||||
|
||||
enterTodo(): void {
|
||||
this.addTodo(this.inputValue);
|
||||
this.inputValue = '';
|
||||
}
|
||||
|
||||
doneEditing($event: any /** TODO #9100 */, todo: Todo): void {
|
||||
var which = $event.keyCode;
|
||||
doneEditing($event: KeyboardEvent, todo: Todo): void {
|
||||
const which = $event.keyCode;
|
||||
if (which === 13) {
|
||||
todo.title = todo.editTitle;
|
||||
this.todoEdit = null;
|
||||
@ -59,7 +59,7 @@ export class TodoApp {
|
||||
|
||||
deleteMe(todo: Todo): void { this.todoStore.remove(todo); }
|
||||
|
||||
toggleAll($event: any /** TODO #9100 */): void {
|
||||
toggleAll($event: MouseEvent): void {
|
||||
this.isComplete = !this.isComplete;
|
||||
this.todoStore.list.forEach((todo: Todo) => { todo.completed = this.isComplete; });
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ListWrapper, Predicate} from '@angular/core/src/facade/collection';
|
||||
|
||||
// base model for RecordStore
|
||||
export class KeyModel {
|
||||
@ -35,25 +34,14 @@ export class TodoFactory {
|
||||
|
||||
// Store manages any generic item that inherits from KeyModel
|
||||
@Injectable()
|
||||
export class Store {
|
||||
list: KeyModel[] = [];
|
||||
export class Store<T extends KeyModel> {
|
||||
list: T[] = [];
|
||||
|
||||
add(record: KeyModel): void { this.list.push(record); }
|
||||
add(record: T): void { this.list.push(record); }
|
||||
|
||||
remove(record: KeyModel): void { this._spliceOut(record); }
|
||||
remove(record: T): void { this.removeBy((item) => item === record); }
|
||||
|
||||
removeBy(callback: Predicate<KeyModel>): void {
|
||||
var records = this.list.filter(callback);
|
||||
ListWrapper.removeAll(this.list, records);
|
||||
removeBy(callback: (record: T) => boolean): void {
|
||||
this.list = this.list.filter((record) => !callback(record));
|
||||
}
|
||||
|
||||
private _spliceOut(record: KeyModel) {
|
||||
var i = this._indexFor(record);
|
||||
if (i > -1) {
|
||||
return this.list.splice(i, 1)[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private _indexFor(record: KeyModel) { return this.list.indexOf(record); }
|
||||
}
|
||||
|
Reference in New Issue
Block a user