Home

Awesome

cycle-canvas npm version Build Status

A canvas driver for Cycle.js. Great for games or art.

Currently highly experimental. Expect major breaking changes.

Installation

$ npm install cycle-canvas --save

Example

import {run} from '@cycle/rxjs-run';
import {makeCanvasDriver, rect, text} from 'cycle-canvas';
import {Observable} from 'rxjs/Observable';

function main () {
  return {
    Canvas: Observable.just(
      rect({
        x: 10,
        y: 10,

        width: 160,
        height: 100,

        draw: [
          {fill: 'purple'}
        ],

        children: [
          text({
            x: 15,
            y: 25,

            value: 'Hello World!',

            font: '18pt Arial',

            draw: [
              {fill: 'white'}
            ]
          })
        ]
      })
    )
  };
}

const drivers = {
  Canvas: makeCanvasDriver(null, {width: 800, height: 600})
};

run(main, drivers);

Looks like this:

img

Also check out the flappy bird example.

You can find the source for flappy bird here.

API

Creating a canvas driver

Using event streams of the canvas element

Drawing shapes and text

Transformations

Creating a canvas driver

<a id="makeCanvasDriver"></a> makeCanvasDriver(selector, canvasSize = null)

A factory for the canvas driver function.

Receives a selector which should resolve to a canvas to which the driver function will attach.

If the selector does not resolve to a canvas, a new canvas element will be added at the bottom of the document and the driver will attach to that canvas.

The input to this driver is a stream of drawing instructions and transformations as detailed below.

Arguments

Using event streams of the canvas element

<a id="events"></a> sources.Canvas.events(eventName)

Canvas driver exposes a source object with an events method, which works similarly to the events method of the DOM driver.

Example:

import {run} from '@cycle/rxjs-run';
import {makeCanvasDriver, rect, text} from 'cycle-canvas';
import 'rxjs'

function main (sources) {
  const canvasClick$ = sources.Canvas.events('click')
  const counter$ = canvasClick$.startWith(0).scan(counter => counter + 1)
  return {
    Canvas: counter$.map(counter =>
      rect({
        children: [
          text({
            x: 15,
            y: 25,
            value: `Canvas was clicked ${counter} times`,
            font: '18pt Arial',
            draw: [
              {fill: 'black'}
            ]
          })
        ]
      })
    )
  };
}

const drivers = {
  Canvas: makeCanvasDriver(null, {width: 800, height: 600})
};

run(main, drivers);

Drawing shapes and text

<a id="rect"></a> rect(params = {})

Draws a rectangle given an object containing drawing parameters.

params {}:

Example:

rect({
	x: 10,
	y: 10,
	width: 100,
	height: 100,
	draw: [
		{fill: 'purple'}
	],
	children: [
		rect({
			x: 20,
			y: 20,
			width: 50,
			height: 50,
			draw: [
				{fill: 'blue'}
			]
		})
	]
})

<a id="line"></a> line(params = {})

Draws line(s) given an object containing drawing parameters.

params {}:

Example:

line({
	x: 10,
	y: 10,
	style: {
		lineWidth: 2,
		lineCap: 'square',
		strokeStyle: '#CCCCCC'
	},
	points: [
		{x: 10, y: 10},
		{x: 10, y: 20},
		{x: 20, y: 10},
		{x: 10, y: 10}
	]
})

<a id="arc"></a> arc(params = {})

Draws an arc given an object containing drawing parameters.

params {}:

Example:

arc({
  x: 50,
  y: 50,
  radius: 50,
  startAngle: 0,
  endAngle: 2 * Math.PI,
  false,
  draw: [{fill: 'red'}, {stroke: 'black'}]
})

<a id="polygon"></a> polygon(params = {})

Draws line(s) given an object containing drawing parameters.

params {}:

Example:

polygon({
	points: [
		{x: 10, y: 0},
		{x: 0, y: 10},
		{x: 0, y: 30},
		{x: 30, y: 30},
		{x: 30, y: 10} // a house shaped polygon
	],
	draw: {
		stroke: '#000',
		fill: '#ccc'
	},
})

<a id="text"></a> text(options = {})

Draws text given an object containing drawing parameters.

params {}:

Example:

text({
	x: 10,
	y: 10,
	value: 'Hello World!',
	font: '18pt Arial',
	draw: [
		{fill: 'white'}
	]
})

<a id="image"></a> image(params = {})

Draws an image given an object containing drawing parameters.

params {}:

Example:

image({
	x: 10,
	y: 10,
  src: document.querySelector('img')
})

Transformations

Transformations are added as a list to the transformations attribute to drawing shapes and text.

<a id="translate"></a> translate: {x: number, y: number}

Moves the canvas origin to a different point.

Example:

	rect({
		transformations: [
      {translate: {x: 10, y: 10}}
    ],
		x: 100,
		y: 100,
		width: 150,
		height: 150,
		draw: [
			{fill: 'purple'}
		]
	})

<a id="rotate"></a> rotate: number

Rotate the canvas around the current origin.

Example:

	rect({
		transformations: [
		  {rotate: (20*Math.PI/180)}
    ],
		x: 10,
		y: 10,
		width: 150,
		height: 150,
		draw: [
			{fill: 'purple'}
		]
	})

<a id="scale"></a> scale: {x: number, y: number}

Scales the drawing bigger or smaller.

Example:

	rect({
		transformations: [
		  {scale: {x: 2, y: 2}},
    ],
		x: 10,
		y: 10,
		width: 150,
		height: 150,
		draw: [
			{fill: 'purple'}
		]
	})

Combining transformations

Example:

Rotate around the point (100, 100) and draw a 50x50px box centered there:

	rect({
		transformations: [
      {translate: {x: 100, y: 100}},
      {rotate: (20*Math.PI/180)}
    ],
		x: -25, // At this point, {x: 0, y: 0} is a point on position {x: 100, y: 100} of the canvas
		y: -25,
		width: 50,
		height: 50,
		draw: [
			{fill: 'purple'}
		]
	})