├── README.md ├── demo.gif ├── index.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | ![demo](https://raw.githubusercontent.com/expo/expo-processing/master/demo.gif "demo") 2 | 3 | *NOTE: GIF above looks weird some times because it's a GIF, the real thing is nice, I promise...* 4 | 5 | # expo-processing 6 | 7 | Use [Processing.js](http://processingjs.org) on [Expo](https://expo.io)! Just 8 | `npm i -S processing-js expo-processing` in your Expo project and import it with 9 | `import { ProcessingView } from 'expo-processing;`. 10 | 11 | ## Components 12 | 13 | ### `ExpoProcessing.ProcessingView` 14 | 15 | Display a `Processing.js` sketch. 16 | 17 | #### Props 18 | 19 | The component accepts all `View` layout props for specifying its layout. 20 | 21 | - `sketch`: A Processing.js sketch function that takes a `processing` instance 22 | and calls Processing.js functions on it, such as the [`sketchProc` function](http://processingjs.org/articles/jsQuickStart.html#javascriptonlyprocessingcode) in 23 | the Processing.js documentation for writing JavaScript-only Processing.js 24 | code. 25 | 26 | ## Example 27 | 28 | This is based on 29 | the ["In and out"](https://www.openprocessing.org/sketch/434617) sketch on 30 | OpenProcessing.org. 31 | 32 | In 33 | a 34 | [new blank Expo project](https://docs.expo.io/versions/latest/get-started/installation/), 35 | run `expo install processing-js expo-processing expo-gl` to install Processing.js and ExpoProcessing. Then replace 36 | `App.js` with the following: 37 | 38 | ```js 39 | import React from "react"; 40 | import { ProcessingView } from "expo-processing"; 41 | 42 | export default class App extends React.Component { 43 | render() { 44 | return ; 45 | } 46 | 47 | _sketch = p => { 48 | p.setup = () => { 49 | p.strokeWeight(7); 50 | }; 51 | 52 | const harom = (ax, ay, bx, by, level, ratio) => { 53 | if (level <= 0) { 54 | return; 55 | } 56 | 57 | const vx = bx - ax; 58 | const vy = by - ay; 59 | const nx = p.cos(p.PI / 3) * vx - p.sin(p.PI / 3) * vy; 60 | const ny = p.sin(p.PI / 3) * vx + p.cos(p.PI / 3) * vy; 61 | const cx = ax + nx; 62 | const cy = ay + ny; 63 | p.line(ax, ay, bx, by); 64 | p.line(ax, ay, cx, cy); 65 | p.line(cx, cy, bx, by); 66 | 67 | harom( 68 | ax * ratio + cx * (1 - ratio), 69 | ay * ratio + cy * (1 - ratio), 70 | ax * (1 - ratio) + bx * ratio, 71 | ay * (1 - ratio) + by * ratio, 72 | level - 1, 73 | ratio 74 | ); 75 | }; 76 | 77 | p.draw = () => { 78 | p.background(240); 79 | harom( 80 | p.width - 142, 81 | p.height - 142, 82 | 142, 83 | p.height - 142, 84 | 6, 85 | (p.sin((0.0005 * Date.now()) % (2 * p.PI)) + 1) / 2 86 | ); 87 | }; 88 | }; 89 | } 90 | ```` 91 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/expo-processing/6d9094d8c1e7cb5af3085e7c3d66c32ce3dbf970/demo.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { GLView } from 'expo-gl'; 3 | 4 | const Browser = require('processing-js/lib/Browser'); 5 | Browser.window = window; 6 | const Processing = require('processing-js/src')(Browser); 7 | 8 | export class ProcessingView extends React.Component { 9 | componentWillUnmount() { 10 | if (this._p) { 11 | this._p.exit(); 12 | this._p = null; 13 | } 14 | } 15 | 16 | render() { 17 | return ( 18 | 22 | ); 23 | } 24 | 25 | _onGLContextCreate = (gl) => { 26 | // Canvas polyfilling 27 | 28 | let canvas = Browser.document.createElement('canvas'); 29 | 30 | canvas.getContext = () => gl; 31 | 32 | // Cache uniform and attrib locations 33 | 34 | const origGetUniformLocation = gl.getUniformLocation; 35 | gl.getUniformLocation = (program, name) => { 36 | if (!program.uniformLocationCache) { 37 | program.uniformLocationCache = {}; 38 | } 39 | let loc = program.uniformLocationCache[name]; 40 | if (loc !== undefined) { 41 | return loc; 42 | } 43 | loc = origGetUniformLocation.call(gl, program, name); 44 | program.uniformLocationCache[name] = loc; 45 | return loc; 46 | } 47 | 48 | const origGetAttribLocation = gl.getAttribLocation; 49 | gl.getAttribLocation = (program, name) => { 50 | if (!program.attribLocationCache) { 51 | program.attribLocationCache = {}; 52 | } 53 | let loc = program.attribLocationCache[name]; 54 | if (loc !== undefined) { 55 | return loc; 56 | } 57 | loc = origGetAttribLocation.call(gl, program, name); 58 | program.attribLocationCache[name] = loc; 59 | return loc; 60 | } 61 | 62 | 63 | // Call `gl.endFrameEXP()` every frame 64 | 65 | const keepFlushing = () => { 66 | gl.endFrameEXP(); 67 | requestAnimationFrame(keepFlushing); 68 | } 69 | keepFlushing(); 70 | 71 | 72 | // The Processing sketch 73 | 74 | new Processing(canvas, (p) => { 75 | this._p = p; 76 | 77 | // Force render viewport size / mode 78 | p.size( 79 | gl.drawingBufferWidth, 80 | gl.drawingBufferHeight, 81 | p.WEBGL); 82 | p.size = () => {}; 83 | 84 | // Run user's sketch 85 | if (this.props.sketch) { 86 | this.props.sketch(p); 87 | } else { 88 | p.draw = () => {}; 89 | } 90 | }); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-processing", 3 | "version": "2.0.1", 4 | "description": "Utilities for using Processing.js on Expo", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "github.com/expo/expo-processing" 12 | }, 13 | "keywords": [ 14 | "expo", 15 | "processing.js", 16 | "graphics", 17 | "opengl", 18 | "gl" 19 | ], 20 | "author": "Nikhilesh Sigatapu", 21 | "license": "MIT", 22 | "peerDependencies": { 23 | "processing-js": "^1.6.6", 24 | "expo-gl": "*" 25 | } 26 | } 27 | --------------------------------------------------------------------------------