CqFramework class
A simple framework for easy access to events created by the canvas.
class CqFramework {
/// The [CqWrapper] of this object.
final CqWrapper cqWrapper;
CqFramework._(this.cqWrapper);
CanvasElement get _canvas => cqWrapper.canvas;
Point _mousePosition(UIEvent e) => CqTools.mousePosition(e);
bool get _mobile => CqTools.mobile;
/**
* Fires a [CqStepEvent] every time [interval] has passed.
*
* Can be used for game logic. Will fire new events even if the browser
* tab is inactive.
*/
Stream<CqStepEvent> onStep(Duration interval) {
var controller = new StreamController<CqStepEvent>();
var lastTick = window.performance.now();
new Timer.periodic(interval, (_) {
var delta = window.performance.now() - lastTick;
lastTick = window.performance.now();
controller.add(new CqStepEvent(delta, lastTick));
});
return controller.stream;
}
/**
* Fires a [CqStepEvent] when `window.animationFrame`'s future executes.
*
* Can be used for rendering. Will not fire events while the browser tab is
* inactive.
*/
Stream<CqStepEvent> get onRender {
var controller = new StreamController<CqStepEvent>();
var lastTick = window.performance.now();
step(_) {
var delta = window.performance.now() - lastTick;
lastTick = window.performance.now();
window.animationFrame.then(step);
controller.add(new CqStepEvent(delta, lastTick));
};
window.animationFrame.then(step);
return controller.stream;
}
/**
* Fires a [CqMouseEvent] when an `onMouseMove` or an `onTouchMove` event
* is fired.
*/
Stream<Point> get onMouseMove {
Stream<UIEvent> stream;
if (_mobile) {
stream = _canvas.onTouchMove;
} else {
stream = _canvas.onMouseMove;
}
return stream.map((e) => _mousePosition(e));
}
/**
* Fires a [CqMouseEvent] when an `onMouseDown` or an `onTouchSouch` event
* is fired.
*/
Stream<CqMouseEvent> get onMouseDown {
var controller = new StreamController<CqMouseEvent>();
Stream<UIEvent> stream;
if (_mobile) {
stream = _canvas.onTouchStart;
} else {
stream = _canvas.onMouseDown;
}
stream.listen((e) {
e.preventDefault();
controller.add(new CqMouseEvent(_mousePosition(e), e.button));
});
return controller.stream;
}
/**
* Fires a [CqMouseEvent] when an `onMouseUp` or an `onTouchEnd` event
* is fired.
*/
Stream<CqMouseEvent> get onMouseUp {
Stream<UIEvent> stream;
if (_mobile) {
stream = _canvas.onTouchEnd;
} else {
stream = _canvas.onMouseUp;
}
return stream.map((e) => new CqMouseEvent(_mousePosition(e), e.button));
}
/**
* Returns a [Stream] of swipe direction.
*/
Stream<String> onSwipe({num threshold: 35, num timeout: 350}) {
var controller = new StreamController<String>();
var swipeSP = 0;
var swipeST = 0;
var swipeEP = 0;
var swipeET = 0;
swipeStart(e) {
e.preventDefault();
swipeSP = _mousePosition(e);
swipeST = window.performance.now();
}
swipeUpdate(e) {
e.preventDefault();
swipeEP = _mousePosition(e);
swipeET = window.performance.now();
}
swipeEnd(e) {
e.preventDefault();
var xDif = (swipeSP.x - swipeEP.x);
var yDif = (swipeSP.y - swipeEP.y);
var x = (xDif * xDif);
var y = (yDif * yDif);
var swipeDist = sqrt(x + y);
var swipeTime = (swipeET - swipeST);
var swipeDir = null;
if(swipeDist > threshold && swipeTime < timeout) {
if(xDif.abs() > yDif.abs()) {
if(xDif > 0) {
swipeDir = "left";
} else {
swipeDir = "right";
}
} else {
if(yDif > 0) {
swipeDir = "up";
} else {
swipeDir = "down";
}
}
controller.add(swipeDir);
}
}
if (_mobile) {
_canvas.onTouchStart.listen((e) => swipeStart(e));
_canvas.onTouchMove.listen((e) => swipeUpdate(e));
_canvas.onTouchEnd.listen((e) => swipeEnd(e));
} else {
_canvas.onMouseDown.listen((e) => swipeStart(e));
_canvas.onMouseMove.listen((e) => swipeUpdate(e));
_canvas.onMouseUp.listen((e) => swipeEnd(e));
}
return controller.stream;
}
/**
* Returns a stream of [KeyCode].
*/
Stream<int> get onKeyDown => document.onKeyDown.map((e) => e.keyCode);
/**
* Returns a stream of [KeyCode].
*/
Stream<int> get onKeyUp => document.onKeyUp.map((e) => e.keyCode);
/**
* Returns a Stream of [Rect] for the new size of the window.
*/
Stream<Rect> get onResize => window.onResize.map((_) => new Rect(0, 0, window.innerWidth, window.innerHeight));
/**
* Returns a [Stream} of dropped [ImageElement].
*/
Stream<ImageElement> get onDropImage {
var controller = new StreamController<ImageElement>();
document.onDrop.listen((MouseEvent e) {
e.stopPropagation();
e.preventDefault();
var file = e.dataTransfer.files[0];
if (!file.type.startsWith('image/')) {
controller.addError('unexpected filetype, "${file.name}" is not an image');
return;
}
var reader = new FileReader();
reader.onLoad.listen((ProgressEvent pe) {
var image = new ImageElement();
image.onLoad.listen((e3) {
controller.add(image);
});
image.src = reader.result;
});
reader.readAsDataUrl(file);
});
document.onDragOver.listen((e) {
e.preventDefault();
});
return controller.stream;
}
}
Properties
final Stream<ImageElement> onDropImage #
Returns a [Stream} of dropped ImageElement.
Stream<ImageElement> get onDropImage {
var controller = new StreamController<ImageElement>();
document.onDrop.listen((MouseEvent e) {
e.stopPropagation();
e.preventDefault();
var file = e.dataTransfer.files[0];
if (!file.type.startsWith('image/')) {
controller.addError('unexpected filetype, "${file.name}" is not an image');
return;
}
var reader = new FileReader();
reader.onLoad.listen((ProgressEvent pe) {
var image = new ImageElement();
image.onLoad.listen((e3) {
controller.add(image);
});
image.src = reader.result;
});
reader.readAsDataUrl(file);
});
document.onDragOver.listen((e) {
e.preventDefault();
});
return controller.stream;
}
final Stream<int> onKeyDown #
Returns a stream of KeyCode.
Stream<int> get onKeyDown => document.onKeyDown.map((e) => e.keyCode);
final Stream<int> onKeyUp #
Returns a stream of KeyCode.
Stream<int> get onKeyUp => document.onKeyUp.map((e) => e.keyCode);
final Stream<CqMouseEvent> onMouseDown #
Fires a CqMouseEvent when an onMouseDown or an onTouchSouch event
is fired.
Stream<CqMouseEvent> get onMouseDown {
var controller = new StreamController<CqMouseEvent>();
Stream<UIEvent> stream;
if (_mobile) {
stream = _canvas.onTouchStart;
} else {
stream = _canvas.onMouseDown;
}
stream.listen((e) {
e.preventDefault();
controller.add(new CqMouseEvent(_mousePosition(e), e.button));
});
return controller.stream;
}
final Stream<Point> onMouseMove #
Fires a CqMouseEvent when an onMouseMove or an onTouchMove event
is fired.
Stream<Point> get onMouseMove {
Stream<UIEvent> stream;
if (_mobile) {
stream = _canvas.onTouchMove;
} else {
stream = _canvas.onMouseMove;
}
return stream.map((e) => _mousePosition(e));
}
final Stream<CqMouseEvent> onMouseUp #
Fires a CqMouseEvent when an onMouseUp or an onTouchEnd event
is fired.
Stream<CqMouseEvent> get onMouseUp {
Stream<UIEvent> stream;
if (_mobile) {
stream = _canvas.onTouchEnd;
} else {
stream = _canvas.onMouseUp;
}
return stream.map((e) => new CqMouseEvent(_mousePosition(e), e.button));
}
final Stream<CqStepEvent> onRender #
Fires a CqStepEvent when window.animationFrame's future executes.
Can be used for rendering. Will not fire events while the browser tab is inactive.
Stream<CqStepEvent> get onRender {
var controller = new StreamController<CqStepEvent>();
var lastTick = window.performance.now();
step(_) {
var delta = window.performance.now() - lastTick;
lastTick = window.performance.now();
window.animationFrame.then(step);
controller.add(new CqStepEvent(delta, lastTick));
};
window.animationFrame.then(step);
return controller.stream;
}
final Stream<Rect> onResize #
Returns a Stream of Rect for the new size of the window.
Stream<Rect> get onResize => window.onResize.map((_) => new Rect(0, 0, window.innerWidth, window.innerHeight));
Methods
Stream<CqStepEvent> onStep(Duration interval) #
Fires a CqStepEvent every time interval has passed.
Can be used for game logic. Will fire new events even if the browser tab is inactive.
Stream<CqStepEvent> onStep(Duration interval) {
var controller = new StreamController<CqStepEvent>();
var lastTick = window.performance.now();
new Timer.periodic(interval, (_) {
var delta = window.performance.now() - lastTick;
lastTick = window.performance.now();
controller.add(new CqStepEvent(delta, lastTick));
});
return controller.stream;
}
Stream<String> onSwipe({num threshold: 35, num timeout: 350}) #
Returns a Stream of swipe direction.
Stream<String> onSwipe({num threshold: 35, num timeout: 350}) {
var controller = new StreamController<String>();
var swipeSP = 0;
var swipeST = 0;
var swipeEP = 0;
var swipeET = 0;
swipeStart(e) {
e.preventDefault();
swipeSP = _mousePosition(e);
swipeST = window.performance.now();
}
swipeUpdate(e) {
e.preventDefault();
swipeEP = _mousePosition(e);
swipeET = window.performance.now();
}
swipeEnd(e) {
e.preventDefault();
var xDif = (swipeSP.x - swipeEP.x);
var yDif = (swipeSP.y - swipeEP.y);
var x = (xDif * xDif);
var y = (yDif * yDif);
var swipeDist = sqrt(x + y);
var swipeTime = (swipeET - swipeST);
var swipeDir = null;
if(swipeDist > threshold && swipeTime < timeout) {
if(xDif.abs() > yDif.abs()) {
if(xDif > 0) {
swipeDir = "left";
} else {
swipeDir = "right";
}
} else {
if(yDif > 0) {
swipeDir = "up";
} else {
swipeDir = "down";
}
}
controller.add(swipeDir);
}
}
if (_mobile) {
_canvas.onTouchStart.listen((e) => swipeStart(e));
_canvas.onTouchMove.listen((e) => swipeUpdate(e));
_canvas.onTouchEnd.listen((e) => swipeEnd(e));
} else {
_canvas.onMouseDown.listen((e) => swipeStart(e));
_canvas.onMouseMove.listen((e) => swipeUpdate(e));
_canvas.onMouseUp.listen((e) => swipeEnd(e));
}
return controller.stream;
}