Skip to content

Commit

Permalink
add CanvasForm, fix resizing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
williamngan committed May 20, 2017
1 parent 413f17d commit f4c9eb2
Show file tree
Hide file tree
Showing 8 changed files with 583 additions and 56 deletions.
316 changes: 296 additions & 20 deletions dist/pts.js

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
</head>

<body>
e
<canvas id="pt" width="300" height="300"></canvas>
<!--<div id="pt" style="width:300px; height: 300px;">-->
<canvas id="pt" width="400" height="400"></canvas>
<!--</div>-->
<script type="text/javascript" src="./dist/pts.js"></script>
</body>

Expand Down
102 changes: 102 additions & 0 deletions src/CanvasForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {Form} from "./Form";
import {IPt, Pt} from "./Pt";
import {CanvasSpace} from "./CanvasSpace";
import {Const} from "./Util";

export class CanvasForm extends Form {

protected _space:CanvasSpace;
protected _ctx:CanvasRenderingContext2D;

constructor( space:CanvasSpace ) {
super();
this._space = space;
this._ctx = this._space.ctx;
this._ctx.fillStyle = "#e9f1f5";
this._ctx.strokeStyle = "#37405a";
}

public get space():CanvasSpace { return this._space; }


/**
* Set current fill style. For example: `form.fill("#F90")` `form.fill("rgba(0,0,0,.5")` `form.fill(false)`
* @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
* @return this
*/
public fill( c:string|boolean ):this {
if (typeof c == "boolean") {
this.filled = c;
} else {
this.filled = true;
this._ctx.fillStyle = c;
}
return this;
}


/**
* Set current stroke style. For example: `form.stroke("#F90")` `form.stroke("rgba(0,0,0,.5")` `form.stroke(false)` `form.stroke("#000", 0.5, 'round')`
* @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
* @param width Optional value (can be floating point) to set line width
* @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
* @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
* @return this
*/
public stroke( c:string|boolean, width?:number, linejoin?:string, linecap?:string ):this {
if (typeof c == "boolean") {
this.stroked = c;
} else {
this.stroked = true;
this._ctx.strokeStyle = c;
if (width) this._ctx.lineWidth = width;
if (linejoin) this._ctx.lineJoin = linejoin;
if (linecap) this._ctx.lineCap = linecap;
}
return this;
}


protected _paint() {
if (this._filled) this._ctx.fill();
if (this._stroked) this._ctx.stroke();
}

public point( p:IPt, radius:number=5, shape:string="square" ):this {
if (CanvasForm[shape]) {
CanvasForm[shape]( this._ctx, p, radius );
this._paint();
} else {
console.warn( `${shape} is not a static function of CanvasForm`);
}
return this;
}


public static circle( ctx:CanvasRenderingContext2D, pt:IPt, radius:number ) {
ctx.beginPath()
ctx.arc( pt.x, pt.y, radius, 0, Const.two_pi, false );
ctx.closePath();
}

public static square( ctx:CanvasRenderingContext2D, pt:IPt, halfsize:number ) {
let x1 = pt.x-halfsize
let y1 = pt.y-halfsize
let x2 = pt.x+halfsize
let y2 = pt.y+halfsize

// faster than using `rect`
ctx.beginPath()
ctx.moveTo( x1, y1 )
ctx.lineTo( x1, y2 )
ctx.lineTo( x2, y2 )
ctx.lineTo( x2, y1 )
ctx.closePath()
}


public draw( ps:Pt[], shape?:string ):this {
return this;
}

}
53 changes: 36 additions & 17 deletions src/CanvasSpace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Space} from './Space';
import {Pt, IPt} from './Pt';
import {Pts} from './Pts';
import {Bound} from './Bound';
import {CanvasForm} from "./CanvasForm";

interface PtsCanvasRenderingContext2D extends CanvasRenderingContext2D {
webkitBackingStorePixelRatio?:number;
Expand All @@ -11,16 +12,16 @@ interface PtsCanvasRenderingContext2D extends CanvasRenderingContext2D {
backingStorePixelRatio?:number;
}

type TouchPointsKey = "touches" | "changedTouches" | "targetTouches";
export type TouchPointsKey = "touches" | "changedTouches" | "targetTouches";


export default class CanvasSpace extends Space {
export class CanvasSpace extends Space {

protected _canvas:HTMLCanvasElement;

protected _container:Element;
protected _pixelScale = 1;
protected _autoResize = false;
protected _autoResize = true;
protected _bgcolor = "#F3F7FA";
protected _ctx:PtsCanvasRenderingContext2D;

Expand Down Expand Up @@ -70,6 +71,7 @@ export default class CanvasSpace extends Space {
} else {
this._canvas = _selector as HTMLCanvasElement;
this._container = _selector.parentElement;
this._autoResize = false;
}

// if size is known then set it immediately
Expand All @@ -84,6 +86,9 @@ export default class CanvasSpace extends Space {
// store canvas 2d rendering context
this._ctx = this._canvas.getContext('2d');

//


}


Expand All @@ -106,10 +111,10 @@ export default class CanvasSpace extends Space {
private _ready( callback:Function ) {
if (!this._container) throw `Cannot initiate #${this.id} element`;

if (this._autoResize) {
let b = this._container.getBoundingClientRect();
this.resize( Bound.fromBoundingRect(b) );
}

let b = (this._autoResize) ? this._container.getBoundingClientRect() : this._canvas.getBoundingClientRect();
this.resize( Bound.fromBoundingRect(b) );


this.clear( this._bgcolor );
this._canvas.dispatchEvent( new Event("ready") );
Expand All @@ -128,17 +133,29 @@ export default class CanvasSpace extends Space {
setup( opt:{bgcolor?:string, resize?:boolean, retina?:boolean} ):this {
if (opt.bgcolor) this._bgcolor = opt.bgcolor;

this._autoResize = (opt.resize === true);
if (opt.resize != undefined) this._autoResize = opt.resize;

if (opt.retina !== false) {
let r1 = window.devicePixelRatio || 1
let r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1;
this._pixelScale = r1/r2
let r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1;
this._pixelScale = r1/r2;
}
return this;
}


/**
* Get the rendering context of canvas
*/
public get ctx():PtsCanvasRenderingContext2D { return this._ctx; }


/**
* Get a new CanvasForm for drawing
*/
public getForm():CanvasForm { return new CanvasForm(this); }


/**
* Window resize handling
* @param evt
Expand Down Expand Up @@ -187,13 +204,15 @@ export default class CanvasSpace extends Space {

this.bound = b;

let s = this.bound.size.$scale( this._pixelScale );
this._canvas.width = s.x;
this._canvas.height = s.y;
this._canvas.style.width = s.x + "px";
this._canvas.style.height = s.y + "px";
this._canvas.width = this.bound.size.x * this._pixelScale;
this._canvas.height = this.bound.size.y * this._pixelScale;
this._canvas.style.width = this.bound.size.x + "px";
this._canvas.style.height = this.bound.size.y + "px";

if (this._pixelScale != 1) this._ctx.scale( this._pixelScale, this._pixelScale );
if (this._pixelScale != 1) {
this._ctx.scale( this._pixelScale, this._pixelScale );
this._ctx.translate( 0.5, 0.5);
}

for (let k in this.players) {
let p = this.players[k];
Expand Down
43 changes: 43 additions & 0 deletions src/Form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {Space} from "./Space";
import {Pt, IPt} from "./Pt";

export class Font {
public size:number;
public face:string;
public style:string;

constructor( size=11, face="sans-serif", style="") {
this.size = size;
this.face = face;
this.style = style;
}

get data():string { return `${this.style} ${this.size}px ${this.face}` };
}


export abstract class Form {

protected _filled = true;
public get filled():boolean { return this._filled; }
public set filled( b:boolean ) { this._filled = b; }

protected _stroked = true;
public get stroked():boolean { return this._stroked; }
public set stroked( b:boolean ) { this._stroked = b; }

protected _font:Font;
public get font():Font { return this._font; }
public set font( b:Font ) { this._font = b; }

abstract get space():Space;

public abstract fill( c:string|boolean ):this;

public abstract stroke( c:string|boolean, width?:number, linejoin?:string, linecap?:string ):this;

public abstract point( p:IPt, radius:number, shape?:string ): this;

public abstract draw( ps:Pt[], shape?:string ): this;

}
29 changes: 16 additions & 13 deletions src/Space.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import {Vector} from "vectorious";
import {Bound} from "./Bound";
import {Pt, IPt} from "./Pt";
import {Pts} from "./Pts";

import {Form} from "./Form";

export interface IPlayer {
animateID: string;
animate( time:number, frameTime:number, context:any ): IPlayer;
onSpaceResize( p:IPt, evt?:Event ): undefined;
onMouseAction( type:string, px:number, py:number, evt:Event );
onTouchAction( type:string, px:number, py:number, evt:Event );
animateID?: string;
animate( time:number, frameTime:number, context:any );
onSpaceResize?( p:IPt, evt?:Event ): undefined;
onMouseAction?( type:string, px:number, py:number, evt:Event );
onTouchAction?( type:string, px:number, py:number, evt:Event );
}

interface ISpacePlayers {
[key: string]: IPlayer;
}

interface ITimer {
export interface ITimer {
prev: number;
diff: number;
end: number;
Expand All @@ -30,12 +28,12 @@ export abstract class Space {
protected _time: ITimer = { prev: 0, diff: 0, end: -1 };
protected players:ISpacePlayers = {};
protected playerCount = 0;
protected ctx:any = {};
protected _ctx:any;

private _animID:number = -1;

private _pause:boolean = false;
private _refresh:boolean = false;
private _refresh:boolean = true;

/**
* Set whether the rendering should be repainted on each frame
Expand All @@ -58,7 +56,7 @@ export abstract class Space {

this.players[pid] = player;
player.animateID = pid;
player.onSpaceResize( this.bound );
if (player.onSpaceResize) player.onSpaceResize( this.bound );

return this;
}
Expand Down Expand Up @@ -111,7 +109,7 @@ export abstract class Space {

// animate all players
for (let k in this.players) {
this.players[k].animate( time, this._time.diff, this.ctx );
this.players[k].animate( time, this._time.diff, this._ctx );
}

// stop if time ended
Expand Down Expand Up @@ -164,11 +162,16 @@ export abstract class Space {
*/
abstract resize( b:IPt, evt?:Event ):this;


/**
* clear all contents in the space
*/
abstract clear( ):this;


/**
* Get a default form for drawing in this space
*/
abstract getForm():Form;

}
Loading

0 comments on commit f4c9eb2

Please sign in to comment.