ReglFrame color not persisting across React redraw calls
Closed this issue · 6 comments
I'm testing the basic triangle example and noticed that the background color (green in this example) is respected when I render the react component for the first time, but if I change the react component color prop (e.g. on a button click to trigger a re-render in react), the triangle color changes as expected, but the ReglFrame background color turns black (instead of green).
<ReglFrame width={width} height={height} color={[0, 1, 0, 1]}>
<Triangle color={props.color}/>
</ReglFrame>
Also, this may be a separate issue, but alpha in ReglFrame's color doesn't affect anything in the frame background. Is there a way to enable alpha support?
@gouldingken can you post a fuller reproduction example with the click handler? think this is probably related to #31
re: alpha
What are your expectations here? Trying to understand. When you set an alpha value of the color
prop it would effect the transparency of the ReglFrame
component?
Yes - in my case I want the canvas overlaid on an image so the image shows through. Digging into the code a little, it looks like you're setting "alpha" to false when creating the WebGL context (ReglFrame.tsx line 40). I think premultipliedAlpha also needs to be set to false for my use case. Perhaps a more generic solution would be to allow passing custom settings to the "getContext" call? I'm not sure if additional REGL options would also need to be configured.
I can post a fuller example. Is there a platform for sharing example code (e.g. JSFiddle/CodePen) that will work with React-Regl setup? Code is below for now:
ColorizerCanvas.js
import React from 'react';
import regl, {ReglFrame} from 'react-regl';
import {observer} from "mobx-react";
const Triangle = regl({
vert: `
precision mediump float;
attribute vec2 position;
void main () {
gl_Position = vec4(position, 0, 1);
}`,
frag: `
precision mediump float;
uniform vec4 color;
void main () {
gl_FragColor = color;
}`,
attributes: {
position: [
[-1, 0],
[0, -1],
[1, 1]
]
},
uniforms: {
color: regl.prop('color')
},
count: 3
});
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function hexToArr(color) {
const {r, g, b} = hexToRgb(color);
return [r / 255, g / 255, b / 255, 0.5];
}
const ColorizerCanvas = ({color, width, height}) => {
return (//TODO figure out why background color doesn't persist
<ReglFrame width={width} height={height} color={[0, 1, 0, 1]}>
<Triangle color={hexToArr(color)}/>
</ReglFrame>
);
};
export default observer(ColorizerCanvas);
ColorizerStage.js
import React from 'react';
import {observer} from "mobx-react";
import ColorizerStack from "./ColorizerStack";
const ColorizerStage = ({store}) => {
return (
<div>
{store.colors.map((color, i) => <div>{color}</div>)}
<button onClick={() => store.shiftColors()}>
NEXT
</button>
{store.colors.map((color, i) => <ColorizerStack key={i} color={color}/>)}
</div>
);
};
export default observer(ColorizerStage);
ColorizerStack.js
import React from 'react';
import {observer} from "mobx-react";
import ColorizerCanvas from "./ColorizerCanvas";
const ColorizerStack = ({color}) => {
const width = 400;
const height = 300;
return (
<div className={'ColorizerStack'} style={{width, height}}>
<img src={`https://picsum.photos/${width}/${height}`}/>
<ColorizerCanvas color={color} width={width} height={height}/>
</div>
);
};
export default observer(ColorizerStack);
MainStore.ts
import {action, autorun, computed, observable} from "mobx";
export default class MainStore {
@observable scale = 0.8;
@observable colors = [
'#339988',
'#993388',
'#3388FF',
'#b1984c',
];
@action
setScale(n:number) {
this.scale = n;
}
@action
shiftColors() {
if (this.colors.length === 0) return;
this.colors.push(this.colors.shift() || '');
}
}
Yes - in my case I want the canvas overlaid on an image so the image shows through. Digging into the code a little, it looks like you're setting "alpha" to false when creating the WebGL context (ReglFrame.tsx line 40). I think premultipliedAlpha also needs to be set to false for my use case. Perhaps a more generic solution would be to allow passing custom settings to the "getContext" call? I'm not sure if additional REGL options would also need to be configured.
Ok yes this is a good idea the ReglFrame
component should take some additional props to pass into getContext
I can post a fuller example. Is there a platform for sharing example code (e.g. JSFiddle/CodePen) that will work with React-Regl setup? Code is below for now:
You could create a Pull request branch, that puts the code in the storybook and then I could review it and edit it as a story.
context props published in 4.3.2
Not sure if a pull request makes sense for a temporary example, but here's a fork with an example included. This also demonstrates animating via react props and testing the new transparency capabilities (via <ReglFrame webGLContext={{alpha: true, premultipliedAlpha: false}}
)
https://github.com/gouldingken/react-regl/tree/issue-36-story
merged a fix in #39. published in 4.3.3. It might have unintended side effects but think it fixes this case.
Thanks for the demonstration PR. let me know if that works for you