Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtual Canvas ⚙️ #21

Merged
merged 9 commits into from
Oct 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/smart-render.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
id: smart-render
title: Smart Render
sidebar_label: Smart Render (reflect)
---

# Virtual Canvas

React Ape use an render algorithm called Virtual Canvas.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"canvas-prebuilt": "^1.6.5-prerelease.1",
"chalk": "^2.4.1",
"docusaurus": "^1.3.3",
"flow-bin": "^0.76.0",
"flow-bin": "^0.80.0",
"flow-typed": "^2.5.1",
"glob": "^7.1.2",
"google-closure-compiler": "20180506.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/example-movie-list/.babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"presets":[
"env", "react"
"env", "react", "flow"
]
}
3 changes: 2 additions & 1 deletion packages/example-movie-list/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
    <meta charset="UTF-8">
    <title>Movie List with React Ape</title>
<style>
/*
body {
background: #262626;
}

*/
canvas {
width: 100%;
height: 100%;
Expand Down
3 changes: 2 additions & 1 deletion packages/example-movie-list/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"scripts": {
"build": "NODE_ENV=production webpack",
"dev": "webpack-dev-server --progress --colors"
"start": "webpack-dev-server --progress --colors"
},
"dependencies": {
"react": "^16.4.1"
Expand All @@ -16,6 +16,7 @@
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"babel-preset-flow": "^7.0.0-beta.3",
"uglifyjs-webpack-plugin": "^1.0.1",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.4"
Expand Down
62 changes: 45 additions & 17 deletions packages/example-movie-list/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ListView,
View,
Image,
Tools,
StyleSheet,
dimensions,
} from '../../react-ape/reactApeEntry';
Expand All @@ -14,6 +15,11 @@ import {
*/

const styles = StyleSheet.create({
surface: {
backgroundColor: '#202020',
width: dimensions.getWidth(),
height: dimensions.getHeight(),
},
heading: {
top: 62,
left: 250,
Expand All @@ -34,14 +40,6 @@ const styles = StyleSheet.create({
top: 10,
left: 30,
},
infoAboutRenderer: {
top: 590,
left: 30,
fontFamily: 'Arial',
fontWeight: 'bold',
color: 'lightblue',
fontSize: 23,
},
list: {
top: 100,
left: 0,
Expand Down Expand Up @@ -81,13 +79,7 @@ class App extends React.Component {

renderPostersList() {
const renderRow = (data, idx) => (
<View
height={200}
width={200}
key={'poster-list-' + idx}
onClick={() => {
console.log(data);
}}>
<View height={200} width={200} key={'poster-list-' + idx}>
<Image
style={{x: 220 * idx + 30, y: 140, width: 200, height: 300}}
src={data.src}
Expand All @@ -109,7 +101,7 @@ class App extends React.Component {

render() {
return (
<View>
<View style={styles.surface}>
<Image
src={'posters/netflix.png'}
style={styles.logo}
Expand All @@ -118,11 +110,47 @@ class App extends React.Component {
/>
<Text style={styles.heading}>• React Ape Originals</Text>
<Text style={styles.time}>{this.state.time}</Text>
<Text style={styles.infoAboutRenderer}>Link to GitHub</Text>
{this.renderPostersList()}
</View>
);
}
}

// class App extends React.Component {
// constructor() {
// super();
// this.state = {
// time: new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1'),
// };
// }

// componentDidMount() {
// setInterval(() => {
// const time = new Date()
// .toTimeString()
// .replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1');
// this.setState({time});
// }, 100);
// }

// render() {
// return (
// <View>
// <Tools.Grid/>
// <Image
// src={'posters/netflix.png'}
// style={{top: 10, left: 30}}
// width={210}
// height={100}
// />
// <View style={{backgroundColor: 'purple', height: 80, width: 280, x: 500, y: 220}}>
// <Text style={{x: 520, y: 260, color: 'white', fontSize: 60}}>{this.state.time}</Text>
// </View>
// <Text style={{x: 500, y: 190, color: 'black'}}>{this.state.time}</Text>
// <Text style={{x: 500, y: 360}}>This TextNode should not render again</Text>
// </View>
// );
// }
// }

render(<App />, document.getElementById('root'));
4 changes: 3 additions & 1 deletion packages/example-movie-list/webpack.config.babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

const sourcePath = path.join(__dirname, 'src');
const reactApePath = path.join(__dirname, '../react-ape');

const config = {
entry: ['babel-polyfill', path.resolve(sourcePath, 'App.js')],
Expand All @@ -14,6 +15,7 @@ const config = {
extensions: ['.js', '.jsx'],
modules: [
sourcePath,
reactApePath,
path.resolve(__dirname, 'node_modules'),
// yarn-workspaces
path.resolve(__dirname, '../../node_modules'),
Expand All @@ -25,7 +27,7 @@ const config = {
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
include: sourcePath,
include: [reactApePath, sourcePath],
},
],
},
Expand Down
32 changes: 19 additions & 13 deletions packages/react-ape/__tests__/render-text-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,21 @@ import React from 'react';
import {render, View, Text, StyleSheet} from '../reactApeEntry';

import ViewElement from '../renderer/elements/View';
import TextElement from '../renderer/elements/Text';
import createTextElement from '../renderer/elements/Text';

describe('render', () => {
describe('<Text/>', () => {
// let originalTimeout;

// beforeEach(function() {
// originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
// jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
// });

// afterEach(function() {
// jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
// });

// this test should not change
it('renders only <Text/> correctly', () => {
const canvas = document.createElement('canvas');
Expand Down Expand Up @@ -46,9 +57,7 @@ describe('render', () => {
const expectedCanvas = document.createElement('canvas');

const view = new ViewElement({style: styles.view});
view.appendChild(
TextElement.bind(this, {children: 'Text with Defaults'})
);
view.appendChild(createTextElement({children: 'Text with Defaults'}));
view.render({ctx: expectedCanvas.getContext('2d')});

render(App, canvas);
Expand Down Expand Up @@ -77,10 +86,7 @@ describe('render', () => {

const view = new ViewElement({style: styles.view});
view.appendChild(
TextElement.bind(this, {
children: 'My amazing text',
style: styles.text,
})
createTextElement({children: 'My amazing text', style: styles.text})
);
view.render({ctx: expectedCanvas.getContext('2d')});

Expand Down Expand Up @@ -115,7 +121,7 @@ describe('render', () => {

const view = new ViewElement({style: styles.view});
view.appendChild(
TextElement.bind(this, {
createTextElement({
children: 'Other Text',
style: styles.text,
})
Expand All @@ -136,7 +142,7 @@ describe('render', () => {
const expectedCanvas = document.createElement('canvas');

const view = new ViewElement({style: styles.view});
view.appendChild(TextElement.bind(this, {}));
view.appendChild(createTextElement({}));
view.render({ctx: expectedCanvas.getContext('2d')});

const App = (
Expand All @@ -149,7 +155,7 @@ describe('render', () => {
expect(canvas.toDataURL()).toEqual(expectedCanvas.toDataURL());
});

it('renders <Text/> with state', done => {
it.skip('renders <Text/> with state', done => {
const styles = StyleSheet.create({
view: {
backgroundColor: 'black',
Expand Down Expand Up @@ -185,7 +191,7 @@ describe('render', () => {
const updatedCanvas = document.createElement('canvas');
const newView = new ViewElement({style: styles.view});
newView.appendChild(
TextElement.bind(this, {
createTextElement({
children: formatDate(nextDate),
style: styles.text,
})
Expand All @@ -208,7 +214,7 @@ describe('render', () => {

const view = new ViewElement({style: styles.view});
view.appendChild(
TextElement.bind(this, {
createTextElement({
children: formatDate(date),
style: styles.text,
})
Expand Down
24 changes: 20 additions & 4 deletions packages/react-ape/modules/dimensions/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
/**
* Copyright (c) 2018-present, Raphael Amorim.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

function getWidth() {
if (window && window.innerWidth) {
return window.innerWidth;
if (window || document) {
return (
(window || {}).innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth
);
}
}

function getHeight() {
if (window && window.innerHeight) {
return window.innerHeight;
if (window || document) {
return (
(window || {}).innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/react-ape/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-ape",
"version": "0.0.6",
"version": "0.0.7",
"description": "React Renderer to build interfaces using canvas/WebGL",
"main": "index.js",
"peerDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions packages/react-ape/reactApeEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export const render = ReactApeRenderer.render;
export const Image = 'Image';
export const View = 'View';
export const Text = 'Text';
export const Tools = {
Grid: 'CanvasGrid',
};

export const StyleSheet = StyleSheetModule;
export const dimensions = DimensionsModule;
Expand Down
7 changes: 7 additions & 0 deletions packages/react-ape/renderer/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@
export const View = 'View';
export const Image = 'Image';
export const Text = 'Text';
export const CanvasGrid = 'CanvasGrid';

// Defaults for Render
export const defaultViewSize = 200; // 200x200

// ReactApe Internal Constants
export const _SectionBlockSize = 80; // 80x80
11 changes: 11 additions & 0 deletions packages/react-ape/renderer/core/debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// function debug() {
// if (process.env.NODE_ENV) {
// console.log
// }
// }

// if (process.env.NODE_ENV) {
// window.ReactApe = {};
// }

// export default debug;
Loading