mirror of
https://github.com/gre/gl-react.git
synced 2026-01-25 16:43:36 +00:00
commit
8590e3cd2b
20
package.json
20
package.json
@ -17,17 +17,17 @@
|
||||
"publish": "yarn && lerna run clean && yarn build && lerna publish --registry=https://registry.npmjs.org/"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.3",
|
||||
"@babel/preset-flow": "^7.8.3",
|
||||
"@babel/preset-react": "^7.8.3",
|
||||
"browserify": "^16.5.0",
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.12.1",
|
||||
"@babel/preset-env": "^7.12.11",
|
||||
"@babel/preset-flow": "^7.12.1",
|
||||
"@babel/preset-react": "^7.12.10",
|
||||
"browserify": "^17.0.0",
|
||||
"browserify-shim": "^3.8.12",
|
||||
"documentation": "12.1.4",
|
||||
"documentation": "13.1.0",
|
||||
"flow-copy-source": "^2.0.9",
|
||||
"lerna": "^3.20.2",
|
||||
"prettier": "^1.19.1"
|
||||
"lerna": "^3.22.1",
|
||||
"prettier": "^2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,39 +3,41 @@
|
||||
"version": "4.0.1",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"babel-preset-react-app": "^9.1.0",
|
||||
"raw-loader": "^3.1.0",
|
||||
"react-scripts": "3"
|
||||
"babel-preset-react-app": "^10.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"documentation": "13.1.0",
|
||||
"raw-loader": "4.0.2",
|
||||
"react-scripts": "4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"animated": "^0.2.0",
|
||||
"github-slugger": "^1.2.1",
|
||||
"github-slugger": "^1.3.0",
|
||||
"gl-react": "^4.0.1",
|
||||
"gl-react-dom": "^4.0.1",
|
||||
"gl-shader": "^4.2.1",
|
||||
"gl-texture2d": "^2.1.0",
|
||||
"gl-transitions": "^1.43.0",
|
||||
"hoist-non-react-statics": "^3.3.1",
|
||||
"lodash": "^4.17.15",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"lodash": "^4.17.20",
|
||||
"ndarray": "^1.0.19",
|
||||
"ndarray-ops": "^1.2.2",
|
||||
"prism-theme-one-dark": "^1.0.0",
|
||||
"prismjs": "github:PrismJS/prism#16ce4b336d625e13065bfc12ab6d13ac862d6f50",
|
||||
"prop-types": "^15.7.2",
|
||||
"query-string": "^6.10.1",
|
||||
"query-string": "^6.13.7",
|
||||
"raf": "^3.4.1",
|
||||
"react": "^16.12.0",
|
||||
"react-color": "^2.18.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react": "^17.0.1",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-gl-transition": "^1.19.2",
|
||||
"react-json2d": "^0.3.0",
|
||||
"react-motion": "^0.5.0",
|
||||
"react-prism": "^4.0.0",
|
||||
"react-router": "^5.1.2",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-sidebar": "^3.0.2",
|
||||
"remark": "^11.0.2",
|
||||
"remark-react": "^6.0.0"
|
||||
"remark": "11",
|
||||
"remark-react": "6"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
a:hover, a:focus {
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: inherit;
|
||||
}
|
||||
.menu {
|
||||
@ -40,7 +41,7 @@ a:hover, a:focus {
|
||||
.App > header {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flexDirection: row;
|
||||
flexdirection: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #000;
|
||||
@ -68,13 +69,13 @@ a:hover, a:focus {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.App > header .logo .t1 {
|
||||
color: #E24;
|
||||
color: #e24;
|
||||
}
|
||||
.App > header .logo .t2 {
|
||||
color: #000;
|
||||
}
|
||||
.App > header .logo .t3 {
|
||||
color: #E24;
|
||||
color: #e24;
|
||||
}
|
||||
.App > header .logo .v {
|
||||
font-weight: normal;
|
||||
@ -108,7 +109,8 @@ a:hover, a:focus {
|
||||
.App > header select {
|
||||
margin: 0 20px;
|
||||
}
|
||||
a.left, a.right {
|
||||
a.left,
|
||||
a.right {
|
||||
font-size: 1.6em;
|
||||
padding: 0.6em 0.4em;
|
||||
background: #fff;
|
||||
@ -118,7 +120,8 @@ a.left, a.right {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
a.left:hover, a.right:hover {
|
||||
a.left:hover,
|
||||
a.right:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
a.left {
|
||||
@ -174,7 +177,6 @@ a.right {
|
||||
padding: 10px 0;
|
||||
}
|
||||
.desc em {
|
||||
|
||||
}
|
||||
.desc pre {
|
||||
display: inline-block;
|
||||
|
||||
@ -16,7 +16,8 @@ import Dashboard from "./Dashboard";
|
||||
|
||||
const conf = {
|
||||
version: process.env.REACT_APP_GL_VERSION,
|
||||
githubprefix: "https://github.com/gre/gl-react/tree/master/packages/cookbook/"
|
||||
githubprefix:
|
||||
"https://github.com/gre/gl-react/tree/master/packages/cookbook/",
|
||||
};
|
||||
|
||||
function triggerLink(linkRef) {
|
||||
@ -28,7 +29,7 @@ const lenseSidebar = ({ location }) => {
|
||||
const { menu, inspector } = queryString.parse(location.search);
|
||||
return {
|
||||
menu,
|
||||
inspector
|
||||
inspector,
|
||||
};
|
||||
};
|
||||
|
||||
@ -36,7 +37,7 @@ class MenuContext extends PureComponent<*> {
|
||||
props: {
|
||||
menu: boolean,
|
||||
inspector: boolean,
|
||||
currentExample: ?Object
|
||||
currentExample: ?Object,
|
||||
};
|
||||
render() {
|
||||
const { menu, inspector } = this.props;
|
||||
@ -45,12 +46,12 @@ class MenuContext extends PureComponent<*> {
|
||||
<div>
|
||||
<h3>{all.length} Examples</h3>
|
||||
<ul>
|
||||
{all.map(key => (
|
||||
{all.map((key) => (
|
||||
<li key={key}>
|
||||
<NavLink
|
||||
to={{
|
||||
pathname: "/" + key,
|
||||
search: queryString.stringify({ menu, inspector })
|
||||
search: queryString.stringify({ menu, inspector }),
|
||||
}}
|
||||
activeClassName="active"
|
||||
className="example-link"
|
||||
@ -71,7 +72,7 @@ class Header extends Component<*> {
|
||||
props: {
|
||||
currentExample: ?Object,
|
||||
toToggleMenu: Object,
|
||||
toToggleInspector: Object
|
||||
toToggleInspector: Object,
|
||||
};
|
||||
render() {
|
||||
const { currentExample, toToggleMenu, toToggleInspector } = this.props;
|
||||
@ -115,10 +116,7 @@ class Header extends Component<*> {
|
||||
|
||||
class App extends Component<*> {
|
||||
props: {
|
||||
location: Object
|
||||
};
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired
|
||||
location: Object,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@ -185,16 +183,16 @@ class App extends Component<*> {
|
||||
search: queryString.stringify({
|
||||
...query,
|
||||
menu: !menuOpened ? true : undefined,
|
||||
...(!menuOpened ? { inspector: undefined } : null)
|
||||
})
|
||||
...(!menuOpened ? { inspector: undefined } : null),
|
||||
}),
|
||||
}}
|
||||
toToggleInspector={{
|
||||
pathname: location.pathname,
|
||||
search: queryString.stringify({
|
||||
...query,
|
||||
inspector: !inspectorOpened ? true : undefined,
|
||||
...(!inspectorOpened ? { menu: undefined } : null)
|
||||
})
|
||||
...(!inspectorOpened ? { menu: undefined } : null),
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -204,7 +202,7 @@ class App extends Component<*> {
|
||||
className="left"
|
||||
to={{
|
||||
pathname: prev,
|
||||
search: queryString.stringify({ menu, inspector })
|
||||
search: queryString.stringify({ menu, inspector }),
|
||||
}}
|
||||
>
|
||||
❮
|
||||
@ -217,7 +215,7 @@ class App extends Component<*> {
|
||||
className="right"
|
||||
to={{
|
||||
pathname: next,
|
||||
search: queryString.stringify({ menu, inspector })
|
||||
search: queryString.stringify({ menu, inspector }),
|
||||
}}
|
||||
>
|
||||
❯
|
||||
@ -227,12 +225,12 @@ class App extends Component<*> {
|
||||
<div className="container">
|
||||
<Switch>
|
||||
<Route path="/" exact component={Dashboard} />
|
||||
{Object.keys(examples).map(key => (
|
||||
{Object.keys(examples).map((key) => (
|
||||
<Route
|
||||
path={"/" + key}
|
||||
key={key}
|
||||
isExample
|
||||
render={props => (
|
||||
render={(props) => (
|
||||
<ExamplePage example={examples[key]} {...props} />
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -2,7 +2,7 @@ pre.cookbook-code a {
|
||||
color: inherit;
|
||||
}
|
||||
pre.cookbook-code .js-template-string-glsl {
|
||||
background: rgba(0,0,0,0.3);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
padding: 4px 8px;
|
||||
display: block;
|
||||
max-height: 65vh;
|
||||
|
||||
@ -19,24 +19,22 @@ Prism.languages.insertBefore("jsx", "string", {
|
||||
"js-template-string-glsl": {
|
||||
pattern: /[^`]*/,
|
||||
inside: {
|
||||
rest: Prism.languages.glsl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rest: Prism.languages.glsl,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default class Code extends PureComponent {
|
||||
props: {
|
||||
children?: any
|
||||
children?: any,
|
||||
};
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
return (
|
||||
<pre className="cookbook-code">
|
||||
<PrismCode className="language-jsx">
|
||||
{children}
|
||||
</PrismCode>
|
||||
<PrismCode className="language-jsx">{children}</PrismCode>
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
|
||||
@ -30,13 +30,15 @@
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
.dashboard .showcode, .dashboard .showunderthehood {
|
||||
.dashboard .showcode,
|
||||
.dashboard .showunderthehood {
|
||||
opacity: 0.5;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
font-size: 10px;
|
||||
}
|
||||
.dashboard .showcode:hover, .dashboard .showunderthehood:hover {
|
||||
.dashboard .showcode:hover,
|
||||
.dashboard .showunderthehood:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.dashboard .showcode {
|
||||
|
||||
@ -20,7 +20,7 @@ void main () {
|
||||
texture2D(backbuffer, uv),
|
||||
persistence
|
||||
).rgb, 1.0);
|
||||
}`
|
||||
}`,
|
||||
},
|
||||
HelloGL: {
|
||||
// uniforms are variables from JS. We pipe blue uniform into blue output color
|
||||
@ -30,7 +30,7 @@ varying vec2 uv;
|
||||
uniform float red;
|
||||
void main() {
|
||||
gl_FragColor = vec4(red, uv.x, uv.y, 1.0);
|
||||
}`
|
||||
}`,
|
||||
},
|
||||
Rotate: {
|
||||
frag: GLSL`
|
||||
@ -45,8 +45,8 @@ void main() {
|
||||
p.x < 0.0 || p.x > 1.0 || p.y < 0.0 || p.y > 1.0
|
||||
? vec4(0.0)
|
||||
: texture2D(children, p);
|
||||
}`
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const MotionBlur = ({ children, persistence }) => (
|
||||
@ -60,7 +60,7 @@ const MotionBlur = ({ children, persistence }) => (
|
||||
// We can make a <HelloBlue blue={0.5} /> that will render the concrete <Node/>
|
||||
class HelloGL extends Component {
|
||||
props: {
|
||||
red: number
|
||||
red: number,
|
||||
};
|
||||
render() {
|
||||
const { red } = this.props;
|
||||
@ -72,7 +72,7 @@ class Rotate extends Component {
|
||||
props: {
|
||||
scale: number,
|
||||
angle: number,
|
||||
children: any
|
||||
children: any,
|
||||
};
|
||||
render() {
|
||||
const { angle, scale, children } = this.props;
|
||||
@ -86,7 +86,7 @@ class Ex1 extends Component {
|
||||
props: { time: number };
|
||||
state = {
|
||||
showCode: false,
|
||||
showInspector: false
|
||||
showInspector: false,
|
||||
};
|
||||
onShowCode = () => {
|
||||
this.setState({ showCode: true });
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
|
||||
gl-react API documentation
|
||||
==========================
|
||||
# gl-react API documentation
|
||||
|
||||
`gl-react` is a [React](https://facebook.github.io/react/) library to write and compose WebGL shaders.
|
||||
|
||||
|
||||
@ -12,16 +12,19 @@ import API from "../API.json";
|
||||
import DocIntroMDBase64 from "../DocIntro.md";
|
||||
|
||||
const mdheader = "data:text/x-markdown;base64,";
|
||||
const DocIntroMD = DocIntroMDBase64.indexOf(mdheader) === 0
|
||||
? atob(DocIntroMDBase64.slice(mdheader.length))
|
||||
: "";
|
||||
const DocIntroMD =
|
||||
DocIntroMDBase64.indexOf(mdheader) === 0
|
||||
? atob(DocIntroMDBase64.slice(mdheader.length))
|
||||
: "";
|
||||
|
||||
const paths = {
|
||||
Component: "https://facebook.github.io/react/docs/react-component.html",
|
||||
WebGLRenderingContext: "https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14",
|
||||
WebGLContextAttributes: "https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2"
|
||||
WebGLRenderingContext:
|
||||
"https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14",
|
||||
WebGLContextAttributes:
|
||||
"https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2",
|
||||
};
|
||||
API.forEach(doc => {
|
||||
API.forEach((doc) => {
|
||||
paths[doc.name] = "#" + slug(doc.name);
|
||||
});
|
||||
|
||||
@ -69,7 +72,7 @@ function visit(tree, type, visitor, reverse) {
|
||||
}
|
||||
|
||||
function rerouteLinks(ast) {
|
||||
visit(ast, "link", function(node) {
|
||||
visit(ast, "link", function (node) {
|
||||
if (
|
||||
node.jsdoc &&
|
||||
!node.url.match(/^(http|https|\.)/) &&
|
||||
@ -208,7 +211,7 @@ function parameters(section, short) {
|
||||
.concat(
|
||||
section.params.map((param, i) => [
|
||||
i === 0 ? "" : ", ",
|
||||
parameter(param, short)
|
||||
parameter(param, short),
|
||||
])
|
||||
)
|
||||
.concat([")"]);
|
||||
@ -232,7 +235,7 @@ function md(ast, inline) {
|
||||
) {
|
||||
ast = {
|
||||
type: "root",
|
||||
children: ast.children[0].children.concat(ast.children.slice(1))
|
||||
children: ast.children[0].children.concat(ast.children.slice(1)),
|
||||
};
|
||||
}
|
||||
if (ast) ast = rerouteLinks(ast);
|
||||
@ -259,7 +262,9 @@ function signature(section) {
|
||||
}
|
||||
|
||||
function isReactComponent(section) {
|
||||
return section.augments && section.augments.some(a => a.name === "Component");
|
||||
return (
|
||||
section.augments && section.augments.some((a) => a.name === "Component")
|
||||
);
|
||||
}
|
||||
|
||||
function shortSignature(section) {
|
||||
@ -267,13 +272,13 @@ function shortSignature(section) {
|
||||
if (section.kind === "class") {
|
||||
if (isReactComponent(section)) {
|
||||
const props = (section.properties || [])
|
||||
.filter(p => p.type && p.type.type !== "OptionalType")
|
||||
.map(p => p.name);
|
||||
.filter((p) => p.type && p.type.type !== "OptionalType")
|
||||
.map((p) => p.name);
|
||||
const attrs = props
|
||||
.filter(name => name !== "children")
|
||||
.map(name => " " + name + "={..}")
|
||||
.filter((name) => name !== "children")
|
||||
.map((name) => " " + name + "={..}")
|
||||
.join("");
|
||||
const hasChildren = props.some(name => name === "children");
|
||||
const hasChildren = props.some((name) => name === "children");
|
||||
return (
|
||||
"<" +
|
||||
section.name +
|
||||
@ -301,9 +306,7 @@ class DocSectionList extends PureComponent {
|
||||
{members.map((member, i) => (
|
||||
<div key={i} className="member" id={member.namespace}>
|
||||
<div className="member-title">
|
||||
<code>
|
||||
.{signature(member)}
|
||||
</code>
|
||||
<code>.{signature(member)}</code>
|
||||
</div>
|
||||
<DocSection section={member} nested />
|
||||
</div>
|
||||
@ -321,41 +324,37 @@ class DocSection extends PureComponent {
|
||||
id={slug(section.namespace)}
|
||||
className={"section " + (nested ? "nested" : "")}
|
||||
>
|
||||
{!nested || (section.context && section.context.github)
|
||||
? <div>
|
||||
{!nested
|
||||
? <h3>
|
||||
<a href={"#" + slug(section.namespace)}>{section.name}</a>
|
||||
{!nested || (section.context && section.context.github) ? (
|
||||
<div>
|
||||
{!nested ? (
|
||||
<h3>
|
||||
<a href={"#" + slug(section.namespace)}>{section.name}</a>
|
||||
|
||||
{section.augments ? (
|
||||
<span className="augments">
|
||||
extends
|
||||
{section.augments
|
||||
? <span className="augments">
|
||||
extends
|
||||
{section.augments
|
||||
? section.augments.map((tag, i) => (
|
||||
<span key={i}>
|
||||
{i === 0 ? "" : ", "}
|
||||
{autolink(tag.name)}
|
||||
</span>
|
||||
))
|
||||
: null}
|
||||
</span>
|
||||
? section.augments.map((tag, i) => (
|
||||
<span key={i}>
|
||||
{i === 0 ? "" : ", "}
|
||||
{autolink(tag.name)}
|
||||
</span>
|
||||
))
|
||||
: null}
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
{section.context && section.context.github
|
||||
? <a
|
||||
className="github-link"
|
||||
href={section.context.github}
|
||||
>
|
||||
{section.context.path}
|
||||
</a>
|
||||
: null}
|
||||
</h3>
|
||||
: null}
|
||||
{section.context && section.context.github ? (
|
||||
<a className="github-link" href={section.context.github}>
|
||||
{section.context.path}
|
||||
</a>
|
||||
) : null}
|
||||
</h3>
|
||||
) : null}
|
||||
|
||||
{!nested ? highlight(shortSignature(section)) : null}
|
||||
|
||||
</div>
|
||||
: null}
|
||||
{!nested ? highlight(shortSignature(section)) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{md(section.description)}
|
||||
|
||||
@ -365,67 +364,75 @@ class DocSection extends PureComponent {
|
||||
{section.copyright ? <div>Copyright: {section.copyright}</div> : null}
|
||||
{section.since ? <div>Since: {section.since}</div> : null}
|
||||
|
||||
{section.params
|
||||
? <div>
|
||||
<h4>Parameters</h4>
|
||||
<div>
|
||||
{section.params.map((param, i) => (
|
||||
<div key={i}>
|
||||
<div>
|
||||
<strong><code>{param.name}</code></strong>
|
||||
<code className="type">
|
||||
({formatType(param.type)}
|
||||
{param.default
|
||||
? <span>(default <code>{param.default}</code>)</span>
|
||||
: null}
|
||||
)
|
||||
</code>
|
||||
{md(param.description, true)}
|
||||
</div>
|
||||
{section.params ? (
|
||||
<div>
|
||||
<h4>Parameters</h4>
|
||||
<div>
|
||||
{section.params.map((param, i) => (
|
||||
<div key={i}>
|
||||
<div>
|
||||
<strong>
|
||||
<code>{param.name}</code>
|
||||
</strong>
|
||||
|
||||
<code className="type">
|
||||
({formatType(param.type)}
|
||||
{param.default ? (
|
||||
<span>
|
||||
(default <code>{param.default}</code>)
|
||||
</span>
|
||||
) : null}
|
||||
)
|
||||
</code>
|
||||
{md(param.description, true)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
: null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{section.properties
|
||||
? <div>
|
||||
<h4>
|
||||
{isReactComponent(section) ? "Props" : "Properties"}
|
||||
</h4>
|
||||
<ul className="props">
|
||||
{section.properties.map((property, i) => (
|
||||
<li key={i} className="prop">
|
||||
<strong><code>{property.name}</code></strong>
|
||||
<code className="type">({formatType(property.type)})</code>
|
||||
{property.default
|
||||
? <span>(default <code>{property.default}</code>)</span>
|
||||
: null}
|
||||
{property.description
|
||||
? [": ", md(property.description, true)]
|
||||
: null}
|
||||
{property.properties
|
||||
? <ul>
|
||||
{property.properties.map((property, i) => (
|
||||
<li key={i}>
|
||||
<code>{property.name}</code>
|
||||
|
||||
{formatType(property.type)}
|
||||
{property.default
|
||||
? <span>
|
||||
(default <code>{property.default}</code>)
|
||||
</span>
|
||||
: null}
|
||||
{md(property.description)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
: null}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
: null}
|
||||
{section.properties ? (
|
||||
<div>
|
||||
<h4>{isReactComponent(section) ? "Props" : "Properties"}</h4>
|
||||
<ul className="props">
|
||||
{section.properties.map((property, i) => (
|
||||
<li key={i} className="prop">
|
||||
<strong>
|
||||
<code>{property.name}</code>
|
||||
</strong>
|
||||
|
||||
<code className="type">({formatType(property.type)})</code>
|
||||
{property.default ? (
|
||||
<span>
|
||||
(default <code>{property.default}</code>)
|
||||
</span>
|
||||
) : null}
|
||||
{property.description
|
||||
? [": ", md(property.description, true)]
|
||||
: null}
|
||||
{property.properties ? (
|
||||
<ul>
|
||||
{property.properties.map((property, i) => (
|
||||
<li key={i}>
|
||||
<code>{property.name}</code>
|
||||
|
||||
{formatType(property.type)}
|
||||
{property.default ? (
|
||||
<span>
|
||||
(default <code>{property.default}</code>)
|
||||
</span>
|
||||
) : null}
|
||||
{md(property.description)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{section.returns
|
||||
? section.returns.map((ret, i) => (
|
||||
@ -437,59 +444,59 @@ class DocSection extends PureComponent {
|
||||
))
|
||||
: null}
|
||||
|
||||
{section.throws
|
||||
? <div>
|
||||
<h4>Throws</h4>
|
||||
<ul>
|
||||
{section.throws.map((throws, i) => (
|
||||
<li key={i}>
|
||||
{formatType(throws.type)}
|
||||
{": "}
|
||||
{md(throws.description, true)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
: null}
|
||||
|
||||
{section.examples
|
||||
? <div>
|
||||
<h4>Example{section.examples.length > 1 ? "s" : ""}</h4>
|
||||
{section.examples.map((example, i) => (
|
||||
<div key={i}>
|
||||
{example.caption ? <p>{md(example.caption)}</p> : null}
|
||||
{highlight(example.description)}
|
||||
</div>
|
||||
{section.throws ? (
|
||||
<div>
|
||||
<h4>Throws</h4>
|
||||
<ul>
|
||||
{section.throws.map((throws, i) => (
|
||||
<li key={i}>
|
||||
{formatType(throws.type)}
|
||||
{": "}
|
||||
{md(throws.description, true)}
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
: null}
|
||||
</ul>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{section.members.static && section.members.static.length
|
||||
? <div>
|
||||
<h4>Static Members</h4>
|
||||
<DocSectionList
|
||||
members={section.members.static}
|
||||
noun="Static Member"
|
||||
/>
|
||||
</div>
|
||||
: null}
|
||||
{section.examples ? (
|
||||
<div>
|
||||
<h4>Example{section.examples.length > 1 ? "s" : ""}</h4>
|
||||
{section.examples.map((example, i) => (
|
||||
<div key={i}>
|
||||
{example.caption ? <p>{md(example.caption)}</p> : null}
|
||||
{highlight(example.description)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{section.members.instance && section.members.instance.length
|
||||
? <div>
|
||||
<h4>Instance Members</h4>
|
||||
<DocSectionList
|
||||
members={section.members.instance}
|
||||
noun="Instance Member"
|
||||
/>
|
||||
</div>
|
||||
: null}
|
||||
{section.members.static && section.members.static.length ? (
|
||||
<div>
|
||||
<h4>Static Members</h4>
|
||||
<DocSectionList
|
||||
members={section.members.static}
|
||||
noun="Static Member"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{section.members.events && section.members.events.length
|
||||
? <div>
|
||||
<h4>Events</h4>
|
||||
<DocSectionList members={section.members.events} noun="Event" />
|
||||
</div>
|
||||
: null}
|
||||
{section.members.instance && section.members.instance.length ? (
|
||||
<div>
|
||||
<h4>Instance Members</h4>
|
||||
<DocSectionList
|
||||
members={section.members.instance}
|
||||
noun="Instance Member"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{section.members.events && section.members.events.length ? (
|
||||
<div>
|
||||
<h4>Events</h4>
|
||||
<DocSectionList members={section.members.events} noun="Event" />
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@ -508,9 +515,8 @@ class DocBody extends Component {
|
||||
<div className="intro" id="summary">
|
||||
<DocIntro />
|
||||
</div>
|
||||
{API.map(
|
||||
(s, i) =>
|
||||
s.kind !== "note" ? <DocSection key={i} section={s} /> : null
|
||||
{API.map((s, i) =>
|
||||
s.kind !== "note" ? <DocSection key={i} section={s} /> : null
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@ -530,21 +536,17 @@ export class DocToc extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="documentation-toc">
|
||||
<a href="#summary">
|
||||
gl-react
|
||||
</a>
|
||||
<a href="#summary">gl-react</a>
|
||||
<ul>
|
||||
{API.map((doc, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className={[
|
||||
"kind-" + doc.kind,
|
||||
isReactComponent(doc) ? "react-component" : ""
|
||||
isReactComponent(doc) ? "react-component" : "",
|
||||
].join(" ")}
|
||||
>
|
||||
<a href={"#" + slug(doc.namespace)}>
|
||||
{doc.name}
|
||||
</a>
|
||||
<a href={"#" + slug(doc.namespace)}>{doc.name}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@ -18,13 +18,11 @@
|
||||
.documentation-toc li {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
|
||||
}
|
||||
.documentation-toc li a {
|
||||
padding: 4px 20px;
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
}
|
||||
.documentation-toc li.react-component a {
|
||||
color: #f56;
|
||||
@ -131,7 +129,6 @@ a:hover {
|
||||
}
|
||||
|
||||
.documentation .md {
|
||||
|
||||
}
|
||||
|
||||
.documentation .md blockquote {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import React, { Component } from "react";
|
||||
import queryString from "query-string";
|
||||
|
||||
const encodeQueryValue = value => JSON.stringify(value);
|
||||
const decodeQueryValue = value => JSON.parse(value);
|
||||
const encodeQuery = obj => {
|
||||
const encodeQueryValue = (value) => JSON.stringify(value);
|
||||
const decodeQueryValue = (value) => JSON.parse(value);
|
||||
const encodeQuery = (obj) => {
|
||||
const values = {};
|
||||
for (let k in obj) {
|
||||
if (obj.hasOwnProperty(k)) {
|
||||
@ -12,7 +12,7 @@ const encodeQuery = obj => {
|
||||
}
|
||||
return values;
|
||||
};
|
||||
const decodeQuery = query => {
|
||||
const decodeQuery = (query) => {
|
||||
query = { ...query };
|
||||
for (let k in query) {
|
||||
if (query.hasOwnProperty(k)) {
|
||||
@ -29,27 +29,29 @@ const decodeQuery = query => {
|
||||
|
||||
export default class ExamplePage extends Component {
|
||||
setToolState = (obj: any) => {
|
||||
const { location: { pathname, search } } = this.props;
|
||||
const {
|
||||
location: { pathname, search },
|
||||
} = this.props;
|
||||
this.props.history.replace({
|
||||
pathname,
|
||||
search: queryString.stringify({
|
||||
...queryString.parse(search),
|
||||
...encodeQuery(obj)
|
||||
})
|
||||
...encodeQuery(obj),
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
onChangeField = prop => value => this.setToolState({ [prop]: value });
|
||||
onChangeField = (prop) => (value) => this.setToolState({ [prop]: value });
|
||||
|
||||
render() {
|
||||
const {
|
||||
example: { toolbox, ToolboxFooter, Example, desc, descAfter },
|
||||
location: { search }
|
||||
location: { search },
|
||||
} = this.props;
|
||||
const props = {
|
||||
setToolState: this.setToolState,
|
||||
...Example.defaultProps,
|
||||
...decodeQuery(queryString.parse(search))
|
||||
...decodeQuery(queryString.parse(search)),
|
||||
};
|
||||
return (
|
||||
<div className="example">
|
||||
|
||||
@ -9,7 +9,7 @@ export default (
|
||||
{ refreshRate = 60 }: { refreshRate?: number } = {}
|
||||
): ReactClass<*> => {
|
||||
class TL extends PureComponent {
|
||||
static displayName = `timeLoop(${C.displayName||C.name||""})`;
|
||||
static displayName = `timeLoop(${C.displayName || C.name || ""})`;
|
||||
state: { time: number };
|
||||
state = {
|
||||
time: 0,
|
||||
@ -37,10 +37,7 @@ export default (
|
||||
raf.cancel(this._r);
|
||||
}
|
||||
render() {
|
||||
return <C
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
/>;
|
||||
return <C {...this.props} {...this.state} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AscDA0JcudXmQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABIElEQVR42u3cMQqAQAxE0YkK3v/Ago3gEULIe43lwvLZzqn0Ob/v4/wWd5IcYTUBCAABIAAEgAAQAAJAAAgAASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIABmqfx/qbLL5QUg1Xi2fYDe8+0DIAABuAIBIAAEgAAQAAJAAAgAASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIACmsQ+wl30A7ANsPt8+AAIQgCsQAAJAAAgAASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIAAEgAAQAAJgGvsAe9kHwD7A5vPtAyAAAbgCASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIAAEgAAQAAJAAAgAASAApql8f4niBWChF2e+DTF+hz42AAAAAElFTkSuQmCC');
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AscDA0JcudXmQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABIElEQVR42u3cMQqAQAxE0YkK3v/Ago3gEULIe43lwvLZzqn0Ob/v4/wWd5IcYTUBCAABIAAEgAAQAAJAAAgAASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIABmqfx/qbLL5QUg1Xi2fYDe8+0DIAABuAIBIAAEgAAQAAJAAAgAASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIACmsQ+wl30A7ANsPt8+AAIQgCsQAAJAAAgAASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIAAEgAAQAAJgGvsAe9kHwD7A5vPtAyAAAbgCASAABIAAEAACQAAIAAEgAASAABAAAkAACAABIAAEgAAQAAJAAAgAASAApql8f4niBWChF2e+DTF+hz42AAAAAElFTkSuQmCC");
|
||||
background-size: 64px 64px;
|
||||
}
|
||||
|
||||
@ -65,12 +65,12 @@
|
||||
}
|
||||
|
||||
.gl-react-inspector .box {
|
||||
position: absolute;;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 180px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0px 0px 3px rgba(0,0,0,0);
|
||||
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0);
|
||||
border: 1px solid #eee;
|
||||
background: #fff;
|
||||
transition: 0.2s border-color;
|
||||
@ -156,7 +156,9 @@
|
||||
.gl-react-inspector .box.minimized .uniform .anchor-hook {
|
||||
height: 12px;
|
||||
}
|
||||
.gl-react-inspector .box.minimized .uniform:not(.type-sampler2D):not(.type-array-sampler2D) {
|
||||
.gl-react-inspector
|
||||
.box.minimized
|
||||
.uniform:not(.type-sampler2D):not(.type-array-sampler2D) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -197,7 +199,6 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.gl-react-inspector .box .anchor-hook {
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
@ -323,7 +324,9 @@
|
||||
}
|
||||
|
||||
.gl-react-inspector .preview canvas {
|
||||
background: #f3f3f3 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAARklEQVRYw+3XwQkAIAwEwYvYf8uxBcE8fMwWEAbuleruDDd6cOXzAAEBAQEBAQEBAQFf2tM/RJIyMSAgICAgICAgICDgZQeYxgVOKu5KXQAAAABJRU5ErkJggg==) repeat;
|
||||
background: #f3f3f3
|
||||
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAARklEQVRYw+3XwQkAIAwEwYvYf8uxBcE8fMwWEAbuleruDDd6cOXzAAEBAQEBAQEBAQFf2tM/RJIyMSAgICAgICAgICDgZQeYxgVOKu5KXQAAAABJRU5ErkJggg==)
|
||||
repeat;
|
||||
background-size: 20px 20px;
|
||||
border: 1px solid #666;
|
||||
max-width: 100%;
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
Node,
|
||||
Bus,
|
||||
Uniform,
|
||||
listSurfaces
|
||||
listSurfaces,
|
||||
} from "gl-react";
|
||||
import raf from "raf";
|
||||
import type { Surface } from "gl-react-dom";
|
||||
@ -47,10 +47,10 @@ const primitiveTypeAlias = {
|
||||
bvec4: Array(4).fill("bool"),
|
||||
mat2: Array(4).fill("float"),
|
||||
mat3: Array(9).fill("float"),
|
||||
mat4: Array(16).fill("float")
|
||||
mat4: Array(16).fill("float"),
|
||||
};
|
||||
|
||||
const classType = type => {
|
||||
const classType = (type) => {
|
||||
if (Array.isArray(type)) return "type-array-" + type[0];
|
||||
return "type-" + type;
|
||||
};
|
||||
@ -99,7 +99,7 @@ class PreviewRenderer {
|
||||
1.0,
|
||||
-1.0,
|
||||
1.0,
|
||||
1.0
|
||||
1.0,
|
||||
]),
|
||||
gl.STATIC_DRAW
|
||||
);
|
||||
@ -166,7 +166,7 @@ class UniformValue extends Component {
|
||||
node: Object,
|
||||
value: any,
|
||||
type: any,
|
||||
info: any
|
||||
info: any,
|
||||
};
|
||||
render() {
|
||||
let { id, node, value, type, info } = this.props;
|
||||
@ -200,7 +200,7 @@ class UniformValue extends Component {
|
||||
class Btn extends Component {
|
||||
props: {
|
||||
onClick: ?() => void,
|
||||
children?: any
|
||||
children?: any,
|
||||
};
|
||||
render() {
|
||||
const { onClick, children } = this.props;
|
||||
@ -209,7 +209,7 @@ class Btn extends Component {
|
||||
className="btn"
|
||||
onClick={onClick}
|
||||
style={{
|
||||
opacity: onClick ? 1 : 0.5
|
||||
opacity: onClick ? 1 : 0.5,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
@ -225,11 +225,11 @@ class Btn extends Component {
|
||||
class Anchor extends Component {
|
||||
props: {
|
||||
id: number,
|
||||
drawCount: number
|
||||
drawCount: number,
|
||||
};
|
||||
drawHistoryDates: Array<number> = [];
|
||||
static contextTypes = {
|
||||
inspector: PropTypes.object.isRequired
|
||||
inspector: PropTypes.object.isRequired,
|
||||
};
|
||||
componentDidMount() {
|
||||
this.context.inspector.addAnchor(this.props.id, this);
|
||||
@ -278,10 +278,10 @@ class AnchorHook extends Component {
|
||||
props: {
|
||||
id: string,
|
||||
nodeId: number,
|
||||
anchorId: number
|
||||
anchorId: number,
|
||||
};
|
||||
static contextTypes = {
|
||||
inspector: PropTypes.object.isRequired
|
||||
inspector: PropTypes.object.isRequired,
|
||||
};
|
||||
componentDidMount() {
|
||||
this.context.inspector.addAnchorHook(this.props.anchorId, this);
|
||||
@ -322,8 +322,8 @@ class MetaInfo extends Component {
|
||||
obj: ?Object,
|
||||
initialObj: ?Object,
|
||||
dependency: ?Object,
|
||||
textureOptions: ?Object
|
||||
}
|
||||
textureOptions: ?Object,
|
||||
},
|
||||
};
|
||||
render() {
|
||||
const { id, info, node } = this.props;
|
||||
@ -374,7 +374,7 @@ const sharedRenderer = new PreviewRenderer();
|
||||
|
||||
class Preview extends Component {
|
||||
props: {
|
||||
capture: Function
|
||||
capture: Function,
|
||||
};
|
||||
interval: number;
|
||||
canvas: ?HTMLCanvasElement;
|
||||
@ -395,7 +395,7 @@ class Preview extends Component {
|
||||
sharedRenderer.copyToCanvas2D(ctx);
|
||||
}
|
||||
}, 100);
|
||||
onCanvasRef = canvas => {
|
||||
onCanvasRef = (canvas) => {
|
||||
if (!canvas || this.ctx) return;
|
||||
const ctx = canvas.getContext("2d");
|
||||
if ("imageSmoothingEnabled" in ctx) {
|
||||
@ -421,7 +421,7 @@ class Preview extends Component {
|
||||
|
||||
class PreviewNode extends PureComponent {
|
||||
props: {
|
||||
node: Object
|
||||
node: Object,
|
||||
};
|
||||
capture = () => {
|
||||
const { node } = this.props;
|
||||
@ -436,7 +436,7 @@ class PreviewNode extends PureComponent {
|
||||
|
||||
class PreviewContent extends Component {
|
||||
props: {
|
||||
content: Object
|
||||
content: Object,
|
||||
};
|
||||
capture = () => {
|
||||
const { content } = this.props;
|
||||
@ -449,7 +449,7 @@ class PreviewContent extends Component {
|
||||
|
||||
class DrawCount extends PureComponent {
|
||||
props: {
|
||||
drawCount: number
|
||||
drawCount: number,
|
||||
};
|
||||
render() {
|
||||
const { drawCount } = this.props;
|
||||
@ -472,13 +472,13 @@ class InspectorBox extends Component {
|
||||
grabbed?: boolean,
|
||||
minimized: boolean,
|
||||
onGrabStart: (id: number, e: MouseEvent) => void,
|
||||
onMinimizeChange: (id: number, minimized: boolean) => void
|
||||
onMinimizeChange: (id: number, minimized: boolean) => void,
|
||||
};
|
||||
static contextTypes = {
|
||||
inspector: PropTypes.object.isRequired
|
||||
inspector: PropTypes.object.isRequired,
|
||||
};
|
||||
state = {
|
||||
recentDraw: false
|
||||
recentDraw: false,
|
||||
};
|
||||
lastDrawCountTime: number;
|
||||
_timeout: number;
|
||||
@ -515,11 +515,11 @@ class InspectorBox extends Component {
|
||||
});
|
||||
}
|
||||
};
|
||||
onMouseDown = e => {
|
||||
onMouseDown = (e) => {
|
||||
e.preventDefault();
|
||||
this.props.onGrabStart(this.props.glObject.id, e);
|
||||
};
|
||||
onClickMinimize = e => {
|
||||
onClickMinimize = (e) => {
|
||||
e.preventDefault();
|
||||
this.props.onMinimizeChange(this.props.glObject.id, !this.props.minimized);
|
||||
};
|
||||
@ -536,7 +536,7 @@ class InspectorBox extends Component {
|
||||
children,
|
||||
grabbed,
|
||||
cls,
|
||||
minimized
|
||||
minimized,
|
||||
} = this.props;
|
||||
return (
|
||||
<div
|
||||
@ -570,7 +570,7 @@ class InspectorBox extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const formatType = t => {
|
||||
const formatType = (t) => {
|
||||
if (Array.isArray(t)) return t[0] + "[]";
|
||||
return t;
|
||||
};
|
||||
@ -578,14 +578,14 @@ const formatType = t => {
|
||||
class Uniforms extends PureComponent {
|
||||
props: {
|
||||
node: Object,
|
||||
preparedUniforms: ?Object
|
||||
preparedUniforms: ?Object,
|
||||
};
|
||||
render() {
|
||||
const { node, preparedUniforms } = this.props;
|
||||
return (
|
||||
<div className="uniforms">
|
||||
{preparedUniforms &&
|
||||
preparedUniforms.map(u => (
|
||||
preparedUniforms.map((u) => (
|
||||
<div key={u.key} className={"uniform " + classType(u.type)}>
|
||||
<span
|
||||
className="name"
|
||||
@ -620,7 +620,7 @@ class SVGConnectionLine extends PureComponent {
|
||||
anchorY: number,
|
||||
onPathRef: Function,
|
||||
reversedHook?: boolean,
|
||||
recursive?: boolean
|
||||
recursive?: boolean,
|
||||
};
|
||||
render() {
|
||||
const {
|
||||
@ -630,7 +630,7 @@ class SVGConnectionLine extends PureComponent {
|
||||
hookY,
|
||||
recursive,
|
||||
onPathRef,
|
||||
reversedHook
|
||||
reversedHook,
|
||||
} = this.props;
|
||||
const dx = hookX - anchorX;
|
||||
const dy = hookY - anchorY;
|
||||
@ -671,10 +671,10 @@ class SVGConnection extends Component {
|
||||
solid: number,
|
||||
recursive?: boolean,
|
||||
reversedHook?: boolean,
|
||||
animated?: boolean
|
||||
animated?: boolean,
|
||||
};
|
||||
state = {
|
||||
draws: []
|
||||
draws: [],
|
||||
};
|
||||
path: any;
|
||||
_raf: any;
|
||||
@ -694,10 +694,10 @@ class SVGConnection extends Component {
|
||||
}
|
||||
const length = path.getTotalLength();
|
||||
this.setState({
|
||||
draws: values.map(v => {
|
||||
draws: values.map((v) => {
|
||||
const { x, y } = path.getPointAtLength(v * length);
|
||||
return [x.toFixed(1), y.toFixed(1)]; // round is too aggressive and great jump. but using full float is also more consuming
|
||||
})
|
||||
}),
|
||||
});
|
||||
};
|
||||
this._raf = raf(loop);
|
||||
@ -710,7 +710,7 @@ class SVGConnection extends Component {
|
||||
componentWillUnmount() {
|
||||
raf.cancel(this._raf);
|
||||
}
|
||||
onPathRef = ref => {
|
||||
onPathRef = (ref) => {
|
||||
this.path = ref;
|
||||
};
|
||||
render() {
|
||||
@ -722,7 +722,7 @@ class SVGConnection extends Component {
|
||||
tension,
|
||||
solid,
|
||||
recursive,
|
||||
reversedHook
|
||||
reversedHook,
|
||||
} = this.props;
|
||||
const { draws } = this.state;
|
||||
return (
|
||||
@ -753,7 +753,7 @@ class SVGStandaloneConnection extends Component {
|
||||
anchorX: number,
|
||||
anchorY: number,
|
||||
hookX: number,
|
||||
hookY: number
|
||||
hookY: number,
|
||||
};
|
||||
render() {
|
||||
const { animated, anchor, anchorX, anchorY, hookX, hookY } = this.props;
|
||||
@ -782,7 +782,7 @@ class HookDrawer extends Component {
|
||||
anchorPositions: *,
|
||||
anchorHookPositions: *,
|
||||
boxSizes: *,
|
||||
grabbing: ?Object
|
||||
grabbing: ?Object,
|
||||
};
|
||||
render() {
|
||||
const {
|
||||
@ -792,7 +792,7 @@ class HookDrawer extends Component {
|
||||
anchorPositions,
|
||||
anchorHookPositions,
|
||||
boxSizes,
|
||||
grabbing
|
||||
grabbing,
|
||||
} = this.props;
|
||||
return (
|
||||
<svg ref="svg" className="hook-drawer">
|
||||
@ -817,7 +817,7 @@ class HookDrawer extends Component {
|
||||
hookY={anchorPosition[1] + size[1] - 22}
|
||||
/>
|
||||
) : (
|
||||
hooks.map(hook => {
|
||||
hooks.map((hook) => {
|
||||
const hookId = hook.getId();
|
||||
const hookNodeId = hook.getNodeId();
|
||||
const hookIsGrabbed = grabbing && grabbing.id === hookNodeId;
|
||||
@ -868,10 +868,10 @@ export default class Inspector extends Component {
|
||||
capture: false,
|
||||
animated: true,
|
||||
physics: false,
|
||||
minimizeAll: false
|
||||
minimizeAll: false,
|
||||
};
|
||||
static childContextTypes = {
|
||||
inspector: PropTypes.object.isRequired
|
||||
inspector: PropTypes.object.isRequired,
|
||||
};
|
||||
getChildContext() {
|
||||
return { inspector: this };
|
||||
@ -900,14 +900,14 @@ export default class Inspector extends Component {
|
||||
grabbing: ?{
|
||||
id: number,
|
||||
initialPos: [number, number],
|
||||
initialEventPos: [number, number]
|
||||
initialEventPos: [number, number],
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
Visitors.add(this);
|
||||
this._startupTimeout = setTimeout(() => this.detectSurface(), 0);
|
||||
let lastT;
|
||||
const loop = t => {
|
||||
const loop = (t) => {
|
||||
this._raf = raf(loop);
|
||||
if (!lastT) lastT = t;
|
||||
const delta = Math.min(100, t - lastT);
|
||||
@ -978,7 +978,7 @@ export default class Inspector extends Component {
|
||||
|
||||
onNodeDrawEnd(node: Node) {
|
||||
this.nodeDrawCounts.set(node, (this.nodeDrawCounts.get(node) || 0) + 1);
|
||||
node.dependencies.forEach(obj => {
|
||||
node.dependencies.forEach((obj) => {
|
||||
if (obj instanceof Bus) {
|
||||
this.busDrawCounts.set(obj, (this.busDrawCounts.get(obj) || 0) + 1);
|
||||
}
|
||||
@ -1023,7 +1023,7 @@ export default class Inspector extends Component {
|
||||
const pos = [
|
||||
// FIXME TMP
|
||||
60 + 240 * ((i + 1) % 2),
|
||||
40 + 200 * Math.floor(i / 2)
|
||||
40 + 200 * Math.floor(i / 2),
|
||||
];
|
||||
this.boxPos.set(id, pos);
|
||||
this.boxMinimized.set(id, this.state.minimizeAll);
|
||||
@ -1051,7 +1051,7 @@ export default class Inspector extends Component {
|
||||
anchorHooksByAnchorId,
|
||||
anchorHookPositions,
|
||||
boxesById,
|
||||
boxSizes
|
||||
boxSizes,
|
||||
} = this;
|
||||
// FIXME only the Anchor and AnchorHook should be allow to "sync this"
|
||||
// as soon as we make this local position, not global...
|
||||
@ -1065,8 +1065,8 @@ export default class Inspector extends Component {
|
||||
anchorPositions.set(id, [x, y]);
|
||||
}
|
||||
});
|
||||
anchorHooksByAnchorId.forEach(anchorHooks => {
|
||||
anchorHooks.forEach(anchorHook => {
|
||||
anchorHooksByAnchorId.forEach((anchorHooks) => {
|
||||
anchorHooks.forEach((anchorHook) => {
|
||||
let [x, y] = anchorHook.getXY();
|
||||
x = Math.round(x - offX);
|
||||
y = Math.round(y - offY);
|
||||
@ -1105,13 +1105,13 @@ export default class Inspector extends Component {
|
||||
anchorsById,
|
||||
anchorHooksByAnchorId,
|
||||
boxPos,
|
||||
boxSizes
|
||||
boxSizes,
|
||||
} = this;
|
||||
anchorsById.forEach((anchor, anchorId) => {
|
||||
const hooks = anchorHooksByAnchorId.get(anchorId) || [];
|
||||
const anchorPos = anchorPositions.get(anchorId);
|
||||
if (!anchorPos) return;
|
||||
hooks.forEach(hook => {
|
||||
hooks.forEach((hook) => {
|
||||
const hookId = hook.getId();
|
||||
const hookNodeId = hook.getNodeId();
|
||||
if (anchorId !== hookNodeId) {
|
||||
@ -1171,7 +1171,7 @@ export default class Inspector extends Component {
|
||||
const size = boxSizes.get(id) || [0, 0];
|
||||
v = [
|
||||
(v[0] + a[0] * timestep) * damping,
|
||||
(v[1] + a[1] * timestep) * damping
|
||||
(v[1] + a[1] * timestep) * damping,
|
||||
];
|
||||
p = [p[0] + v[0] * timestep, p[1] + v[1] * timestep];
|
||||
if (bounds) {
|
||||
@ -1191,7 +1191,7 @@ export default class Inspector extends Component {
|
||||
this.spring();
|
||||
this.updateVelocityPosition(timestep);
|
||||
var energy = 0.0;
|
||||
this.boxVel.forEach(v => {
|
||||
this.boxVel.forEach((v) => {
|
||||
energy += v[0] * v[0] + v[1] * v[1];
|
||||
});
|
||||
if (energy > 0.00001) {
|
||||
@ -1204,7 +1204,7 @@ export default class Inspector extends Component {
|
||||
this.grabbing = {
|
||||
id,
|
||||
initialPos: boxPos,
|
||||
initialEventPos: [e.clientX, e.clientY]
|
||||
initialEventPos: [e.clientX, e.clientY],
|
||||
};
|
||||
this.forceUpdate();
|
||||
};
|
||||
@ -1334,7 +1334,7 @@ export default class Inspector extends Component {
|
||||
grabbed: grabbing ? grabbing.id === id : false,
|
||||
minimized,
|
||||
onMinimizeChange: this.onMinimizeChange,
|
||||
onGrabStart: this.onGrabStart
|
||||
onGrabStart: this.onGrabStart,
|
||||
};
|
||||
if (n instanceof Node) {
|
||||
const [width, height] = n.getGLSize();
|
||||
@ -1428,7 +1428,7 @@ export default class Inspector extends Component {
|
||||
<Btn key="ctx" onClick={this.loseContext}>
|
||||
lose GL context
|
||||
</Btn>
|
||||
)
|
||||
),
|
||||
];
|
||||
body = (
|
||||
<div ref="body" className="body">
|
||||
@ -1453,7 +1453,7 @@ export default class Inspector extends Component {
|
||||
<div className="no-surface">
|
||||
<h2>No Surface is currently inspected. Select one of these:</h2>
|
||||
<ul>
|
||||
{listSurfaces().map(surface => (
|
||||
{listSurfaces().map((surface) => (
|
||||
<li key={surface.id}>
|
||||
<span onClick={() => this.setSurface(surface)}>
|
||||
{surface.getGLName()}
|
||||
@ -1482,7 +1482,7 @@ export default class Inspector extends Component {
|
||||
onChange={this.onSelectChange}
|
||||
>
|
||||
<option value="">(none)</option>
|
||||
{listSurfaces().map(surface => (
|
||||
{listSurfaces().map((surface) => (
|
||||
<option key={surface.id} value={surface.id}>
|
||||
{surface.getGLName()}
|
||||
</option>
|
||||
|
||||
@ -4,7 +4,8 @@ import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import Animated from "animated";
|
||||
const shaders = Shaders.create({
|
||||
cursor: { frag: GLSL`
|
||||
cursor: {
|
||||
frag: GLSL`
|
||||
precision lowp float; varying vec2 uv; uniform vec2 style;
|
||||
void main() {
|
||||
float dist = pow(1.0 - distance(style, uv), 8.0);
|
||||
@ -12,12 +13,15 @@ void main() {
|
||||
1.0 * dist + pow(1.0 - distance(style.y, uv.y), 16.0),
|
||||
0.5 * dist + pow(1.0 - distance(style.y, uv.y), 32.0),
|
||||
0.2 * dist + pow(1.0 - distance(style.x, uv.x), 32.0)), 1.0);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
class Cursor extends Component {
|
||||
render() {
|
||||
const { style: { x, y } } = this.props;
|
||||
return <Node shader={shaders.cursor} uniforms={{ style: [ x, y ] }} />;
|
||||
const {
|
||||
style: { x, y },
|
||||
} = this.props;
|
||||
return <Node shader={shaders.cursor} uniforms={{ style: [x, y] }} />;
|
||||
}
|
||||
}
|
||||
// using "style" is a hack. see https://github.com/animatedjs/animated/issues/45
|
||||
@ -25,7 +29,7 @@ const AnimatedCursor = Animated.createAnimatedComponent(Cursor);
|
||||
|
||||
export default class Example extends Component {
|
||||
state = {
|
||||
style: new Animated.ValueXY({ x: 0.5, y: 0.5 })
|
||||
style: new Animated.ValueXY({ x: 0.5, y: 0.5 }),
|
||||
};
|
||||
onMouseMove = (e: any) => {
|
||||
const rect = e.target.getBoundingClientRect();
|
||||
@ -33,7 +37,7 @@ export default class Example extends Component {
|
||||
toValue: {
|
||||
x: (e.clientX - rect.left) / rect.width,
|
||||
y: (rect.bottom - e.clientY) / rect.height,
|
||||
}
|
||||
},
|
||||
}).start();
|
||||
};
|
||||
render() {
|
||||
@ -43,4 +47,4 @@ export default class Example extends Component {
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -44,4 +44,4 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
};
|
||||
`
|
||||
`;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ void main() {
|
||||
color += texture2D(t, uv - (off2 / dim)) * 0.0702702703;
|
||||
gl_FragColor = color;
|
||||
}
|
||||
`
|
||||
`,
|
||||
},
|
||||
game: {
|
||||
frag: GLSL`
|
||||
@ -74,7 +74,7 @@ void main() {
|
||||
)
|
||||
* mix(1.0, smoothstep(1.0, 0.0, dd), 0.6), 1.0);
|
||||
}
|
||||
`
|
||||
`,
|
||||
},
|
||||
glare: {
|
||||
frag: GLSL`
|
||||
@ -84,7 +84,7 @@ uniform sampler2D t;
|
||||
void main() {
|
||||
gl_FragColor = vec4(step(0.9, texture2D(t, uv).r));
|
||||
}
|
||||
`
|
||||
`,
|
||||
},
|
||||
laser: {
|
||||
frag: GLSL`
|
||||
@ -102,7 +102,7 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
`
|
||||
`,
|
||||
},
|
||||
persistence: {
|
||||
frag: GLSL`
|
||||
@ -117,7 +117,7 @@ void main() {
|
||||
texture2D(t, uv).rgb,
|
||||
1.0);
|
||||
}
|
||||
`
|
||||
`,
|
||||
},
|
||||
player: {
|
||||
frag: GLSL`
|
||||
@ -208,8 +208,8 @@ void main() {
|
||||
c *= 1.0 - 1.3 * distance(uv, vec2(0.5));
|
||||
gl_FragColor = vec4(light * mix(env(), c.rgb, clamp(c.a, 0.0, 1.0)), 1.0);
|
||||
}
|
||||
`
|
||||
}
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
const Blur1D = ({ dim, dir, children: t }) => (
|
||||
@ -234,15 +234,13 @@ export default class Example extends Component {
|
||||
k: [0, 0],
|
||||
W: 2,
|
||||
H: 2,
|
||||
S: 0
|
||||
S: 0,
|
||||
};
|
||||
const dim = [W, H];
|
||||
|
||||
return (
|
||||
<div style={{ background: "black" }} ref="container">
|
||||
|
||||
<Surface width={W} height={H} pixelRatio={1}>
|
||||
|
||||
<Bus ref="laser">
|
||||
<Node
|
||||
shader={shaders.laser}
|
||||
@ -285,9 +283,10 @@ export default class Example extends Component {
|
||||
<Blur1D dim={dim} dir={[1, 0]}>
|
||||
<Blur1D dim={dim} dir={[-0.5, 0.5]}>
|
||||
<Blur1D dim={dim} dir={[0.5, 0.5]}>
|
||||
{() => this.refs.laser
|
||||
//FIXME this should be glare instead.
|
||||
//but i think there is a bug in gl-react!
|
||||
{
|
||||
() => this.refs.laser
|
||||
//FIXME this should be glare instead.
|
||||
//but i think there is a bug in gl-react!
|
||||
}
|
||||
</Blur1D>
|
||||
</Blur1D>
|
||||
@ -301,7 +300,7 @@ export default class Example extends Component {
|
||||
backbuffering
|
||||
uniforms={{
|
||||
t: this.refs.glareBlurred,
|
||||
r: Uniform.Backbuffer
|
||||
r: Uniform.Backbuffer,
|
||||
}}
|
||||
/>
|
||||
</Bus>
|
||||
@ -316,7 +315,7 @@ export default class Example extends Component {
|
||||
E: () => this.refs.player,
|
||||
s,
|
||||
F,
|
||||
k
|
||||
k,
|
||||
}}
|
||||
/>
|
||||
</Surface>
|
||||
@ -324,9 +323,7 @@ export default class Example extends Component {
|
||||
<canvas id="c" ref="gameCanvas" hidden={!showCanvas} />
|
||||
|
||||
<div style={{ textAlign: "center", padding: 20 }}>
|
||||
<button onClick={this.sendAsteroid}>
|
||||
SEND ASTEROID!
|
||||
</button>
|
||||
<button onClick={this.sendAsteroid}>SEND ASTEROID!</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -345,6 +342,6 @@ export default class Example extends Component {
|
||||
sendAsteroid = () => window._behindAsteroids_send();
|
||||
|
||||
static defaultProps = {
|
||||
showCanvas: false
|
||||
showCanvas: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL, Bus, Uniform } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -348,4 +348,4 @@ export default class Example extends Component {
|
||||
showCanvas: false
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -3,16 +3,25 @@ import React from "react";
|
||||
export const title = "Behind Asteroids (js13k 2015 – greweb)";
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "showCanvas",
|
||||
{
|
||||
prop: "showCanvas",
|
||||
title: "Under the hood",
|
||||
Editor:
|
||||
({ value, onChange }) =>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" checked={value} onChange={e => onChange(e.target.checked)} />
|
||||
Show the 2D Canvas rendered by the game
|
||||
</label>
|
||||
<p><em>The rest of the rendering is done in WebGL (ported in gl-react).</em></p>
|
||||
</div>
|
||||
Editor: ({ value, onChange }) => (
|
||||
<div>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={value}
|
||||
onChange={(e) => onChange(e.target.checked)}
|
||||
/>
|
||||
Show the 2D Canvas rendered by the game
|
||||
</label>
|
||||
<p>
|
||||
<em>
|
||||
The rest of the rendering is done in WebGL (ported in gl-react).
|
||||
</em>
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@ -5,12 +5,13 @@ import { Surface } from "gl-react-dom";
|
||||
import { BlurXY } from "../blurxy";
|
||||
import { images } from "./meta";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
import image from "./1.jpg";
|
||||
|
||||
const ContinuousBlur = timeLoop(BlurXY);
|
||||
|
||||
export default class Example extends Component {
|
||||
state = {
|
||||
buffering: false
|
||||
buffering: false,
|
||||
};
|
||||
componentWillReceiveProps({ image, refreshId }: *) {
|
||||
if (image !== this.props.image || refreshId !== this.props.refreshId) {
|
||||
@ -43,8 +44,8 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
static defaultProps = {
|
||||
image: require("./1.jpg"),
|
||||
image,
|
||||
factor: 0,
|
||||
refreshId: 0
|
||||
refreshId: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { NearestCopy, LinearCopy, Uniform } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -48,4 +48,4 @@ export default class Example extends Component {
|
||||
refreshId: 0
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -4,16 +4,16 @@ import ImagesPicker from "../../toolbox/ImagesPicker";
|
||||
import makeFloatSlider from "../../toolbox/makeFloatSlider";
|
||||
|
||||
export const images = [
|
||||
require("./1.jpg"),
|
||||
require("./2.jpg"),
|
||||
require("./3.jpg")
|
||||
require("./1.jpg").default,
|
||||
require("./2.jpg").default,
|
||||
require("./3.jpg").default,
|
||||
];
|
||||
|
||||
export const toolbox = [
|
||||
{
|
||||
prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0, 8, 0.2)
|
||||
Editor: makeFloatSlider(0, 8, 0.2),
|
||||
},
|
||||
{
|
||||
prop: "image",
|
||||
@ -21,19 +21,20 @@ export const toolbox = [
|
||||
Editor: ImagesPicker,
|
||||
style: { width: 400 },
|
||||
imageStyle: { maxWidth: 56, maxHeight: 56, marginBottom: 16 },
|
||||
images
|
||||
images,
|
||||
},
|
||||
{
|
||||
prop: "refreshId",
|
||||
title: "",
|
||||
Editor: ({ onChange, value }) =>
|
||||
Editor: ({ onChange, value }) => (
|
||||
<button
|
||||
style={{ fontSize: "1.4em", lineHeight: "1.4em" }}
|
||||
onClick={() => onChange(value + 1)}
|
||||
>
|
||||
REFRESH
|
||||
</button>
|
||||
}
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export const title = "Blur feedback";
|
||||
|
||||
@ -30,7 +30,7 @@ void main() {
|
||||
), 1.0);
|
||||
float isText = 1.0 - texture2D(title, uv).r;
|
||||
gl_FragColor = mix(bgColor, textColor, isText);
|
||||
}`
|
||||
}`,
|
||||
},
|
||||
TitleBlurMap: {
|
||||
frag: GLSL`
|
||||
@ -42,8 +42,8 @@ void main() {
|
||||
gl_FragColor = vec4(
|
||||
vec3(smoothstep(1.0, threshold, texture2D(t, uv).r)),
|
||||
1.0);
|
||||
}`
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const AveragePixels = ({ children, quality }) => (
|
||||
@ -68,7 +68,7 @@ const TitleBlurMap = ({ children: title, threshold }) => (
|
||||
<Blur factor={4} passes={4} width={200} height={200}>
|
||||
{title}
|
||||
</Blur>
|
||||
)
|
||||
),
|
||||
}}
|
||||
width={64}
|
||||
height={64}
|
||||
@ -89,10 +89,10 @@ class Title extends PureComponent {
|
||||
font: "bold 78px Didot,Georgia,serif",
|
||||
fillStyle: "#000",
|
||||
textBaseline: "top",
|
||||
textAlign: "center"
|
||||
textAlign: "center",
|
||||
},
|
||||
["fillText", children, width / 2, 10, 84]
|
||||
]
|
||||
["fillText", children, width / 2, 10, 84],
|
||||
],
|
||||
}}
|
||||
</JSON2D>
|
||||
</LinearCopy>
|
||||
@ -106,7 +106,7 @@ class ImageTitleC extends Component {
|
||||
height: PropTypes.number.isRequired,
|
||||
children: PropTypes.any.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
colorThreshold: PropTypes.number.isRequired
|
||||
colorThreshold: PropTypes.number.isRequired,
|
||||
};
|
||||
render() {
|
||||
const { width, height, children: img, text, colorThreshold } = this.props;
|
||||
@ -119,10 +119,9 @@ class ImageTitleC extends Component {
|
||||
imgBlurred: () => this.refs.imgBlurred,
|
||||
title: () => this.refs.title,
|
||||
imgTone: () => this.refs.imgTone,
|
||||
blurMap: () => this.refs.blurMap
|
||||
blurMap: () => this.refs.blurMap,
|
||||
}}
|
||||
>
|
||||
|
||||
<Bus ref="title">
|
||||
<Title width={width} height={height}>
|
||||
{text}
|
||||
@ -130,15 +129,11 @@ class ImageTitleC extends Component {
|
||||
</Bus>
|
||||
|
||||
<Bus ref="blurMap">
|
||||
<TitleBlurMap threshold={0.7}>
|
||||
{() => this.refs.title}
|
||||
</TitleBlurMap>
|
||||
<TitleBlurMap threshold={0.7}>{() => this.refs.title}</TitleBlurMap>
|
||||
</Bus>
|
||||
|
||||
<Bus ref="imgTone">
|
||||
<AveragePixels quality={8}>
|
||||
{img}
|
||||
</AveragePixels>
|
||||
<AveragePixels quality={8}>{img}</AveragePixels>
|
||||
</Bus>
|
||||
|
||||
<Bus ref="imgBlurred">
|
||||
@ -146,7 +141,6 @@ class ImageTitleC extends Component {
|
||||
{img}
|
||||
</BlurV>
|
||||
</Bus>
|
||||
|
||||
</Node>
|
||||
);
|
||||
}
|
||||
@ -168,6 +162,6 @@ export default class Example extends Component {
|
||||
static defaultProps = {
|
||||
title: "Hello\nSan Francisco\n☻",
|
||||
colorThreshold: 0.6,
|
||||
image: require("./sf-6.jpg")
|
||||
image: require("./sf-6.jpg").default,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { PureComponent, Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Shaders, Node, GLSL, Bus, LinearCopy, connectSize } from "gl-react";
|
||||
@ -171,4 +171,4 @@ export default class Example extends Component {
|
||||
image: require("./sf-6.jpg")
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -5,7 +5,8 @@ import makeFloatSlider from "../../toolbox/makeFloatSlider";
|
||||
export const title = "Dynamic Blur Image Title";
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "title",
|
||||
{
|
||||
prop: "title",
|
||||
title: "Title",
|
||||
Editor: makeTextArea({
|
||||
height: 140,
|
||||
@ -15,22 +16,27 @@ export const toolbox = [
|
||||
lineHeight: "42px",
|
||||
fontWeight: "bold",
|
||||
textAlign: "center",
|
||||
}) },
|
||||
{ prop: "colorThreshold",
|
||||
}),
|
||||
},
|
||||
{
|
||||
prop: "colorThreshold",
|
||||
title: "Color Threshold",
|
||||
Editor: makeFloatSlider(0, 1, 0.01) }, // FIXME black <-> white
|
||||
{ prop: "image",
|
||||
Editor: makeFloatSlider(0, 1, 0.01),
|
||||
}, // FIXME black <-> white
|
||||
{
|
||||
prop: "image",
|
||||
title: "Image",
|
||||
Editor: ImagesPicker,
|
||||
style: { width: 400 },
|
||||
imageStyle: { maxWidth: 56, maxHeight: 56, marginBottom: 16, },
|
||||
imageStyle: { maxWidth: 56, maxHeight: 56, marginBottom: 16 },
|
||||
images: [
|
||||
require("./sf-1.jpg"),
|
||||
require("./sf-2.jpg"),
|
||||
require("./sf-3.jpg"),
|
||||
require("./sf-4.jpg"),
|
||||
require("./sf-5.jpg"),
|
||||
require("./sf-6.jpg"),
|
||||
require("./sf-7.jpg"),
|
||||
] },
|
||||
require("./sf-1.jpg").default,
|
||||
require("./sf-2.jpg").default,
|
||||
require("./sf-3.jpg").default,
|
||||
require("./sf-4.jpg").default,
|
||||
require("./sf-5.jpg").default,
|
||||
require("./sf-6.jpg").default,
|
||||
require("./sf-7.jpg").default,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@ -24,8 +24,8 @@ vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
|
||||
}
|
||||
void main() {
|
||||
gl_FragColor = blur9(t, uv, resolution, direction * texture2D(map, uv).rg);
|
||||
}`
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Same concept than Blur1D except it takes one more prop:
|
||||
@ -41,12 +41,14 @@ export const BlurV1D = connectSize(
|
||||
|
||||
// And its N-pass version
|
||||
export const BlurV = connectSize(({ children, factor, map, passes }) => {
|
||||
const rec = pass =>
|
||||
pass <= 0
|
||||
? children
|
||||
: <BlurV1D map={map} direction={directionForPass(pass, factor, passes)}>
|
||||
{rec(pass - 1)}
|
||||
</BlurV1D>;
|
||||
const rec = (pass) =>
|
||||
pass <= 0 ? (
|
||||
children
|
||||
) : (
|
||||
<BlurV1D map={map} direction={directionForPass(pass, factor, passes)}>
|
||||
{rec(pass - 1)}
|
||||
</BlurV1D>
|
||||
);
|
||||
return rec(passes);
|
||||
});
|
||||
|
||||
@ -64,6 +66,6 @@ export default class Example extends Component {
|
||||
static defaultProps = {
|
||||
factor: 2,
|
||||
passes: 4,
|
||||
map: StaticBlurMap.images[0]
|
||||
map: StaticBlurMap.images[0],
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL, connectSize } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -67,4 +67,4 @@ export default class Example extends Component {
|
||||
map: StaticBlurMap.images[0]
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -9,13 +9,11 @@ export const descAfter = markdown`
|
||||
We use a texture to map the depth of the Blur.
|
||||
`;
|
||||
export const toolbox = [
|
||||
{ prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{ prop: "passes",
|
||||
title: value => `Blur Passes (${value})`,
|
||||
Editor: makeFloatSlider(1, 8, 1) },
|
||||
{ prop: "map",
|
||||
title: "Blur Texture Map",
|
||||
Editor: StaticBlurMap },
|
||||
{ prop: "factor", title: "Blur", Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{
|
||||
prop: "passes",
|
||||
title: (value) => `Blur Passes (${value})`,
|
||||
Editor: makeFloatSlider(1, 8, 1),
|
||||
},
|
||||
{ prop: "map", title: "Blur Texture Map", Editor: StaticBlurMap },
|
||||
];
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, Bus, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import {BlurV} from "../blurmap";
|
||||
import { BlurV } from "../blurmap";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
@ -15,14 +15,13 @@ void main () {
|
||||
gl_FragColor = vec4(vec3(
|
||||
mod(phase + atan(uv.x-0.5, uv.y-0.5)/(2.0*PI), 1.0)
|
||||
), 1.0);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const ConicalGradiantLoop = timeLoop(({ time }) =>
|
||||
<Node
|
||||
shader={shaders.ConicalGradiant}
|
||||
uniforms={{ phase: time/3000 }}
|
||||
/>);
|
||||
const ConicalGradiantLoop = timeLoop(({ time }) => (
|
||||
<Node shader={shaders.ConicalGradiant} uniforms={{ phase: time / 3000 }} />
|
||||
));
|
||||
|
||||
export default class Example extends Component {
|
||||
render() {
|
||||
@ -43,4 +42,4 @@ export default class Example extends Component {
|
||||
factor: 6,
|
||||
passes: 4,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, Bus, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -44,4 +44,4 @@ export default class Example extends Component {
|
||||
passes: 4,
|
||||
};
|
||||
};
|
||||
`
|
||||
`;
|
||||
|
||||
@ -5,10 +5,10 @@ export const desc = markdown`
|
||||
Any arbitrary shader can be used as a blur map!
|
||||
`;
|
||||
export const toolbox = [
|
||||
{ prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{ prop: "passes",
|
||||
title: value => `Blur Passes (${value})`,
|
||||
Editor: makeFloatSlider(1, 8, 1) },
|
||||
{ prop: "factor", title: "Blur", Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{
|
||||
prop: "passes",
|
||||
title: (value) => `Blur Passes (${value})`,
|
||||
Editor: makeFloatSlider(1, 8, 1),
|
||||
},
|
||||
];
|
||||
|
||||
@ -13,8 +13,8 @@ uniform sampler2D t;
|
||||
uniform vec2 offset;
|
||||
void main () {
|
||||
gl_FragColor = texture2D(t, uv + offset);
|
||||
}`
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const Offset = ({ t, offset }) => (
|
||||
@ -23,7 +23,7 @@ const Offset = ({ t, offset }) => (
|
||||
|
||||
export default class Example extends Component {
|
||||
state = {
|
||||
offset: [0, 0]
|
||||
offset: [0, 0],
|
||||
};
|
||||
render() {
|
||||
const { map } = this.props;
|
||||
@ -55,12 +55,12 @@ export default class Example extends Component {
|
||||
this.setState({
|
||||
offset: [
|
||||
-(e.clientX - rect.left - rect.width / 2) / rect.width,
|
||||
(e.clientY - rect.top - rect.height / 2) / rect.height
|
||||
]
|
||||
(e.clientY - rect.top - rect.height / 2) / rect.height,
|
||||
],
|
||||
});
|
||||
};
|
||||
onMouseLeave = () => this.setState({ offset: [0, 0] });
|
||||
static defaultProps = {
|
||||
map: StaticBlurMap.images[0]
|
||||
map: StaticBlurMap.images[0],
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, Bus, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -64,4 +64,4 @@ export default class Example extends Component {
|
||||
map: StaticBlurMap.images[0]
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -10,7 +10,5 @@ We want the "offset" framebuffer to be computed once,
|
||||
we use gl-react [\`<Bus>\`](/api#bus) concept for this.
|
||||
`;
|
||||
export const toolbox = [
|
||||
{ prop: "map",
|
||||
title: "Blur Texture Map",
|
||||
Editor: StaticBlurMap },
|
||||
{ prop: "map", title: "Blur Texture Map", Editor: StaticBlurMap },
|
||||
];
|
||||
|
||||
@ -5,25 +5,34 @@ import { Surface } from "gl-react-dom";
|
||||
import { Blur1D } from "../blurxy";
|
||||
|
||||
// empirical strategy to chose a 2d vector for a blur pass
|
||||
const NORM = Math.sqrt(2)/2;
|
||||
const NORM = Math.sqrt(2) / 2;
|
||||
export const directionForPass = (p: number, factor: number, total: number) => {
|
||||
const f = factor * 2 * Math.ceil(p / 2) / total;
|
||||
switch ((p-1) % 4) { // alternate horizontal, vertical and 2 diagonals
|
||||
case 0: return [f,0];
|
||||
case 1: return [0,f];
|
||||
case 2: return [f*NORM,f*NORM];
|
||||
default: return [f*NORM,-f*NORM];
|
||||
const f = (factor * 2 * Math.ceil(p / 2)) / total;
|
||||
switch (
|
||||
(p - 1) %
|
||||
4 // alternate horizontal, vertical and 2 diagonals
|
||||
) {
|
||||
case 0:
|
||||
return [f, 0];
|
||||
case 1:
|
||||
return [0, f];
|
||||
case 2:
|
||||
return [f * NORM, f * NORM];
|
||||
default:
|
||||
return [f * NORM, -f * NORM];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// recursively apply Blur1D to make a multi pass Blur component
|
||||
export const Blur = connectSize(({ children, factor, passes }) => {
|
||||
const rec = pass =>
|
||||
pass <= 0
|
||||
? children
|
||||
: <Blur1D direction={directionForPass(pass, factor, passes)}>
|
||||
{rec(pass-1)}
|
||||
</Blur1D>;
|
||||
const rec = (pass) =>
|
||||
pass <= 0 ? (
|
||||
children
|
||||
) : (
|
||||
<Blur1D direction={directionForPass(pass, factor, passes)}>
|
||||
{rec(pass - 1)}
|
||||
</Blur1D>
|
||||
);
|
||||
return rec(passes);
|
||||
});
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { connectSize } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -43,4 +43,4 @@ export default class Example extends Component {
|
||||
passes: 4,
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -13,10 +13,10 @@ We also vary the intensity for each pass.
|
||||
`;
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{ prop: "passes",
|
||||
title: passes => `Blur Passes (${passes})`,
|
||||
Editor: makeFloatSlider(0, 8, 1) },
|
||||
{ prop: "factor", title: "Blur", Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{
|
||||
prop: "passes",
|
||||
title: (passes) => `Blur Passes (${passes})`,
|
||||
Editor: makeFloatSlider(0, 8, 1),
|
||||
},
|
||||
];
|
||||
|
||||
@ -20,7 +20,7 @@ export default class Example extends Component {
|
||||
contrast,
|
||||
saturation,
|
||||
brightness,
|
||||
map
|
||||
map,
|
||||
} = this.props;
|
||||
return (
|
||||
<Surface width={480} height={360} pixelRatio={1}>
|
||||
@ -30,7 +30,7 @@ export default class Example extends Component {
|
||||
saturation={saturation}
|
||||
brightness={brightness}
|
||||
>
|
||||
{redraw => (
|
||||
{(redraw) => (
|
||||
<Video onFrame={redraw} autoPlay loop>
|
||||
<source type="video/mp4" src={videoMP4} />
|
||||
</Video>
|
||||
@ -38,8 +38,10 @@ export default class Example extends Component {
|
||||
</Saturate>
|
||||
</Bus>
|
||||
<BlurV map={map} passes={passes} factor={factor}>
|
||||
{// as a texture, we give a function that resolve the video ref
|
||||
() => this.refs.vid}
|
||||
{
|
||||
// as a texture, we give a function that resolve the video ref
|
||||
() => this.refs.vid
|
||||
}
|
||||
</BlurV>
|
||||
</Surface>
|
||||
);
|
||||
@ -51,6 +53,6 @@ export default class Example extends Component {
|
||||
brightness: 1,
|
||||
factor: 2,
|
||||
passes: 4,
|
||||
map: StaticBlurMap.images[0]
|
||||
map: StaticBlurMap.images[0],
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Bus } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -54,4 +54,4 @@ export default class Example extends Component {
|
||||
map: StaticBlurMap.images[0]
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -2,23 +2,23 @@ import makeFloatSlider from "../../toolbox/makeFloatSlider";
|
||||
import StaticBlurMap from "../../toolbox/StaticBlurMap";
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "contrast",
|
||||
title: "Contrast",
|
||||
Editor: makeFloatSlider(0, 2, 0.05) },
|
||||
{ prop: "saturation",
|
||||
{ prop: "contrast", title: "Contrast", Editor: makeFloatSlider(0, 2, 0.05) },
|
||||
{
|
||||
prop: "saturation",
|
||||
title: "Saturation",
|
||||
Editor: makeFloatSlider(0, 2, 0.05) },
|
||||
{ prop: "brightness",
|
||||
Editor: makeFloatSlider(0, 2, 0.05),
|
||||
},
|
||||
{
|
||||
prop: "brightness",
|
||||
title: "Brightness",
|
||||
Editor: makeFloatSlider(0, 2, 0.05) },
|
||||
{ prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{ prop: "passes",
|
||||
title: value => `Blur Passes (${value})`,
|
||||
Editor: makeFloatSlider(1, 8, 1) },
|
||||
{ prop: "map",
|
||||
title: "Blur Texture Map",
|
||||
Editor: StaticBlurMap },
|
||||
Editor: makeFloatSlider(0, 2, 0.05),
|
||||
},
|
||||
{ prop: "factor", title: "Blur", Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{
|
||||
prop: "passes",
|
||||
title: (value) => `Blur Passes (${value})`,
|
||||
Editor: makeFloatSlider(1, 8, 1),
|
||||
},
|
||||
{ prop: "map", title: "Blur Texture Map", Editor: StaticBlurMap },
|
||||
];
|
||||
export const title = "Video + multi-pass Blur + contrast/saturation/brightness";
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
//@flow
|
||||
import React, { Component } from "react";
|
||||
import {Shaders, Node, GLSL, connectSize} from "gl-react";
|
||||
import { Shaders, Node, GLSL, connectSize } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
blur1D: { // blur9: from https://github.com/Jam3/glsl-fast-gaussian-blur
|
||||
frag: GLSL`
|
||||
blur1D: {
|
||||
// blur9: from https://github.com/Jam3/glsl-fast-gaussian-blur
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
uniform sampler2D t;
|
||||
@ -23,35 +24,34 @@ vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
|
||||
}
|
||||
void main() {
|
||||
gl_FragColor = blur9(t, uv, resolution, direction);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
// This implements a blur on a single direction (x or y axis for instance)
|
||||
// connectSize will inject for us the width/height from context if not provided
|
||||
export const Blur1D =
|
||||
connectSize(({ children: t, direction, width, height }) =>
|
||||
export const Blur1D = connectSize(
|
||||
({ children: t, direction, width, height }) => (
|
||||
<Node
|
||||
shader={shaders.blur1D}
|
||||
uniforms={{ t, resolution: [ width, height ], direction }}
|
||||
/>);
|
||||
uniforms={{ t, resolution: [width, height], direction }}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
// BlurXY is a basic blur that apply Blur1D on Y and then on X
|
||||
export const BlurXY =
|
||||
connectSize(({ factor, children }) =>
|
||||
<Blur1D direction={[ factor, 0 ]}>
|
||||
<Blur1D direction={[ 0, factor ]}>
|
||||
{children}
|
||||
</Blur1D>
|
||||
</Blur1D>);
|
||||
export const BlurXY = connectSize(({ factor, children }) => (
|
||||
<Blur1D direction={[factor, 0]}>
|
||||
<Blur1D direction={[0, factor]}>{children}</Blur1D>
|
||||
</Blur1D>
|
||||
));
|
||||
|
||||
export default class Example extends Component {
|
||||
render() {
|
||||
const { factor } = this.props;
|
||||
return (
|
||||
<Surface width={400} height={300}>
|
||||
<BlurXY factor={factor}>
|
||||
https://i.imgur.com/iPKTONG.jpg
|
||||
</BlurXY>
|
||||
<BlurXY factor={factor}>https://i.imgur.com/iPKTONG.jpg</BlurXY>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import {Shaders, Node, GLSL, connectSize} from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -59,4 +59,4 @@ export default class Example extends Component {
|
||||
factor: 1,
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -5,7 +5,7 @@ export const title = "simple Blur (2-passes)";
|
||||
|
||||
export const desc = markdown`
|
||||
Implementing Blur efficiently isn't trivial.
|
||||
This approach do 2 passes *(X and Y)*
|
||||
This approach do 2 passes _(X and Y)_
|
||||
`;
|
||||
export const descAfter = markdown`
|
||||
We apply a linear blur (9 gaussian lookup)
|
||||
@ -16,7 +16,5 @@ We can see the blur quality isn't perfect,
|
||||
`;
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
{ prop: "factor", title: "Blur", Editor: makeFloatSlider(0, 8, 0.2) },
|
||||
];
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
//@flow
|
||||
import React, { Component } from "react";
|
||||
import {LinearCopy} from "gl-react";
|
||||
import { LinearCopy } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import {BlurXY} from "../blurxy";
|
||||
import { BlurXY } from "../blurxy";
|
||||
|
||||
export default class Example extends Component {
|
||||
render() {
|
||||
@ -15,7 +15,7 @@ export default class Example extends Component {
|
||||
</BlurXY>
|
||||
</LinearCopy>
|
||||
</Surface>
|
||||
// we have to wrap this in a <LinearCopy> so it upscales to the Surface size.
|
||||
// we have to wrap this in a <LinearCopy> so it upscales to the Surface size.
|
||||
);
|
||||
}
|
||||
static defaultProps = {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import {LinearCopy} from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -22,4 +22,4 @@ export default class Example extends Component {
|
||||
factor: 0.5,
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -3,7 +3,8 @@ import makeFloatSlider from "../../toolbox/makeFloatSlider";
|
||||
export const title = "simple Blur + downscale";
|
||||
export const desc = markdown`
|
||||
[BlurXY](/blurxy) allows to override width/height (\`connectSize\`),
|
||||
we can downscale the Blur to accentuate the Blur effect.`;
|
||||
we can downscale the Blur to accentuate the Blur effect.
|
||||
`;
|
||||
export const descAfter = markdown`
|
||||
It also bring better performance (less pixels to process).
|
||||
But it's still a quality tradeoff and a balance to found.
|
||||
@ -12,7 +13,5 @@ But it's still a quality tradeoff and a balance to found.
|
||||
`;
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "factor",
|
||||
title: "Blur",
|
||||
Editor: makeFloatSlider(0.2, 0.8, 0.02) },
|
||||
{ prop: "factor", title: "Blur", Editor: makeFloatSlider(0.2, 0.8, 0.02) },
|
||||
];
|
||||
|
||||
@ -15,7 +15,8 @@ void main() {
|
||||
vec4(0.0),
|
||||
step(1.0, d)
|
||||
);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
class ColoredDisc extends Component {
|
||||
@ -23,10 +24,7 @@ class ColoredDisc extends Component {
|
||||
// fromColor/toColor must be array of 3 numbers because defined as vec3 type.
|
||||
const { fromColor, toColor } = this.props;
|
||||
return (
|
||||
<Node
|
||||
shader={shaders.ColoredDisc}
|
||||
uniforms={{ fromColor, toColor }}
|
||||
/>
|
||||
<Node shader={shaders.ColoredDisc} uniforms={{ fromColor, toColor }} />
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -41,7 +39,7 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
static defaultProps = {
|
||||
fromColor: [ 1, 0, 1 ],
|
||||
toColor: [ 1, 1, 0 ],
|
||||
fromColor: [1, 0, 1],
|
||||
toColor: [1, 1, 0],
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -45,4 +45,4 @@ export default class Example extends Component {
|
||||
toColor: [ 1, 1, 0 ],
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -2,12 +2,14 @@ import Vec3ColorPicker from "../../toolbox/Vec3ColorPicker";
|
||||
import markdown from "../../markdown";
|
||||
export const toolbox = [
|
||||
{ prop: "fromColor", title: "fromColor", Editor: Vec3ColorPicker },
|
||||
{ prop: "toColor", title: "toColor", Editor: Vec3ColorPicker },
|
||||
{ prop: "toColor", title: "toColor", Editor: Vec3ColorPicker },
|
||||
];
|
||||
|
||||
export const title = "Colored Disc {fromColor, toColor} uniforms";
|
||||
|
||||
export const desc = markdown`Implement a simple radial gradient.`;
|
||||
export const desc = markdown`
|
||||
Implement a simple radial gradient.
|
||||
`;
|
||||
|
||||
export const descAfter = markdown`
|
||||
Learn more GLSL built-in functions:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,8 @@
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import colorScales from "./colorScales"; export {colorScales};
|
||||
import colorScales from "./colorScales";
|
||||
export { colorScales };
|
||||
|
||||
const shaders = Shaders.create({
|
||||
colorify: {
|
||||
@ -15,26 +16,27 @@ void main() {
|
||||
vec4 original = texture2D(children, uv);
|
||||
vec4 newcolor = texture2D(colorScale, vec2(greyscale(original.rgb), 0.5));
|
||||
gl_FragColor = vec4(newcolor.rgb, original.a * newcolor.a);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
export const Colorify =
|
||||
({ children, colorScale, interpolation }) =>
|
||||
export const Colorify = ({ children, colorScale, interpolation }) => (
|
||||
<Node
|
||||
shader={shaders.colorify}
|
||||
uniformsOptions={{ colorScale: { interpolation } }}
|
||||
uniforms={{ colorScale, children }}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
export default class Example extends Component {
|
||||
render() {
|
||||
const { interpolation, color } = this.props;
|
||||
return (
|
||||
<Surface width={400} height={300}>
|
||||
<Colorify colorScale={colorScales[color]} interpolation={interpolation}>
|
||||
https://i.imgur.com/iPKTONG.jpg
|
||||
</Colorify>
|
||||
</Surface>
|
||||
<Surface width={400} height={300}>
|
||||
<Colorify colorScale={colorScales[color]} interpolation={interpolation}>
|
||||
https://i.imgur.com/iPKTONG.jpg
|
||||
</Colorify>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
static defaultProps = {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -42,4 +42,4 @@ export default class Example extends Component {
|
||||
color: Object.keys(colorScales)[0],
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -13,20 +13,28 @@ of the image greyscale.
|
||||
`;
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "color",
|
||||
{
|
||||
prop: "color",
|
||||
title: "color scale",
|
||||
Editor: makeSelect(Object.keys(colorScales).map(cs =>
|
||||
({ key: cs, label: cs }))) },
|
||||
{ prop: "interpolation",
|
||||
Editor: makeSelect(
|
||||
Object.keys(colorScales).map((cs) => ({ key: cs, label: cs }))
|
||||
),
|
||||
},
|
||||
{
|
||||
prop: "interpolation",
|
||||
Editor: makeRadios([
|
||||
{ key: "linear", label: "linear interpolation" },
|
||||
{ key: "nearest", label: "nearest interpolation" },
|
||||
]) }
|
||||
]),
|
||||
},
|
||||
];
|
||||
|
||||
export const ToolboxFooter = ({ color, interpolation }) =>
|
||||
export const ToolboxFooter = ({ color, interpolation }) => (
|
||||
<Surface style={{ minWidth: "100%" }} width={400} height={20}>
|
||||
{ interpolation==="linear"
|
||||
? <LinearCopy>{colorScales[color]}</LinearCopy>
|
||||
: <NearestCopy>{colorScales[color]}</NearestCopy> }
|
||||
</Surface>;
|
||||
{interpolation === "linear" ? (
|
||||
<LinearCopy>{colorScales[color]}</LinearCopy>
|
||||
) : (
|
||||
<NearestCopy>{colorScales[color]}</NearestCopy>
|
||||
)}
|
||||
</Surface>
|
||||
);
|
||||
|
||||
@ -7,7 +7,7 @@ import shadertoyTex17jpg from "./shadertoy-tex17.jpg";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
desertPassage: {
|
||||
// from https://www.shadertoy.com/view/XtyGzc
|
||||
// from https://www.shadertoy.com/view/XtyGzc
|
||||
frag: GLSL`
|
||||
precision mediump float;
|
||||
varying vec2 uv;
|
||||
@ -206,10 +206,11 @@ void main() {
|
||||
u = uv;
|
||||
col = min(col, 1.)*pow( 16.0*u.x*u.y*(1.0-u.x)*(1.0-u.y) , .125);
|
||||
gl_FragColor = vec4(sqrt(clamp(col, 0., 1.)), 1);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const DesertPassage = ({ time }) =>
|
||||
const DesertPassage = ({ time }) => (
|
||||
<Node
|
||||
shader={shaders.desertPassage}
|
||||
uniforms={{
|
||||
@ -217,10 +218,12 @@ const DesertPassage = ({ time }) =>
|
||||
iChannel0: shadertoyTex17jpg,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const DesertPassageLoop = timeLoop(DesertPassage, { frameRate: 30 });
|
||||
|
||||
export default() =>
|
||||
export default () => (
|
||||
<Surface width={400} height={400}>
|
||||
<DesertPassageLoop />
|
||||
</Surface>
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -224,4 +224,4 @@ export default() =>
|
||||
<Surface width={400} height={400}>
|
||||
<DesertPassageLoop />
|
||||
</Surface>
|
||||
`
|
||||
`;
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
//@flow
|
||||
import React, { Component, PureComponent } from "react";
|
||||
import {Shaders, Node, GLSL, Bus, connectSize} from "gl-react";
|
||||
import { Shaders, Node, GLSL, Bus, connectSize } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import {DesertPassageLoop} from "../demodesert";
|
||||
import { DesertPassageLoop } from "../demodesert";
|
||||
import "./index.css";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
crt: {
|
||||
// adapted from http://bit.ly/2eR1iKi
|
||||
// adapted from http://bit.ly/2eR1iKi
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
@ -58,16 +58,17 @@ void main()
|
||||
mul_res *= dotMaskWeights;
|
||||
mul_res = pow(mul_res, vec3(1.0 / (2.0 * inputGamma - outputGamma)));
|
||||
gl_FragColor = vec4(mul_res, 1.0);
|
||||
}` },
|
||||
copy: {
|
||||
frag: GLSL`
|
||||
}`,
|
||||
},
|
||||
copy: {
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
uniform sampler2D t;
|
||||
void main(){
|
||||
gl_FragColor=texture2D(t,uv);
|
||||
}`,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
class CRT extends Component {
|
||||
@ -80,16 +81,18 @@ class CRT extends Component {
|
||||
};
|
||||
render() {
|
||||
const { children, inSize, outSize, texSize, distortion } = this.props;
|
||||
return <Node
|
||||
shader={shaders.crt}
|
||||
uniforms={{
|
||||
rubyTexture: children,
|
||||
rubyInputSize: inSize,
|
||||
rubyOutputSize: outSize,
|
||||
rubyTextureSize: texSize,
|
||||
distortion,
|
||||
}}
|
||||
/>;
|
||||
return (
|
||||
<Node
|
||||
shader={shaders.crt}
|
||||
uniforms={{
|
||||
rubyTexture: children,
|
||||
rubyInputSize: inSize,
|
||||
rubyOutputSize: outSize,
|
||||
rubyTextureSize: texSize,
|
||||
distortion,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,10 +100,12 @@ const Desert = connectSize(DesertPassageLoop);
|
||||
|
||||
class ShowCaptured extends PureComponent {
|
||||
render() {
|
||||
const {t} = this.props;
|
||||
return <Surface width={200} height={200}>
|
||||
<Node shader={shaders.copy} uniforms={{ t }} />
|
||||
</Surface>;
|
||||
const { t } = this.props;
|
||||
return (
|
||||
<Surface width={200} height={200}>
|
||||
<Node shader={shaders.copy} uniforms={{ t }} />
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,38 +125,40 @@ export default class Example extends Component {
|
||||
const { distortion } = this.props;
|
||||
const { surfacePixels, desertPixels } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<Surface ref="surface"
|
||||
width={400}
|
||||
height={400}
|
||||
webglContextAttributes={{ preserveDrawingBuffer: true }}>
|
||||
<div>
|
||||
<Surface
|
||||
ref="surface"
|
||||
width={400}
|
||||
height={400}
|
||||
webglContextAttributes={{ preserveDrawingBuffer: true }}
|
||||
>
|
||||
<Bus ref="desert">
|
||||
{/* we use a Bus to have a ref for capture */}
|
||||
<Desert width={128} height={128} />
|
||||
</Bus>
|
||||
|
||||
<Bus ref="desert">{/* we use a Bus to have a ref for capture */}
|
||||
<Desert width={128} height={128} />
|
||||
</Bus>
|
||||
<CRT
|
||||
distortion={distortion}
|
||||
texSize={[128, 128]}
|
||||
inSize={[128, 128]}
|
||||
outSize={[400, 400]}
|
||||
>
|
||||
{() => this.refs.desert}
|
||||
</CRT>
|
||||
</Surface>
|
||||
|
||||
<CRT
|
||||
distortion={distortion}
|
||||
texSize={[ 128, 128 ]}
|
||||
inSize={[ 128, 128 ]}
|
||||
outSize={[ 400, 400 ]}>
|
||||
{() => this.refs.desert}
|
||||
</CRT>
|
||||
|
||||
</Surface>
|
||||
|
||||
<div className="buttons">
|
||||
<button onClick={this.onCapture}>capture</button>
|
||||
</div>
|
||||
<div className="snaps">
|
||||
<ShowCaptured t={surfacePixels} />
|
||||
<ShowCaptured t={desertPixels} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="buttons">
|
||||
<button onClick={this.onCapture}>capture</button>
|
||||
</div>
|
||||
<div className="snaps">
|
||||
<ShowCaptured t={surfacePixels} />
|
||||
<ShowCaptured t={desertPixels} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
distortion: 0.2
|
||||
distortion: 0.2,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component, PureComponent } from "react";
|
||||
import {Shaders, Node, GLSL, Bus, connectSize} from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -155,4 +155,4 @@ export default class Example extends Component {
|
||||
distortion: 0.2
|
||||
};
|
||||
};
|
||||
`
|
||||
`;
|
||||
|
||||
@ -3,7 +3,9 @@ import makeFloatSlider from "../../toolbox/makeFloatSlider";
|
||||
export const title = "Desert Shadertoy + CRT effect + snapshot()";
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "distortion",
|
||||
{
|
||||
prop: "distortion",
|
||||
title: "Distortion",
|
||||
Editor: makeFloatSlider(0, 1, 0.01) },
|
||||
Editor: makeFloatSlider(0, 1, 0.01),
|
||||
},
|
||||
];
|
||||
|
||||
@ -6,7 +6,7 @@ import timeLoop from "../../HOC/timeLoop";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
squareTunnel: {
|
||||
// from https://en.wikipedia.org/wiki/Shadertoy
|
||||
// from https://en.wikipedia.org/wiki/Shadertoy
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
@ -20,18 +20,18 @@ void main() {
|
||||
vec3 col = 0.5 + 0.5*sin( 3.1416*f + vec3(0.0,0.5,1.0) );
|
||||
col = col*r;
|
||||
gl_FragColor = vec4( col, 1.0 );
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const SquareTunnel = ({ time }) =>
|
||||
<Node
|
||||
shader={shaders.squareTunnel}
|
||||
uniforms={{ iGlobalTime: time / 1000 }}
|
||||
/>
|
||||
const SquareTunnel = ({ time }) => (
|
||||
<Node shader={shaders.squareTunnel} uniforms={{ iGlobalTime: time / 1000 }} />
|
||||
);
|
||||
|
||||
const DesertPassageLoop = timeLoop(SquareTunnel);
|
||||
|
||||
export default() =>
|
||||
export default () => (
|
||||
<Surface width={400} height={400}>
|
||||
<DesertPassageLoop />
|
||||
</Surface>
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -35,4 +35,4 @@ export default() =>
|
||||
<Surface width={400} height={400}>
|
||||
<DesertPassageLoop />
|
||||
</Surface>
|
||||
`
|
||||
`;
|
||||
|
||||
@ -13,19 +13,18 @@ varying vec2 uv;
|
||||
uniform float red;
|
||||
void main() {
|
||||
gl_FragColor = vec4(red, uv.x, uv.y, 1.0);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const HelloGLAnimated = timeLoop( ({ time }) =>
|
||||
<Node
|
||||
shader={shaders.helloRed}
|
||||
uniforms={{ red: Math.cos(time / 100) }}
|
||||
/>
|
||||
);
|
||||
const HelloGLAnimated = timeLoop(({ time }) => (
|
||||
<Node shader={shaders.helloRed} uniforms={{ red: Math.cos(time / 100) }} />
|
||||
));
|
||||
|
||||
export default () =>
|
||||
export default () => (
|
||||
<Surface width={300} height={300}>
|
||||
<DiamondCrop>
|
||||
<HelloGLAnimated blue={0.8} />
|
||||
</DiamondCrop>
|
||||
</Surface>;
|
||||
</Surface>
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -29,4 +29,4 @@ export default () =>
|
||||
<HelloGLAnimated blue={0.8} />
|
||||
</DiamondCrop>
|
||||
</Surface>;
|
||||
`
|
||||
`;
|
||||
|
||||
@ -4,7 +4,7 @@ import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
const shaders = Shaders.create({
|
||||
DiamondCrop: {
|
||||
frag: GLSL`
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
uniform sampler2D t;
|
||||
@ -14,20 +14,20 @@ gl_FragColor = mix(
|
||||
vec4(0.0),
|
||||
step(0.5, abs(uv.x - 0.5) + abs(uv.y - 0.5))
|
||||
);
|
||||
}` },
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
export const DiamondCrop = ({ children: t }) =>
|
||||
<Node shader={shaders.DiamondCrop} uniforms={{ t }} />;
|
||||
export const DiamondCrop = ({ children: t }) => (
|
||||
<Node shader={shaders.DiamondCrop} uniforms={{ t }} />
|
||||
);
|
||||
|
||||
export default class Example extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Surface width={300} height={300}>
|
||||
<DiamondCrop>
|
||||
https://i.imgur.com/5EOyTDQ.jpg
|
||||
</DiamondCrop>
|
||||
<DiamondCrop>https://i.imgur.com/5EOyTDQ.jpg</DiamondCrop>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -31,4 +31,4 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
};
|
||||
`
|
||||
`;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import { DiamondCrop } from "../diamondcrop";
|
||||
@ -15,4 +15,4 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -33,34 +33,33 @@ void main() {
|
||||
texture2D(t, lookup(-colorSeparation * orientation, amp2)).g,
|
||||
texture2D(t, lookup(vec2(0.0), amp2)).b),
|
||||
1.0);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const Vignette = timeLoop(({ children: t, time, mouse }) =>
|
||||
const Vignette = timeLoop(({ children: t, time, mouse }) => (
|
||||
<Node
|
||||
shader={shaders.vignetteColorSeparationDistortion}
|
||||
uniforms={{
|
||||
t,
|
||||
time: time / 1000, // seconds is better for float precision
|
||||
mouse,
|
||||
freq: 10 + 2 * Math.sin(0.0007*time),
|
||||
amp: 0.05 + Math.max(0, 0.03*Math.cos(0.001 * time)),
|
||||
freq: 10 + 2 * Math.sin(0.0007 * time),
|
||||
amp: 0.05 + Math.max(0, 0.03 * Math.cos(0.001 * time)),
|
||||
moving: 0,
|
||||
}}
|
||||
/>);
|
||||
/>
|
||||
));
|
||||
|
||||
export default class Example extends Component {
|
||||
state = {
|
||||
mouse: [ 0.5, 0.5 ]
|
||||
mouse: [0.5, 0.5],
|
||||
};
|
||||
render() {
|
||||
const { mouse } = this.state;
|
||||
return (
|
||||
<Surface width={500} height={400} onMouseMove={this.onMouseMove}>
|
||||
<Vignette mouse={mouse}>
|
||||
https://i.imgur.com/2VP5osy.jpg
|
||||
</Vignette>
|
||||
<Vignette mouse={mouse}>https://i.imgur.com/2VP5osy.jpg</Vignette>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
@ -70,7 +69,7 @@ export default class Example extends Component {
|
||||
mouse: [
|
||||
(e.clientX - rect.left) / rect.width,
|
||||
(rect.bottom - e.clientY) / rect.height,
|
||||
]
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`import React, { Component } from "react";
|
||||
module.exports = `import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
@ -74,4 +74,4 @@ export default class Example extends Component {
|
||||
});
|
||||
}
|
||||
};
|
||||
`
|
||||
`;
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import markdown from "../../markdown";
|
||||
export const title = "Vignette color separation distortion + mouse";
|
||||
export const desc =
|
||||
markdown`
|
||||
export const desc = markdown`
|
||||
Crazy distortion effect on an image
|
||||
`;
|
||||
|
||||
export const descAfter =
|
||||
markdown`
|
||||
export const descAfter = markdown`
|
||||
We can listen to mouse events on the \`<Surface>\`.
|
||||
Remember that \`<Surface>\` is rendering a \`<canvas>\`
|
||||
and just forward the same React callbacks to it.
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
color: #c22;
|
||||
font-size: 10px;
|
||||
line-height: 18px;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@ -4,18 +4,20 @@ import { Node, Visitor, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
|
||||
const Preview = timeLoop(({ frag, visitor, time }) =>
|
||||
const Preview = timeLoop(({ frag, visitor, time }) => (
|
||||
<Surface width={500} height={200} visitor={visitor}>
|
||||
<Node shader={{ frag }} uniforms={{ time: time / 1000 }} />
|
||||
</Surface>);
|
||||
</Surface>
|
||||
));
|
||||
|
||||
class DisplayError extends Component {
|
||||
render() {
|
||||
const {error} = this.props;
|
||||
if (!error) return <div className="compile success">Compilation success!</div>;
|
||||
const { error } = this.props;
|
||||
if (!error)
|
||||
return <div className="compile success">Compilation success!</div>;
|
||||
let err = error.message;
|
||||
const i = err.indexOf("ERROR:");
|
||||
if (i!==-1) err = "line "+err.slice(i + 9);
|
||||
if (i !== -1) err = "line " + err.slice(i + 9);
|
||||
return <div className="compile error">{err}</div>;
|
||||
}
|
||||
}
|
||||
@ -30,22 +32,23 @@ export default class Example extends Component {
|
||||
};
|
||||
visitor.onSurfaceDrawEnd = () => this.setState({ error: null });
|
||||
this.state = { error: null, visitor };
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { frag } = this.props;
|
||||
const { error, visitor } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<Preview frag={frag} visitor={visitor} />
|
||||
<DisplayError error={error} />
|
||||
</div>
|
||||
<div>
|
||||
<Preview frag={frag} visitor={visitor} />
|
||||
<DisplayError error={error} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
props: { frag: string };
|
||||
state: { error: ?Error, visitor: Visitor };
|
||||
static defaultProps = { // adapted from http://glslsandbox.com/e#27937.0
|
||||
static defaultProps = {
|
||||
// adapted from http://glslsandbox.com/e#27937.0
|
||||
frag: GLSL`precision highp float;
|
||||
varying vec2 uv;
|
||||
|
||||
@ -67,6 +70,6 @@ void main() {
|
||||
}
|
||||
gl_FragColor = cbuff;
|
||||
}
|
||||
`
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Node, Visitor, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -70,4 +70,4 @@ void main() {
|
||||
\`
|
||||
};
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -16,7 +16,7 @@ export const toolbox = [
|
||||
color: "#ABB2BF",
|
||||
fontSize: 10,
|
||||
lineHeight: 1.5,
|
||||
fontFamily: "Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace"
|
||||
})
|
||||
}
|
||||
fontFamily: "Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
@ -17,7 +17,7 @@ float random (vec2 uv) {
|
||||
// i
|
||||
void main() {
|
||||
gl_FragColor = vec4(vec3(step(0.5, random(uv))), 1.0);
|
||||
}`
|
||||
}`,
|
||||
},
|
||||
GameOfLife: {
|
||||
// implement Game Of Life.
|
||||
@ -40,8 +40,8 @@ void main() {
|
||||
step(0.5, texture2D(t, uv + vec2( 0.0, -1.0)*c).r);
|
||||
float next = prev==1.0 && sum >= 2.0 && sum <= 3.0 || sum == 3.0 ? 1.0 : 0.0;
|
||||
gl_FragColor = vec4(vec3(next), 1.0);
|
||||
}`
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
const refreshEveryTicks = 20;
|
||||
@ -52,25 +52,27 @@ export const GameOfLife = ({ tick }) => {
|
||||
// However, we can conditionally change shader/uniforms,
|
||||
// React reconciliation will preserve the same <Node> instance,
|
||||
// and our Game of Life state will get preserved!
|
||||
return tick % refreshEveryTicks === 0
|
||||
? <Node
|
||||
shader={shaders.InitGameOfLife}
|
||||
width={size}
|
||||
height={size}
|
||||
backbuffering // makes Node holding 2 fbos that get swapped each draw time
|
||||
sync // force <Node> to draw in sync each componentDidUpdate time
|
||||
/>
|
||||
: <Node
|
||||
shader={shaders.GameOfLife}
|
||||
width={size}
|
||||
height={size}
|
||||
backbuffering
|
||||
sync
|
||||
uniforms={{
|
||||
t: Uniform.Backbuffer, // Use previous frame buffer as a texture
|
||||
size
|
||||
}}
|
||||
/>;
|
||||
return tick % refreshEveryTicks === 0 ? (
|
||||
<Node
|
||||
shader={shaders.InitGameOfLife}
|
||||
width={size}
|
||||
height={size}
|
||||
backbuffering // makes Node holding 2 fbos that get swapped each draw time
|
||||
sync // force <Node> to draw in sync each componentDidUpdate time
|
||||
/>
|
||||
) : (
|
||||
<Node
|
||||
shader={shaders.GameOfLife}
|
||||
width={size}
|
||||
height={size}
|
||||
backbuffering
|
||||
sync
|
||||
uniforms={{
|
||||
t: Uniform.Backbuffer, // Use previous frame buffer as a texture
|
||||
size,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const GameOfLifeLoop = timeLoop(GameOfLife, { refreshRate: 20 });
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React from "react";
|
||||
import { Uniform, Shaders, Node, GLSL, NearestCopy } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -82,4 +82,4 @@ export default () => (
|
||||
</NearestCopy>
|
||||
</Surface>
|
||||
);
|
||||
`
|
||||
`;
|
||||
|
||||
@ -11,5 +11,5 @@ gl-react have a \`Backbuffer\` Symbol we can pass
|
||||
as texture uniform to access previously drawn frame.
|
||||
|
||||
> gl-react hooks React lifecycle to GL draws.
|
||||
\`componentDidUpdate => gl.draw\`
|
||||
> \`componentDidUpdate => gl.draw\`
|
||||
`;
|
||||
|
||||
@ -16,7 +16,7 @@ const GameOfLifeLoop = timeLoop(
|
||||
sync
|
||||
uniforms={{
|
||||
t: tick === 0 ? gliderGunImage : Uniform.Backbuffer,
|
||||
size
|
||||
size,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
@ -31,7 +31,7 @@ export default class Example extends Component {
|
||||
height={500}
|
||||
preload={[
|
||||
// preload textures before starting rendering
|
||||
gliderGunImage
|
||||
gliderGunImage,
|
||||
]}
|
||||
>
|
||||
<NearestCopy>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Uniform, Node, NearestCopy } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -41,4 +41,4 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -8,7 +8,7 @@ export const desc = markdown`
|
||||
`;
|
||||
export const descAfter = markdown`
|
||||
Initial image state inspired from [wikipedia](https://en.wikipedia.org/wiki/Conway's_Game_of_Life).
|
||||
${<br />}
|
||||
${(<br />)}
|
||||
${(
|
||||
<a href={gliderGun64png}>
|
||||
<img
|
||||
|
||||
@ -3,7 +3,7 @@ import React from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
import {GameOfLife} from "../gol";
|
||||
import { GameOfLife } from "../gol";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
Rotating: {
|
||||
@ -19,27 +19,32 @@ void main() {
|
||||
p.x < 0.0 || p.x > 1.0 || p.y < 0.0 || p.y > 1.0
|
||||
? vec4(0.0)
|
||||
: texture2D(children, p);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
export const Rotating = ({ angle, scale, children }) =>
|
||||
export const Rotating = ({ angle, scale, children }) => (
|
||||
<Node
|
||||
shader={shaders.Rotating}
|
||||
uniformsOptions={{ children: { interpolation: "nearest" } }}
|
||||
uniforms={{ angle, scale, children }}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const RotatingLoop = timeLoop(({ time, children }) => Rotating({
|
||||
angle: (time / 1000) % (2 * Math.PI),
|
||||
scale: 0.6 + 0.15 * Math.cos(time / 500),
|
||||
children,
|
||||
}));
|
||||
const RotatingLoop = timeLoop(({ time, children }) =>
|
||||
Rotating({
|
||||
angle: (time / 1000) % (2 * Math.PI),
|
||||
scale: 0.6 + 0.15 * Math.cos(time / 500),
|
||||
children,
|
||||
})
|
||||
);
|
||||
|
||||
const GameOfLifeLoop = timeLoop(GameOfLife, { refreshRate: 5 });
|
||||
|
||||
export default () =>
|
||||
export default () => (
|
||||
<Surface width={500} height={500}>
|
||||
<RotatingLoop>
|
||||
<GameOfLifeLoop />
|
||||
</RotatingLoop>
|
||||
</Surface>;
|
||||
</Surface>
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -43,4 +43,4 @@ export default () =>
|
||||
<GameOfLifeLoop />
|
||||
</RotatingLoop>
|
||||
</Surface>;
|
||||
`
|
||||
`;
|
||||
|
||||
@ -2,11 +2,12 @@ import markdown from "../../markdown";
|
||||
export const title = "Rotating GameOfLife. 2 loops";
|
||||
export const desc = markdown`
|
||||
Compose [Game of Life][/gol] with Rotation
|
||||
\`\`\`
|
||||
|
||||
~~~
|
||||
<RotatingLoop>
|
||||
<GameOfLifeLoop />
|
||||
</RotatingLoop>
|
||||
\`\`\`
|
||||
~~~
|
||||
`;
|
||||
export const descAfter = markdown`
|
||||
GameOfLifeLoop runs at 5fps, RotatingLoop runs at full speed (60fps).
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
import React, { Component } from "react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
import {GameOfLife} from "../gol";
|
||||
import {Rotating} from "../golrot";
|
||||
import { GameOfLife } from "../gol";
|
||||
import { Rotating } from "../golrot";
|
||||
|
||||
class PureGameOfLife extends Component {
|
||||
shouldComponentUpdate ({ tick }) { // only tick should trigger redraw
|
||||
shouldComponentUpdate({ tick }) {
|
||||
// only tick should trigger redraw
|
||||
return tick !== this.props.tick;
|
||||
}
|
||||
render() {
|
||||
@ -14,14 +15,14 @@ class PureGameOfLife extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const RotatingGameOfLife = ({ time }) =>
|
||||
const RotatingGameOfLife = ({ time }) => (
|
||||
<Rotating
|
||||
angle={(time / 1000) % (2 * Math.PI)}
|
||||
scale={0.6 + 0.15 * Math.cos(time / 500)}>
|
||||
|
||||
scale={0.6 + 0.15 * Math.cos(time / 500)}
|
||||
>
|
||||
<PureGameOfLife tick={Math.floor(time / 200)} />
|
||||
|
||||
</Rotating>;
|
||||
</Rotating>
|
||||
);
|
||||
|
||||
export const RotatingGameOfLifeLoop = timeLoop(RotatingGameOfLife);
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
@ -34,4 +34,4 @@ export default class Example extends Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -28,22 +28,23 @@ void main () {
|
||||
1.0);
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
`,
|
||||
},
|
||||
});
|
||||
|
||||
const Display = ({ gol, webcam }) =>
|
||||
const Display = ({ gol, webcam }) => (
|
||||
<Node
|
||||
shader={extraShaders.Display}
|
||||
uniformsOptions={{ gol: { interpolation: "nearest" } }}
|
||||
uniforms={{
|
||||
gol,
|
||||
webcam,
|
||||
webcamRatio: Uniform.textureSizeRatio(webcam)
|
||||
webcamRatio: Uniform.textureSizeRatio(webcam),
|
||||
}}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const GameOfLife = ({ size, reset, resetTexture }) =>
|
||||
const GameOfLife = ({ size, reset, resetTexture }) => (
|
||||
<Node
|
||||
shader={shaders.GameOfLife}
|
||||
width={size}
|
||||
@ -52,12 +53,13 @@ const GameOfLife = ({ size, reset, resetTexture }) =>
|
||||
sync
|
||||
uniforms={{
|
||||
t: reset ? resetTexture : Uniform.Backbuffer,
|
||||
size
|
||||
size,
|
||||
}}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const GameOfLifeLoop = timeLoop(GameOfLife, {
|
||||
refreshRate: 4
|
||||
refreshRate: 4,
|
||||
});
|
||||
|
||||
export default class Example extends Component {
|
||||
@ -73,10 +75,11 @@ export default class Example extends Component {
|
||||
onMouseUp={this.onMouseUp}
|
||||
>
|
||||
<Bus ref="webcam">
|
||||
{redraw =>
|
||||
{(redraw) => (
|
||||
<Video onFrame={redraw} autoPlay>
|
||||
<WebCamSource />
|
||||
</Video>}
|
||||
</Video>
|
||||
)}
|
||||
</Bus>
|
||||
|
||||
<Display
|
||||
@ -95,7 +98,7 @@ export default class Example extends Component {
|
||||
onMouseDown = () =>
|
||||
this.setState({
|
||||
reset: true,
|
||||
size: Math.floor(10 + 200 * Math.random() * Math.random())
|
||||
size: Math.floor(10 + 200 * Math.random() * Math.random()),
|
||||
});
|
||||
onMouseUp = () => this.setState({ reset: false });
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Bus, Uniform, Node, Shaders, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -99,4 +99,4 @@ export default class Example extends Component {
|
||||
});
|
||||
onMouseUp = () => this.setState({ reset: false });
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -5,7 +5,8 @@ import { Surface } from "gl-react-dom";
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
gradients: { frag: GLSL`
|
||||
gradients: {
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
uniform vec4 colors[3];
|
||||
@ -23,33 +24,36 @@ void main () {
|
||||
sum.a = 1.0;
|
||||
}
|
||||
gl_FragColor = vec4(sum.a * sum.rgb, 1.0);
|
||||
}`}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Alternative syntax using React stateless function component
|
||||
const Gradients = ({ time }) =>
|
||||
const Gradients = ({ time }) => (
|
||||
<Node
|
||||
shader={shaders.gradients}
|
||||
uniforms={{
|
||||
colors: [
|
||||
[ Math.cos(0.002*time), Math.sin(0.002*time), 0.2, 1 ],
|
||||
[ Math.sin(0.002*time), -Math.cos(0.002*time), 0.1, 1 ],
|
||||
[ 0.3, Math.sin(3+0.002*time), Math.cos(1+0.003*time), 1 ]
|
||||
[Math.cos(0.002 * time), Math.sin(0.002 * time), 0.2, 1],
|
||||
[Math.sin(0.002 * time), -Math.cos(0.002 * time), 0.1, 1],
|
||||
[0.3, Math.sin(3 + 0.002 * time), Math.cos(1 + 0.003 * time), 1],
|
||||
],
|
||||
particles: [
|
||||
[ 0.3, 0.3 ],
|
||||
[ 0.7, 0.5 ],
|
||||
[ 0.4, 0.9 ]
|
||||
]
|
||||
[0.3, 0.3],
|
||||
[0.7, 0.5],
|
||||
[0.4, 0.9],
|
||||
],
|
||||
}}
|
||||
/>;
|
||||
/>
|
||||
);
|
||||
|
||||
const GradientsLoop = timeLoop(Gradients);
|
||||
|
||||
export default () =>
|
||||
export default () => (
|
||||
<Surface width={300} height={300}>
|
||||
<GradientsLoop />
|
||||
</Surface>;
|
||||
</Surface>
|
||||
);
|
||||
|
||||
// NB: don't abuse the uniforms array:
|
||||
// it's not meant to be used with lot of objects.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -54,4 +54,4 @@ export default () =>
|
||||
// NB: don't abuse the uniforms array:
|
||||
// it's not meant to be used with lot of objects.
|
||||
// GLSL 1 also don't support variable length in loops.
|
||||
`
|
||||
`;
|
||||
|
||||
@ -2,10 +2,11 @@
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
import {Motion, spring} from "react-motion";
|
||||
import { Motion, spring } from "react-motion";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
Heart: { // inspired from http://glslsandbox.com/e#29521.0
|
||||
Heart: {
|
||||
// inspired from http://glslsandbox.com/e#29521.0
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
@ -16,7 +17,7 @@ void main() {
|
||||
float scale = 1.0 - 0.1 * over - 0.8 * toggle;
|
||||
vec2 offset = vec2(0.0, -0.3 - 0.1 * over - 0.7 * toggle);
|
||||
vec2 p = scale * (2.0 * uv - 1.0 + offset);
|
||||
float a = atan(p.x, p.y) / ${Math.PI/* \o/ */};
|
||||
float a = atan(p.x, p.y) / ${Math.PI /* \o/ */};
|
||||
float r = length(p);
|
||||
float h = abs(a);
|
||||
float d = (13.0*h - 22.0*h*h + 10.0*h*h*h - 0.3 * (1.0-over))/(6.0-5.0*h);
|
||||
@ -24,8 +25,8 @@ void main() {
|
||||
vec3 t = texture2D(image, uv).rgb;
|
||||
vec3 c = mix(color * (1.0 + 0.6 * t), t, min(0.8 * over + toggle, 1.0));
|
||||
gl_FragColor = vec4(mix(vec3(1.0), c, f), 1.0);
|
||||
}`
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
class InteractiveHeart extends Component {
|
||||
@ -37,28 +38,32 @@ class InteractiveHeart extends Component {
|
||||
const { color, image } = this.props;
|
||||
const { over, toggle } = this.state;
|
||||
return (
|
||||
<Surface width={300} height={300}
|
||||
<Surface
|
||||
width={300}
|
||||
height={300}
|
||||
onClick={this.onClick}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.onMouseLeave}>
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
>
|
||||
<Motion
|
||||
defaultStyle={{ over, toggle }}
|
||||
style={{
|
||||
over: spring(over, [150, 15]),
|
||||
toggle: spring(toggle, [150, 15])
|
||||
}}>{ ({ over, toggle }) =>
|
||||
<Node
|
||||
shader={shaders.Heart}
|
||||
uniforms={{ color, image, over, toggle }}
|
||||
/>
|
||||
}</Motion>
|
||||
toggle: spring(toggle, [150, 15]),
|
||||
}}
|
||||
>
|
||||
{({ over, toggle }) => (
|
||||
<Node
|
||||
shader={shaders.Heart}
|
||||
uniforms={{ color, image, over, toggle }}
|
||||
/>
|
||||
)}
|
||||
</Motion>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () =>
|
||||
<InteractiveHeart
|
||||
color={[ 1, 0, 0 ]}
|
||||
image="https://i.imgur.com/GQo1KWq.jpg"
|
||||
/>;
|
||||
export default () => (
|
||||
<InteractiveHeart color={[1, 0, 0]} image="https://i.imgur.com/GQo1KWq.jpg" />
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -16,7 +16,7 @@ void main() {
|
||||
float scale = 1.0 - 0.1 * over - 0.8 * toggle;
|
||||
vec2 offset = vec2(0.0, -0.3 - 0.1 * over - 0.7 * toggle);
|
||||
vec2 p = scale * (2.0 * uv - 1.0 + offset);
|
||||
float a = atan(p.x, p.y) / ${Math.PI/* \\o/ */};
|
||||
float a = atan(p.x, p.y) / ${Math.PI /* \\o/ */};
|
||||
float r = length(p);
|
||||
float h = abs(a);
|
||||
float d = (13.0*h - 22.0*h*h + 10.0*h*h*h - 0.3 * (1.0-over))/(6.0-5.0*h);
|
||||
@ -62,4 +62,4 @@ export default () =>
|
||||
color={[ 1, 0, 0 ]}
|
||||
image="https://i.imgur.com/GQo1KWq.jpg"
|
||||
/>;
|
||||
`
|
||||
`;
|
||||
|
||||
@ -4,7 +4,8 @@ export const title = "Heart animation";
|
||||
|
||||
export const desc = markdown`
|
||||
gl-react can be used with any React library.
|
||||
For instance, [react-motion](https://github.com/chenglou/react-motion)'s spring animation.`;
|
||||
For instance, [react-motion](https://github.com/chenglou/react-motion)'s spring animation.
|
||||
`;
|
||||
|
||||
export const descAfter = markdown`
|
||||
If you click fastly on the Heart, react-motion nicely
|
||||
|
||||
@ -5,14 +5,15 @@ import { Surface } from "gl-react-dom";
|
||||
|
||||
const shaders = Shaders.create({
|
||||
helloBlue: {
|
||||
// uniforms are variables from JS. We pipe blue uniform into blue output color
|
||||
// uniforms are variables from JS. We pipe blue uniform into blue output color
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
uniform float blue;
|
||||
void main() {
|
||||
gl_FragColor = vec4(uv.x, uv.y, blue, 1.0);
|
||||
}` }
|
||||
}`,
|
||||
},
|
||||
});
|
||||
|
||||
// We can make a <HelloBlue blue={0.5} /> that will render the concrete <Node/>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -34,4 +34,4 @@ export default class Example extends Component {
|
||||
}
|
||||
static defaultProps = { blue: 0.5 };
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@ -2,16 +2,11 @@ import makeFloatSlider from "../../toolbox/makeFloatSlider";
|
||||
|
||||
export const title = "Hello GL blue";
|
||||
|
||||
export const desc =
|
||||
``;
|
||||
export const desc = ``;
|
||||
|
||||
export const descAfter =
|
||||
`^ Examples can have properties.
|
||||
export const descAfter = `^ Examples can have properties.
|
||||
They are injected as React props.`;
|
||||
|
||||
|
||||
export const toolbox = [
|
||||
{ prop: "blue",
|
||||
title: "Blue Color",
|
||||
Editor: makeFloatSlider(0, 1, 0.01) },
|
||||
{ prop: "blue", title: "Blue Color", Editor: makeFloatSlider(0, 1, 0.01) },
|
||||
];
|
||||
|
||||
@ -9,13 +9,15 @@ import { HelloBlue } from "../helloblue";
|
||||
// in a requestAnimationFrame loop and provide a time and tick prop
|
||||
import timeLoop from "../../HOC/timeLoop";
|
||||
|
||||
export default timeLoop(class Example extends Component {
|
||||
render() {
|
||||
const { time } = this.props;
|
||||
return (
|
||||
<Surface width={300} height={300}>
|
||||
<HelloBlue blue={0.5 + 0.5 * Math.cos(time / 500)} />
|
||||
</Surface>
|
||||
);
|
||||
export default timeLoop(
|
||||
class Example extends Component {
|
||||
render() {
|
||||
const { time } = this.props;
|
||||
return (
|
||||
<Surface width={300} height={300}>
|
||||
<HelloBlue blue={0.5 + 0.5 * Math.cos(time / 500)} />
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
|
||||
@ -19,4 +19,4 @@ export default timeLoop(class Example extends Component {
|
||||
);
|
||||
}
|
||||
});
|
||||
`
|
||||
`;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import markdown from "../../markdown";
|
||||
export const title = "Hello GL blue animated (node re-render)";
|
||||
export const desc =
|
||||
markdown`Let's animate *helloblue* !`;
|
||||
export const descAfter =
|
||||
`Not lost yet?
|
||||
export const desc = markdown`
|
||||
Let's animate _helloblue_ !
|
||||
`;
|
||||
export const descAfter = `Not lost yet?
|
||||
We will re-use some examples,
|
||||
try to not skip one!`;
|
||||
|
||||
@ -6,19 +6,19 @@ import { Surface } from "gl-react-dom";
|
||||
// in gl-react you need to statically define "shaders":
|
||||
const shaders = Shaders.create({
|
||||
helloGL: {
|
||||
// This is our first fragment shader in GLSL language (OpenGL Shading Language)
|
||||
// (GLSL code gets compiled and run on the GPU)
|
||||
// This is our first fragment shader in GLSL language (OpenGL Shading Language)
|
||||
// (GLSL code gets compiled and run on the GPU)
|
||||
frag: GLSL`
|
||||
precision highp float;
|
||||
varying vec2 uv;
|
||||
void main() {
|
||||
gl_FragColor = vec4(uv.x, uv.y, 0.5, 1.0);
|
||||
}`
|
||||
// the main() function is called FOR EACH PIXELS
|
||||
// the varying uv is a vec2 where x and y respectively varying from 0.0 to 1.0.
|
||||
// we set in output the pixel color using the vec4(r,g,b,a) format.
|
||||
// see [GLSL_ES_Specification_1.0.17](http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf)
|
||||
}
|
||||
}`,
|
||||
// the main() function is called FOR EACH PIXELS
|
||||
// the varying uv is a vec2 where x and y respectively varying from 0.0 to 1.0.
|
||||
// we set in output the pixel color using the vec4(r,g,b,a) format.
|
||||
// see [GLSL_ES_Specification_1.0.17](http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf)
|
||||
},
|
||||
});
|
||||
|
||||
export default class Example extends Component {
|
||||
@ -28,7 +28,7 @@ export default class Example extends Component {
|
||||
<Node shader={shaders.helloGL} />
|
||||
</Surface>
|
||||
);
|
||||
// Surface creates the canvas, an area of pixels where you can draw.
|
||||
// Node instanciates a "shader program" with the fragment shader defined above.
|
||||
// Surface creates the canvas, an area of pixels where you can draw.
|
||||
// Node instanciates a "shader program" with the fragment shader defined above.
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports=`//@flow
|
||||
module.exports = `//@flow
|
||||
import React, { Component } from "react";
|
||||
import { Shaders, Node, GLSL } from "gl-react";
|
||||
import { Surface } from "gl-react-dom";
|
||||
@ -32,4 +32,4 @@ export default class Example extends Component {
|
||||
// Node instanciates a "shader program" with the fragment shader defined above.
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user