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; }