GithubHelp home page GithubHelp logo

flipboard / react-canvas Goto Github PK

View Code? Open in Web Editor NEW
13.1K 13.1K 924.0 102 KB

High performance <canvas> rendering for React components

License: BSD 3-Clause "New" or "Revised" License

JavaScript 100.00%

react-canvas's Introduction

react-canvas

Introductory blog post

React Canvas adds the ability for React components to render to <canvas> rather than DOM.

This project is a work-in-progress. Though much of the code is in production on flipboard.com, the React canvas bindings are relatively new and the API is subject to change.

Motivation

Having a long history of building interfaces geared toward mobile devices, we found that the reason mobile web apps feel slow when compared to native apps is the DOM. CSS animations and transitions are the fastest path to smooth animations on the web, but they have several limitations. React Canvas leverages the fact that most modern mobile browsers now have hardware accelerated canvas.

While there have been other attempts to bind canvas drawing APIs to React, they are more focused on visualizations and games. Where React Canvas differs is in the focus on building application user interfaces. The fact that it renders to canvas is an implementation detail.

React Canvas brings some of the APIs web developers are familiar with and blends them with a high performance drawing engine.

Installation

React Canvas is available through npm:

npm install react-canvas

React Canvas Components

React Canvas provides a set of standard React components that abstract the underlying rendering implementation.

<Surface>

Surface is the top-level component. Think of it as a drawing canvas in which you can place other components.

<Layer>

Layer is the the base component by which other components build upon. Common styles and properties such as top, width, left, height, backgroundColor and zIndex are expressed at this level.

<Group>

Group is a container component. Because React enforces that all components return a single component in render(), Groups can be useful for parenting a set of child components. The Group is also an important component for optimizing scrolling performance, as it allows the rendering engine to cache expensive drawing operations.

<Text>

Text is a flexible component that supports multi-line truncation, something which has historically been difficult and very expensive to do in DOM.

<Image>

Image is exactly what you think it is. However, it adds the ability to hide an image until it is fully loaded and optionally fade it in on load.

<Gradient>

Gradient can be used to set the background of a group or surface.

  render() {
    ...
    return (
      <Group style={this.getStyle()}>
        <Gradient style={this.getGradientStyle()} 
                  colorStops={this.getGradientColors()} />
      </Group>
    );
  }
  getGradientColors(){
    return [
      { color: "transparent", position: 0 },
      { color: "#000", position: 1 }
    ]
  }

<ListView>

ListView is a touch scrolling container that renders a list of elements in a column. Think of it like UITableView for the web. It leverages many of the same optimizations that make table views on iOS and list views on Android fast.

Events

React Canvas components support the same event model as normal React components. However, not all event types are currently supported.

For a full list of supported events see EventTypes.

Building Components

Here is a very simple component that renders text below an image:

var React = require('react');
var ReactCanvas = require('react-canvas');

var Surface = ReactCanvas.Surface;
var Image = ReactCanvas.Image;
var Text = ReactCanvas.Text;

var MyComponent = React.createClass({

  render: function () {
    var surfaceWidth = window.innerWidth;
    var surfaceHeight = window.innerHeight;
    var imageStyle = this.getImageStyle();
    var textStyle = this.getTextStyle();

    return (
      <Surface width={surfaceWidth} height={surfaceHeight} left={0} top={0}>
        <Image style={imageStyle} src='...' />
        <Text style={textStyle}>
          Here is some text below an image.
        </Text>
      </Surface>
    );
  },

  getImageHeight: function () {
    return Math.round(window.innerHeight / 2);
  },

  getImageStyle: function () {
    return {
      top: 0,
      left: 0,
      width: window.innerWidth,
      height: this.getImageHeight()
    };
  },

  getTextStyle: function () {
    return {
      top: this.getImageHeight() + 10,
      left: 0,
      width: window.innerWidth,
      height: 20,
      lineHeight: 20,
      fontSize: 12
    };
  }

});

ListView

Many mobile interfaces involve an infinitely long scrolling list of items. React Canvas provides the ListView component to do just that.

Because ListView virtualizes elements outside of the viewport, passing children to it is different than a normal React component where children are declared in render().

The numberOfItemsGetter, itemHeightGetter and itemGetter props are all required.

var ListView = ReactCanvas.ListView;

var MyScrollingListView = React.createClass({

  render: function () {
    return (
      <ListView
        numberOfItemsGetter={this.getNumberOfItems}
        itemHeightGetter={this.getItemHeight}
        itemGetter={this.renderItem} />
    );
  },

  getNumberOfItems: function () {
    // Return the total number of items in the list
  },

  getItemHeight: function () {
    // Return the height of a single item
  },

  renderItem: function (index) {
    // Render the item at the given index, usually a <Group>
  },

});

See the timeline example for a more complete example.

Currently, ListView requires that each item is of the same height. Future versions will support variable height items.

Text sizing

React Canvas provides the measureText function for computing text metrics.

The Page component in the timeline example contains an example of using measureText to achieve precise multi-line ellipsized text.

Custom fonts are not currently supported but will be added in a future version.

css-layout

There is experimental support for using css-layout to style React Canvas components. This is a more expressive way of defining styles for a component using standard CSS styles and flexbox.

Future versions may not support css-layout out of the box. The performance implications need to be investigated before baking this in as a core layout principle.

See the css-layout example.

Accessibility

This area needs further exploration. Using fallback content (the canvas DOM sub-tree) should allow screen readers such as VoiceOver to interact with the content. We've seen mixed results with the iOS devices we've tested. Additionally there is a standard for focus management that is not supported by browsers yet.

One approach that was raised by Bespin in 2009 is to keep a parallel DOM in sync with the elements rendered in canvas.

Running the examples

npm install
npm start

This will start a live reloading server on port 8080. To override the default server and live reload ports, run npm start with PORT and/or RELOAD_PORT environment variables.

A note on NODE_ENV and React: running the examples with NODE_ENV=production will noticeably improve scrolling performance. This is because React skips propType validation in production mode.

Using with webpack

The brfs transform is required in order to use the project with webpack.

npm install -g brfs
npm install --save-dev transform-loader brfs

Then add the brfs transform to your webpack config

module: {
  postLoaders: [
    { loader: "transform?brfs" }
  ]
}

Contributing

We welcome pull requests for bug fixes, new features, and improvements to React Canvas. Contributors to the main repository must accept Flipboard's Apache-style Individual Contributor License Agreement (CLA) before any changes can be merged.

react-canvas's People

Contributors

aboutqx avatar charlietuna avatar codrin-iftimie avatar darkyen avatar devongovett avatar gre avatar hiirene avatar jodelamo avatar mbrgm avatar nolski avatar oleksmarkh avatar petrgazarov avatar stevenw avatar stlk avatar tuxracer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-canvas's Issues

Style inheritance and cascading

Thanks for opensourcing this, however, I do have a question. I’m not sure if anybody done this before and if it would make sense in react-canvas or react-native, but what about CSS-like inheritance and cascading of styles? Even though, everything seems like big step forward in performance and app development, styling, in my opinion, seems more complicated and difficult. Am I wrong?

Top <Image /> half is cut off

I encounter the following result of the css-layout example in all three Chrome Canary, Safari and Firefox. The same happens to my own images.

bildschirmfoto 2015-02-17 um 20 16 04

When using a canvas component, mountedImages[i] is undefined

Use case like so:

import { Button } from 'reapp-kit';
import { Surface, Text } from 'react-canvas';

export default class extends React.Component {
  render() {
    return (
      <Surface width={styles.width} height={styles.height} left={0} top={0}>
        <Text style={styles.text}>
          Here is some text
        </Text>
        <Button>
          hello world
        </Button>
      </Surface>
    );
  }
};

const styles = {
  width: window.innerWidth,
  height: window.innerHeight,

  text: {
    top: 20,
    left: 20,
    width: window.innerWidth,
    height: 20,
    lineHeight: 20,
    fontSize: 12
  }
}

Button is just a simple surface, but its defined in an different module. That module does a require('react-canvas') as well though.

Error is on this line:

mountedImages[i].inject(this.node);

When inspecting that error, mountedImages looks like:

[RenderLayer, "<canvas width="400" height="400" style="width:200px;height:200px;" data-reactid="undefined.1"></canvas>"]

Seems like the problem is that it's expecting a RenderLayer but it's getting a string (the canvas string above).

Any ideas?

Building a UI with layers

Is it possible to create a simple app that uses layers for different aspects of the interactive UI? React-Canvas looks like it is flexible enough for what I have in mind but it is also quite abstracted, likely in order to be an optimal 60fps solution.

Its a good thing I was already calling my apex component the surface. My surface would require different layers for different aspects of rendering and editing. Here is how I envision the layer stack:

surface-container
• background-commit-layer
• foreground-commit-layer
• tool-editing-layer
• tool-reporting-layer
• config-form-layer

The commit layers have a canvas each. Tool edited data would be rendered here, with the background layer rendering data that does not change to often and the foreground layer rendering data that changes more often. These layers optimize the amount of rendering required and serve as useful aspects of the final product the app editing produces.

The tool editing layer renders items during editing, once the editing is complete and accepted the commit layers would update. The report layer draws useful tool data while tools are used, so this has its own layer. These are both canvas based layers.

The config form layer is the only one that is more DOM based. Essentially it is only used to edit various states and styles for the different components in the app, react-router can be used here to manage the different config panels.

These layers would fill the complete app frame and be arranged by z-index and have their own alpha transparency settings or be hidden altogether until some tool brings them forward.

Within the two tool related layers there would also be children components for different editors. I'm assuming that React-Canvas components can contain a mix of canvas or DOM based components.

Is this humble layered app design possible? It looks like the Surface has one base RenderLayer. How do more RenderLayers get added as children of the base RenderLayer? Not sure the Image and Text layers alone are right for defining my apps layer stack?

It certainly would be helpful to understand the React-Canvas API from the perspective described above then move on from there. I have a hunch that React-Canvas can do many things. Its just a matter of grounding the abstractions in something I know.

Component not updated

I have built a little component called Visualizer, mainly it receives a list of element and render them based on their bounds and it allows to drag them around in a given zone, the render function look like that :

render() {
    var {top, left, width, height, boardRenderer} = this.props;

    var elements = this.state.elements.map(element => {
      var renderer = this.props.boardElementRender(element);
      var dragging = this.state.elementsDragging.contains(element.id);

      return <BoardElementRenderer 
                element={element} 
                renderer={renderer} 
                dragging={dragging} 
                onTouchStart={(arg) => this.elementTouchStart(arg)} 
                onTouchEnd={(arg) => this.elementTouchEnd(arg)} />
    });

    var style = { top, left, width, height, position: 'relative' };
    return (
        <Group style={style} onTouchMove={this.touchMove}>
          {boardRenderer}
          {elements}
        </Group>
    );
  }

the parent application contains only a vizualizer element:

render() {
    var {width, height} = this.getSize();
    var boardRenderer = <Layer style={{ 
      backgroundColor: "#EEE", 
      margin: 10,
      width: width - 20, 
      height: height - 20,
      position: 'relative'
    }} />;
    return (
       <Surface top={0} left={0} width={width} height={height} enableCSSLayout={true}>
        <Visualizer 
          elements={this.state.elements}
          top={0} left={0}
          width={width} height={height} 
          boardRenderer={boardRenderer}
          boardElementRender={element => <NoteRenderer element={<Note>element} />}/>
       </Surface>

    );
  }

Now if I move Surface from the top level app inside the Vizualizer like that :

//vizualizer
return (
     <Surface top={0} left={0} width={width} height={height} enableCSSLayout={true}>
        <Group style={style} onTouchMove={this.touchMove}>
          {boardRenderer}
          {elements}
        </Group>
    </Surface>
    );
// main app
return (
  <Visualizer 
          elements={this.state.elements}
          top={0} left={0}
          width={width} height={height} 
          boardRenderer={boardRenderer}
          boardElementRender={element => <NoteRenderer element={<Note>element} />}/>
)

Everything works fine, however if I leave the Surface inside the TopLevel application the Vizualizer never updated the rendered children when drawing. is their something I miss understood or is it a bug ?

Testing

How should these components be tested? I know there's a tests example but that only has a simple test for clamp.js. When you get to testing an actual component, jsdom will complain about the canvas element. Installing node-canvas is no walk in the park afterwards.

Any pointers?

peerDependency causes issues

Does this component really depend on Does react-canvas really depend on React v0.13.0-beta.1? When installed with other commonly used React modules from npm (react-router, react-hot-loader, etc.) this causes npm to be unable to resolve which version of React to use.

For example:

npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants [email protected]
npm ERR! peerinvalid Peer [email protected] wants react@^0.13.0-beta.1
npm ERR! peerinvalid Peer [email protected] wants react@>=0.11.0 || >=0.13.0-beta.1

If react-canvas actually does depend on the beta version of React and the beta version only, then I would update the README to let users know this. Otherwise, I would suggest updating the value of the peerDependency property to be >=0.11.x || 0.13.0-beta.1 in order to enable npm to properly resolve React.

If you are open to this change, I can make a PR.

Getting mega slow behaviour

First of all I am sorry for posting a problem question, but since there is no chat available for these types of discussions, I just went ahead with it and I figure it might help others.

I am entertaining myself trying to build a swipeable cards component, following ListView.js as an example. I am stuck here, because when I put more than 10 cards in the Main component's state, this becomes mega slow. I tried profiling the CPU and it drawImage() showed up as a primary suspect. I am not sure what I'm doing wrong here, since I'm following the example pretty much in the same way, just not using scroller.

I know there are some requestAnimationFrames going on, but those do not fire until there are touch events. The slow behaviour appears while rendering. I was actually not sure if this is the correct way to animate using your library.

Any pointers would be helpful. Happy to make a pull request to the examples directory with this if you guys can help me figure out what might be wrong here.

Thanks

Main.jsx

'use strict'

import React from 'react';
import ReactCanvas from 'react-canvas';
import Card from './Card';
import api from '../Utils/api.js';

var {
    Surface
} = ReactCanvas;


class Main extends React.Component{
    constructor() {
        super();

        this.state = {
            size: document.getElementById('main').getBoundingClientRect(),
            cards: [
                {
                    id: 0,
                    image: 'http://lorempixel.com/500/500',
                },
                {
                    id: 1,
                    image: 'http://lorempixel.com/501/501',
                },
                {
                    id: 2,
                    image: 'http://lorempixel.com/502/502',
                }
            ] 
        }
    }
    destroyCard() {
        this.setState({ cards: this.state.cards.slice(0, -1) })
    }

    cardSwipeLeft() {
        console.log('Card Swipe Left');
    }

    cardSwipeRight() {
        console.log('Card Swipe Right');
    }

    renderCards() {
        return this.state.cards.map( (c, i) => {
            return ( 
                <Card 
                    key={c.id} 
                    onDestroy={this.destroyCard.bind(this)} 
                    imageSrc={c.image} 
                    onSwipeLeft={this.cardSwipeLeft.bind(this)} 
                    onSwipeRight={this.cardSwipeRight.bind(this)} /> 
                )
        })
    }

    render() {
        return (
            <Surface top={0} left={0} width={this.state.size.width} height={this.state.size.height}>
                { this.renderCards() }
            </Surface>
        )
    }
}

module.exports = Main

Card.jsx

'use strict'

import React from 'react';
import ReactCanvas from 'react-canvas';

var VELOCITY_ESCAPE_THRESHOLD = 1;
var ESCAPE_BOUNDING_BOX_SIZE = 0.15;

var {
    Group,
    Surface,
    Image
} = ReactCanvas;

class Card extends React.Component{
    constructor() {
        super();

        this.state = {
            scrollX: 0,
            size: document.getElementById('main').getBoundingClientRect()
        }
    }

    handleTouchStart(e){
        this.setState({ touchStartPoint: e.touches[0].pageX, touchStartTimeStamp: e.timeStamp });
    }

    handleTouchMove(e){
        if (this.state.touchStartPoint)
            this.setState({ scrollX: e.touches[0].pageX - this.state.touchStartPoint });
    }

    handleTouchEnd(e){
        var velocity = this.state.scrollX/(e.timeStamp - this.state.touchStartTimeStamp),
            pageX = this.state.scrollX + this.state.touchStartPoint,
            leaves = false,
            direction = this.state.scrollX/Math.abs(this.state.scrollX);

        if (Math.abs(velocity) >= VELOCITY_ESCAPE_THRESHOLD && velocity < 0)
            leaves = 'left';

        if (Math.abs(velocity) >= VELOCITY_ESCAPE_THRESHOLD && velocity > 0)
            leaves = 'right';

        if (pageX >= 0 && pageX < (this.state.size.width * ESCAPE_BOUNDING_BOX_SIZE) )
            leaves = 'left';

        if (pageX > (this.state.size.width) * ( 1 - ESCAPE_BOUNDING_BOX_SIZE) && pageX <= this.state.size.width)
            leaves = 'right'

        if (!leaves)
            window.requestAnimationFrame(function move() {
                if ( Math.abs(this.state.scrollX) > 1) {
                    this.setState({ scrollX: (this.state.scrollX / 1.5)  })
                    window.requestAnimationFrame(move.bind(this))
                }
            }.bind(this));

        if (leaves) {
            window.requestAnimationFrame(function move() {
                if ( Math.abs(this.state.scrollX) < this.state.size.width*2.5) {
                    this.setState({ scrollX: (this.state.scrollX + 200*direction) })
                    window.requestAnimationFrame(move.bind(this))
                } else {
                    this.destroyItem()
                }
            }.bind(this));
        }

        if (leaves === 'left') 
            this.props.onSwipeLeft && this.props.onSwipeLeft()

        if (leaves === 'right') 
            this.props.onSwipeLeft && this.props.onSwipeRight()
    }

    destroyItem() {
        this.props.onDestroy && this.props.onDestroy();
    }

    handleTouchCancel(e){
        return handleTouchEnd(e)
    }

    render() {
        var containerStyle = {
            top: 0,
            left: 0,
            width: this.state.size.width,
            height: this.state.size.height,
            translateX: this.state.scrollX
        };

        var imageStyle = {
            top: 0,
            left: 0,
            width: this.state.size.width,
            height: Math.floor(this.state.size.height * 0.5),
            backgroundColor: '#eee',
            zIndex: 3
        };

        return (
            <Group style={containerStyle}
                onTouchStart={this.handleTouchStart.bind(this) }
                onTouchMove={ this.handleTouchMove.bind(this) }
                onTouchEnd={this.handleTouchEnd.bind(this)}
                onTouchCancel={this.handleTouchEnd.bind(this)}>

                <Image style={imageStyle} src={this.props.imageSrc} fadeIn={true} useBackingStore={true} />
            </Group>
        )
    }
}

Card.propTypes = {
    imageSrc: React.PropTypes.string.isRequired
}

module.exports = Card;

impossible to npm install

when doing npm install :
npm ERR! git clone git://github.com/mjohnston/scroller Cloning into bare repository '/Users/cosmocat/.npm/_git-remotes/git-github-com-mjohnston-scroller-440e2a6b'...
npm ERR! git clone git://github.com/mjohnston/scroller fatal: unable to connect to github.com:
npm ERR! git clone git://github.com/mjohnston/scroller github.com[0: 192.30.252.129]: errno=Operation timed out
npm ERR! Darwin 14.1.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v0.12.0
npm ERR! npm v2.5.1
npm ERR! code 128

npm ERR! Command failed: git clone --template=/Users/cosmocat/.npm/_git-remotes/_templates --mirror git://github.com/mjohnston/scroller /Users/cosmocat/.npm/_git-remotes/git-github-com-mjohnston-scroller-440e2a6b
npm ERR! Cloning into bare repository '/Users/cosmocat/.npm/_git-remotes/git-github-com-mjohnston-scroller-440e2a6b'...
npm ERR! fatal: unable to connect to github.com:
npm ERR! github.com[0: 192.30.252.129]: errno=Operation timed out

[Enhancement]: Ability to use a router

Any real world application would need one, or some way to do so.

There are many react routers currently existent, I used this one https://github.com/rackt/react-router

The current way i could think off was rendering a canvas inside a route and then binding this on the top but that broke transitions :-/

second method I thought ( which works now) is having the router write an empty url then accessing the route via a store ( flux !!), but that is just too ugly.

[enhancement]: Roadmap

Perhaps a roadmap for this ?
serves as a common path for contributors to follow if they want to commit code ?

or / and
A gitter chat for this repo ?
serves as a place for discussions, helps begginers get thorough and eases communication :-D

[Enhancement]: Ability to use react-router

Any real world application would need this. https://github.com/rackt/react-router

The current way i could think off was rendering a canvas inside a route and then binding this on the top but that broke transitions :-/

second method I thought ( which works now) is having the router write an empty url then accessing the route via a store ( flux !!), but that is just too ugly.

dependency errors

npm install fails every time on git://github.com/mjohnston/scroller because of firewall, so i removed it from package and manually installed submodule under mjohnston/scroller

after all that I get the following error. Obviously my machine has > .NET 4 SDKs installed. I manually grabbed the 2.0 SDKs and jest still fails.

C:\dev\react-canvas\node_modules\jest-cli\node_modules\jsdom\node_modules\contextify>node "C:\nodejs\node_modules\npm\bin\node-gyp-bin....\node_modules\node-gyp\bin\node-gyp.js" rebuild
child_process: customFds option is deprecated, use stdio instead.
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
MSBUILD : error MSB3428: Could not load the Visual C++ component "VCBuild.exe". To fix this, 1) install the .NET Framework 2.0 SDK, 2) install Microsoft Visua l Studio 2005 or 3) add the location of the component to the system path if it
is installed elsewhere. [C:\dev\react-canvas\node_modules\jest-cli\node_module s\jsdom\node_modules\contextify\build\binding.sln]
gyp ERR! build error
gyp ERR! stack Error: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild.exe failed with exit code: 1
gyp ERR! stack at ChildProcess.onExit (C:\nodejs\node_modules\npm\node_modules\node-gyp\lib\build.js:267:23)
gyp ERR! stack at ChildProcess.emit (events.js:110:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:1067:12)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "node" "C:\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" "rebuild"
gyp ERR! cwd C:\dev\react-canvas\node_modules\jest-cli\node_modules\jsdom\node_modules\contextify
gyp ERR! node -v v0.12.0
gyp ERR! node-gyp -v v1.0.2
gyp ERR! not ok
npm WARN optional dep failed, continuing [email protected]
npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\nodejs\node.exe" "C:\nodejs\node_modules\npm\bin\npm-cli.js" "install"
npm ERR! node v0.12.0
npm ERR! npm v2.5.1
npm ERR! code ELIFECYCLE

npm ERR! [email protected] install: node-gyp rebuild
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the contextify package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-gyp rebuild
npm ERR! You can get their info via:
npm ERR! npm owner ls contextify
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! C:\dev\react-canvas\npm-debug.log

Is this better than dom?

I'm very intrigued with this project but I'm curious, other than accessibility, is there any reason this isn't a better solution than DOM? What is currently challenging with this technology thats much easier via dom (assuming we're making a self-contained app, not a traditional website).

A similar canvas solution(Quamolit) here

I'm very interested in this project since I was trying is a similar approach named Quamolit here:
https://github.com/Quamolit
Project Quamolit is not yet done. Actually I'm feeling quite stressful to push it forward due to transitions.
Anyway here's what I think on declarative programming based on canvas:

Why use canvas

I made an expriment before with React Animations(http://repo.cirru.org/fractal-editor/index.html) but got such a conclusion:

My solution

So I created Quamolit, in which each element has it unique id, and its internal state. Then even after sorting, given one element is not destroyed, it will just make transition to its new position or state.
In such way, an element can even jump to another branch if its id stays.

Meanwhile, in elements' lifecycles, there are 'delay', 'entering', 'stable', 'changing', 'postpone', 'leaving'. In most of these periods, there are transitions. By doing this, I think creating animations can be much easier.

At last I took a solution which is quite different with React in syntax. Here's an early example:

https://github.com/Quamolit/todolisting/blob/master/src/app/container.coffee

module.exports = Quamolit.createComponent
  name: 'container'

  stores:
    todos: [todoStore, 'all']

  getInitialState: -> text: ''

  getKeyframe: -> x: 0, y: 0
  getEnteringKeyframe: -> x: -40, y: 0
  getLeavingKeyframe: ->
    @getEnteringKeyframe()

  render: ->
    header = [
      handler {x: 0, y: -140}, {}
    ]

    items = @state.todos.map (data, index) =>
      order = index
      line {x: 0, y: (80 * order - 80)}, {data: data, id: "line.#{data.id}", isComposing: false}

    header.concat items

I'm not sure if that helps react-canvas. Just want to say I'm really interested in such solutions on programming in canvas.

Unable to install react and react-canvas via npm together

☁  gulp-starter [master] npm install --save react react-canvas
npm WARN package.json [email protected] No README data
npm ERR! Darwin 14.1.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "--save" "react" "react-canvas"
npm ERR! node v0.12.0
npm ERR! npm  v2.6.0
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react@^0.13.0-beta.1

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/marc/Dev/React/gulp-starter/npm-debug.log

Events not fired on children of Group

I have a Group containing a Layer. The Layer has a onClick prop, and it does not get fired when clicked, although it works fine when the onClick prop is on the Group.

Is this some yet-to-be-done area ?

zIndex for Groups

I have the situation where I'd like to order Groups by their zIndex. I have a menubar at the top of the screen and a ListView below it. Now that menubar should always stay on top of other elements, which it doesn't because it is drawn first.

In the source I found that Layers are in fact ordered by their zIndex, but Groups are not. Would that ordering be applicable to Groups, too?

onClick on listview example broken

Modified the code on Item to:

  onGroupClick: function() {
    console.log(this.props.title);
  },

  render: function () {
    return (
      <Group style={this.getStyle()} onClick={this.onGroupClick}>
        <Image style={this.getImageStyle()} src={this.props.imageUrl} />
        <Text style={this.getTitleStyle()}>{this.props.title}</Text>
      </Group>
    );
  },

(link to forked repo with this code)

When I click on the first item in the list, it seems to think that I'm clicking on another item. No other items respond to click, just the first.

screen shot 2015-02-12 at 1 52 35 pm

(start! and end! are just statements that I inserted on touchstart and touchend)

onClick works as expected on the Group components of the timeline example, however.

Performance > rendering

I've noticed on the examples such as listView that items are rendered on each scroll event. This works for simple and flat DOM structure but as soon as an item becomes deep and complex, rendering on scroll becomes a bottleneck (renders take more than 16 ms).

Even if I cache the items in ListView instead of calling the getter, the render methods on the children are still called. It seems to be due to this line. Do you have any suggestions to avoid rendering so frequently?

Problem adding Surface element to existing app

I'm having some problems adding a Surface component to my existing app, I have no problem running the example files but no matter what I try in my app I get the following error:

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. 
This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). 
Try rendering this component inside of a new top-level component which will hold the ref.

Even this simple example throws the error:

var React = require('react');
var ReactCanvas = require('react-canvas');
var Surface = ReactCanvas.Surface;
var Text = ReactCanvas.Text;

window.onload = function() {
    React.render(<Surface top={0} left={0} width={100} height={100}>
        <Text>Professor PuddinPop</Text>
    </Surface>, document.body); 
}

Am I doing something wrong?

Use css-layout in more complex example

Wondering, if using css-layout in a bigger size app it seems like you'd need to override and hook into the style attribute to do calculations.

You'd also probably have some system tracking the object of styles as they change, and re-calculating them. Seems like it would get complex really fast.

Have you guys used css-layout more extensively or tackled this sort of thing?

cannot run examples

☃ npm start

> [email protected] start /Users/deadlyicon/tmp/react-canvas
> gulp

[16:03:07] Using gulpfile ~/tmp/react-canvas/gulpfile.js
[16:03:07] Starting 'clean'...
[16:03:07] Finished 'clean' after 2.42 ms
[16:03:07] Starting 'build'...
[16:03:07] Starting 'serve'...
[16:03:07] Finished 'serve' after 7.43 ms
[16:03:07] Starting 'watch'...
[16:03:07] Finished 'watch' after 4.16 ms

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EADDRINUSE
    at errnoException (net.js:904:11)
    at Server._listen2 (net.js:1042:14)
    at listen (net.js:1064:10)
    at Server.listen (net.js:1138:5)
    at ConnectApp.server (/Users/deadlyicon/tmp/react-canvas/node_modules/gulp-connect/index.js:57:19)
    at new ConnectApp (/Users/deadlyicon/tmp/react-canvas/node_modules/gulp-connect/index.js:37:10)
    at Object.module.exports.server (/Users/deadlyicon/tmp/react-canvas/node_modules/gulp-connect/index.js:170:12)
    at Gulp.<anonymous> (/Users/deadlyicon/tmp/react-canvas/gulpfile.js:21:11)
    at module.exports (/Users/deadlyicon/tmp/react-canvas/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:34:7)
    at Gulp.Orchestrator._runTask (/Users/deadlyicon/tmp/react-canvas/node_modules/gulp/node_modules/orchestrator/index.js:273:3)

npm ERR! Darwin 14.1.0
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.10.33
npm ERR! npm  v2.1.11
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `gulp`
npm ERR! Exit status 8
npm ERR!
npm ERR! Failed at the [email protected] start script 'gulp'.
npm ERR! This is most likely a problem with the react-canvas package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     gulp
npm ERR! You can get their info via:
npm ERR!     npm owner ls react-canvas
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/deadlyicon/tmp/react-canvas/npm-debug.log

npm-debug.log

0 info it worked if it ends with ok
1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose node symlink /usr/local/bin/node
5 verbose run-script [ 'prestart', 'start', 'poststart' ]
6 info prestart [email protected]
7 info start [email protected]
8 verbose unsafe-perm in lifecycle true
9 info [email protected] Failed to exec start script
10 verbose stack Error: [email protected] start: `gulp`
10 verbose stack Exit status 8
10 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:212:16)
10 verbose stack     at EventEmitter.emit (events.js:98:17)
10 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12)
10 verbose stack     at ChildProcess.emit (events.js:98:17)
10 verbose stack     at maybeClose (child_process.js:756:16)
10 verbose stack     at Process.ChildProcess._handle.onexit (child_process.js:823:5)
11 verbose pkgid [email protected]
12 verbose cwd /Users/deadlyicon/tmp/react-canvas
13 error Darwin 14.1.0
14 error argv "node" "/usr/local/bin/npm" "start"
15 error node v0.10.33
16 error npm  v2.1.11
17 error code ELIFECYCLE
18 error [email protected] start: `gulp`
18 error Exit status 8
19 error Failed at the [email protected] start script 'gulp'.
19 error This is most likely a problem with the react-canvas package,
19 error not with npm itself.
19 error Tell the author that this fails on your system:
19 error     gulp
19 error You can get their info via:
19 error     npm owner ls react-canvas
19 error There is likely additional logging output above.
20 verbose exit [ 1, true ]

Possible Drawing Surface?

Maybe I can get a little clarification. I'm hoping to use opentype.js to draw to a canvas. I would like to have a stack of canvas layers, targeting specific drawing instructions to specific layers in the stack.

The canvases would all be the same size and use their own transparency settings so there would be a blended composite image resulting from the complete stack of canvas layers. The layers would fill the viewport and be the main app UI (not just be an aside scroller widget).

Is this the kind of thing that react-canvas is intended for?

About layout calculation in 'draw' function

I see every time surface draw,it will calculate the layout again:

draw: function () {
var layout;
if (this.node) {
if (this.props.enableCSSLayout) {
layout = layoutNode(this.node);
}
DrawingUtils.drawRenderLayer(this.getContext(), this.node);
}
},

But I think only calculate the whole layout when style changed with the layout is better,for example,change the backgroundColor do not recalculate the laytout.

TypeScript definitions file

I created a little typescript def file, it's based on https://github.com/fdecampredon/jsx-typescript/blob/jsx/typings/react.d.ts if anybody is interested.

declare module 'react-canvas' {
  import React = require('react');


  type Style = {
    //Text Related props
    color?: string;
    fontFace?: FontFace;
    fontSize?: number;
    lineHeight?: number;
    textAlign?: string

    // Layer style
    backgroundColor?: string;
    borderColor?: string;
    borderRedius?: number;
    clipRect?: string;
    zIndex?: number; 
    alpha?: number; 
    scale?: number; 
    translateX?: number; 
    translateY?: number; 

    ///CSS Layout style

    top?: number;
    left?: number;
    right?: number;
    bottom?: number;

    width?: number | string;
    height?: number | string;

    margin?: number;
    marginLeft?: number;
    marginRight?: number;
    marginTop?: number;
    marginBottom?: number;

    padding?: number;
    paddingLeft?: number;
    paddingRight?: number;
    paddingTop?: number;
    paddingBottom?: number;

    borderWidth?: number;
    borderLeftWidth?: number;
    borderRightWidth?: number;
    borderTopWidth?: number;
    borderBottomWidth?: number;

    flexDirection?: string;
    justifyContent?: string;
    alignItems?: string; 
    alignSelf?: string;

    flex?: number;
    position?: string
  }

  type SurfaceProps = {
    width: number;
    height: number;
    top: number;
    left: number;

    scale?: number;
    enableCSSLayout?: boolean;
  } 

  class Surface extends React.Component<SurfaceProps,{}> {}


  type ComponentProps = {
    style?:Style;

    onTouchStart?: React.TouchEventHandler;
    onTouchMove?: React.TouchEventHandler;
    onTouchEnd?: React.TouchEventHandler;
    onTouchCancel?: React.TouchEventHandler;
    onClick?: React.MouseEventHandler
  }

  class Layer extends React.Component<ComponentProps,{}> {}

  class Group extends React.Component<ComponentProps,{}> {}

  class Text extends React.Component<ComponentProps,{}> { }


  type ImageProps = {
    src: string;
    style?:Style;
    useBackingStore?: boolean;
    fadeIn?: boolean;
    fadeInDuration?: boolean;
  }

  class Image extends React.Component<ImageProps,{}> {}


  class FontFace {
    constructor(family: string, url?: string, attributes?: { style: string; weight: number});
    static Default: FontFace;

    private _fontFaceBrand: any;

    public id: string;
    public family: string;
    public url: string;
    public attributes: string;
  }

  type Measure = {
    width: number;
    height: number;
  }

  function measureText(text: string, width: number, fontFace: FontFace, fontSize: number, lineHeight: number): Measure;

  type ListViewProps = {
      style?: {};
      numberOfItemsGetter: () => number;
      itemHeightGetter: () => number;
      itemGetter: () => Layer;
      snapping?: boolean;
      scrollingDeceleration?: number;
      scrollingPenetrationAcceleration?: number;
      onScroll?: React.EventHandler<React.SyntheticEvent>;
  }

  class ListView extends React.Component<ListViewProps,{}> {

  }
}

RFC: Unit testing

With new pull requests being merged each day, we should look into establishing unit tests and a requirement for all pull requests to have unit tests attached, or we may start to run into regressions.

Did you have test coverage for your internal Flipboard app @mjohnston? Any preferred tooling?

I'm getting a ref error when I try to create a Surface.

This is the console error:

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref.

Here's my code:

'use strict';

var React = require('react');
var $ = require('jquery');
var ReactCanvas = require('react-canvas');
var Surface = ReactCanvas.Surface;
var Image = ReactCanvas.Image;
var Text = ReactCanvas.Text;

var DropGame = React.createClass({

  render: function() {

    return (
        <Surface width={600} height={600} left={0} top={0}>
          <Image src='...' />
          <Text >
            Here is some text below an image.
          </Text>
        </Surface>
    );

  }
});

module.exports = DropGame;

Is there something I'm missing?
Thanks in advance for the help!

impossible to npm start

After a npm install I'm not able to start react-canvas. Below is the terminal output in webstorm and the contents of the npm-debug.log:

SM@SM-MacBook-Pro ~/D/p/x/v/react-canvas> npm start

[email protected] start /Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas
gulp

[08:20:38] Using gulpfile ~/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/gulpfile.js
[08:20:38] Starting 'clean'...
[08:20:38] Finished 'clean' after 3.38 ms
[08:20:38] Starting 'build'...
[08:20:39] Starting 'serve'...
[08:20:40] Finished 'serve' after 245 ms
[08:20:40] Starting 'watch'...
[08:20:40] Finished 'watch' after 7 ms

events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at errnoException (net.js:904:11)
at Server._listen2 (net.js:1042:14)
at listen (net.js:1064:10)
at Server.listen (net.js:1138:5)
at ConnectApp.server (/Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/node_modules/gulp-connect/index.js:57:19)
at new ConnectApp (/Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/node_modules/gulp-connect/index.js:37:10)
at Object.module.exports.server (/Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/node_modules/gulp-connect/index.js:170:12)
at Gulp. (/Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/gulpfile.js:18:11)
at module.exports (/Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:34:7)
at Gulp.Orchestrator._runTask (/Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/node_modules/gulp/node_modules/orchestrator/index.js:273:3)

npm ERR! Darwin 11.4.2
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.10.33
npm ERR! npm v2.1.7
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: gulp
npm ERR! Exit status 8
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the react-canvas package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! gulp
npm ERR! You can get their info via:
npm ERR! npm owner ls react-canvas
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas/npm-debug.log

Here is the npm-debug.log

0 info it worked if it ends with ok
1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info prestart [email protected]
6 info start [email protected]
7 verbose unsafe-perm in lifecycle true
8 info [email protected] Failed to exec start script
9 verbose stack Error: [email protected] start: gulp
9 verbose stack Exit status 8
9 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:212:16)
9 verbose stack at ChildProcess.emit (events.js:98:17)
9 verbose stack at maybeClose (child_process.js:756:16)
9 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:823:5)
10 verbose pkgid [email protected]
11 verbose cwd /Users/SM/Desktop/projects/x5-apex-PROJECTS/varia-SURFACE/react-canvas
12 error Darwin 11.4.2
13 error argv "node" "/usr/local/bin/npm" "start"
14 error node v0.10.33
15 error npm v2.1.7
16 error code ELIFECYCLE
17 error [email protected] start: gulp
17 error Exit status 8
18 error Failed at the [email protected] start script.
18 error This is most likely a problem with the react-canvas package,
18 error not with npm itself.
18 error Tell the author that this fails on your system:
18 error gulp
18 error You can get their info via:
18 error npm owner ls react-canvas
18 error There is likely additional logging output above.
19 verbose exit [ 1, true ]

canvas accessibility

This area needs further exploration. Using fallback content (the canvas DOM sub-tree) should allow screen readers such as VoiceOver to interact with the content. We've seen mixed results with the iOS devices we've tested.

On touch devices for interactive UI you will need to route events on the canvas to the appropriate interactive elements in the sub DOM.

May be helpful: http://www.paciellogroup.com/blog/2015/02/html5-canvas-sub-dom/

Timeline without image

I cloned the repo and the timeline example works fine. I want to have a text only timeline so the same as the example just except the image. But as soon as I remove the image from the timeline example, the scrolling doesn't work anymore. Do I miss something? Do I need to add a Layer instead of the image, or is this a bug?

Browser-ready version

tl;dr
Woah, sorry this turned out to be a longer issue than I expected. I have a solution but it requires manual editing of a compiled file… 👎

Issue:
I’ve been struggling to have a browser drop-in version working (without Node). I updated webpack.config.js accordingly.

I set react in externals so the compiled version looks for React instead of including it when it is required. (React doesn’t handle being required more than once)

In my app:
Uncaught TypeError: Cannot read property 'getPooled' of null: lib/Surface.js#L49

React libs (i.e. invariant & ReactUpdates) are meant to be required when needed (like you guys do) and aren’t defined on the global scope (thus no externals), so when building I let them as-is to be included in dist/react-canvas.js, yet something seems wrong for ReactUpdates.ReactReconcileTransaction is always undefined.

I’m positive that both version of React (my app & the one used to include react/lib/* in the distribution) are the same (0.13.0-rc1).

Teh question:
You who’ve been digging a lot into the core of React, do you see something obvious (or less so) that I’m missing? Is a browser-ready version something you’ve considered?

Hackish solution
I finally have a version that works!

I’ve removed React from my app and bundled it inside dist/react-canvas.js (a little bit like react-with-addons.js). For it to work though, I have to manually (post-building) add window.React = React so that dist/react-canvas.js exposes both React and ReactCanvas

🤘

ListView how to do data loading

My data is ready to roll, how to let the ListView to a certain extent to load the next time, and to adapt to the new data

Demo with Ejecta

This could be a pretty killer option for next-gen non-DOM based hybrid apps when combined with http://impactjs.com/ejecta

I know this is not a real issue but I wasn't sure how to contact you guys :)

npm start error

/usr/src/jigar/nodjswebserver/react-canvas/node_modules/gulp/node_modules/orchestrator/index.js:89
throw new Error('pass strings or arrays of strings');
^
Error: pass strings or arrays of strings
at Gulp.Orchestrator.start (/usr/src/jigar/nodjswebserver/react-canvas/node_modules/gulp/node_modules/orchestrator/index.js:89:12)
at /usr/src/jigar/nodjswebserver/react-canvas/node_modules/gulp/bin/gulp.js:129:20
at process._tickCallback (node.js:355:11)
at Function.Module.runMain (module.js:503:11)
at startup (node.js:129:16)
at node.js:814:3

npm log

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start', '8085' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info prestart [email protected]
6 info start [email protected]
7 verbose unsafe-perm in lifecycle true
8 info [email protected] Failed to exec start script
9 verbose stack Error: [email protected] start: gulp 8085
9 verbose stack Exit status 1
9 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16)
9 verbose stack at EventEmitter.emit (events.js:110:17)
9 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12)
9 verbose stack at ChildProcess.emit (events.js:110:17)
9 verbose stack at maybeClose (child_process.js:1008:16)
9 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1080:5)
10 verbose pkgid [email protected]
11 verbose cwd /usr/src/jigar/nodjswebserver/react-canvas
12 error Linux 3.10.0-123.13.2.el7.x86_64
13 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start" "8085"
14 error node v0.12.0
15 error npm v2.5.1
16 error code ELIFECYCLE
17 error [email protected] start: gulp 8085
17 error Exit status 1
18 error Failed at the [email protected] start script 'gulp 8085'.
18 error This is most likely a problem with the react-canvas package,
18 error not with npm itself.
18 error Tell the author that this fails on your system:
18 error gulp 8085
18 error You can get their info via:
18 error npm owner ls react-canvas
18 error There is likely additional logging output above.
19 verbose exit [ 1, true ]
~

[Performance]: Bitmap Layer Cache

Shouldn't the Bitmap Layer Cache be an LRU aswell ? (make a common cache instead for Image and any other cacheble quantity ?)

A use case :

Suppose my background layer is rendered one using a bunch of circles and shapes that i rendered on the fly or like iOS 7 style frosty-blur, doing it one time is quite expensive (despite scaling), I'd to keep it cached now if multiple objects come and go on the top of the screen ultimately the background will be thrashed first.. which is bad, though this is just an edge case but if we use LRU for ImageCache why not keep this on the same ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.