How to use LinearGradient in React Native ART? - reactjs

I would like to use React Native ART to create some animated SVG graphs. My graph needs an linear gradient, I see that React Native ART seems to have it implemented, but I have no idea on how to use it.
Does anyone know or can figure it out by looking at the javascript here https://github.com/facebook/react-native/blob/master/Libraries/ART/ReactNativeART.js
I am not that good with Javascript yet unfortunately.

Here is the doc of react-native ART module LinearGradient method usage.
AFAIK,it has some touble with Android platform,here is the problem and you can track it with productpains.

I figured it out thanks to this post
You can declare the LinearGradient as such:
let colors = [ "red", "green", "blue", ];
let linearGradient = new LinearGradient(colors, 0, 20, 0, 280);
Then use it in your Shape for example:
<Shape d={path} fill={linearGradient} />
Unfortunately there doesn't seem to be support for offset % such as in d3js.

Like Hylle pointed out, I wasn't able to get percentage offset to work in Android like iOS. All the colors are just evenly spaced. But here's a trick that worked for me:
let iosColors = { '.33': '#000', '.66': '#FFF' };
let androidColors = [ '#000', '#000', '#FFF', '#FFF' ];
or a more complex example:
let iosColors = { '.2': '#000', '.8': '#FFF' };
let androidColors = [ '#000', '#000', '#555', '#AAA', '#FFF', '#FFF' ];
Basically, if you have simple enough, fixed gradient values, you can 'precalculate' the evenly-spaced values you need to get the same percentage offset effect on Android.

Related

Importing color styling in react-native component not working

I have inherited some react-native code where some styling that apparently used to work is no longer working. This is the line of code in question:
<View style={componentStyles.rightButtonContainer}>
The styling assigned looks like this:
rightButtonContainer: {
backgroundColor: config.defaultStyles.greenGradient,
justifyContent: 'center',
alignItems: 'center',
borderBottomRightRadius: 25,
borderTopRightRadius: 25,
width: "45%",
height: 50,
marginLeft: 2,
}
What's not working is the backgroundColor. Notice it is using config.defaultStyles.greenGradient. Now, the config referred to here looks like this:
import colors from '../../styles/Colors';
export default {
defaultStyles: {
greenGradient: colors.greenGradient,
}
};
The above in turn imports colors, which looks like this:
export default {
primary: 'rgb(61, 77, 138)',
secondary: 'rgb(20,169,53)',
greenGradient: ['rgba(20,169,53,1)', 'rgba(20,169,53,1)', 'rgba(20,169,53,1)', 'rgba(20,159,53,1)', 'rgba(20,159,53,1)'],
yellowGradient: ['rgba(229,169,42,1)', 'rgba(229,169,42,1)', 'rgba(229,169,42,1)', 'rgba(219,159,42,1)', 'rgba(219,159,42,1)'],
background: '#fff',
indicator: 'rgb(220, 160, 42)',
text: '#333',
textInverse: '#fff',
textPlaceholder: '#9ab',
textPlaceholderLight: '#ccc',
border:'',
borderLight: '#ccc',
};
So, it should be ultimately assigning the greenGradient color from colors, but as I say it's not working. In other words, the green colored button does not render to the screen.
NOTE: this likely stopped working after updating some libraries and the underlying Expo package. Did something change in terms of how styling is handled?
What is the issue here?
React-native doesn't support gradient. You need to use a third-party module like react-native-linear-gradient.
https://www.npmjs.com/package/react-native-linear-gradient

How to make a div shake from side to side with react spring

I have started playing around with react-spring and I am loving the concept but I am struggling to work out how to build the animation that I want.
I would like to make a div move to the right, then back to start, then to the right, but not as far, back to start, to the right, but not as far again and finally back to start. Just like a spring, that is pulled and when released goes boingoingoing back to it's resting place.
I can see from the documentation how to adjust the feel of the spring and how to trigger the animation, but I have never made an animation before so knowing which properties to change and how to make it loop properly are what I am looking for help on.
Edit: I have this animation so far, and it works, but it feels very disjointed.
const shake = useSpring({
from: { "margin-left": 0 },
to: [
{ "margin-left": 30 },
{ "margin-left": 0 },
{ "margin-left": 20 },
{ "margin-left": 0 },
{ "margin-left": 10 },
{ "margin-left": 0 }
],
config: {
mass: 1,
tension: 500,
friction: 10
}
});
Currently it is clearly three movements, can I decrease the delay between the movements so that it looks like one movement?
Is margin left the best CSS property to use?
UPDATE START
I just came across a simple solution for this problem. It I way better than the one I tried to achieve with configuration. It uses interpolation with range. It is using transform now but can easily adopted to margin.
export default function App() {
const { x } = useSpring({
from: { x: 0 },
to: { x: 1 }
});
return (
<div className="App">
<animated.div
style={{
transform: x
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [180, 220, 180, 220, 180, 220, 180, 200]
})
.interpolate(x => `translate3d(${x}px, 0px, 0px)`)
}}
>
Shake
</animated.div>
</div>
);
}
https://codesandbox.io/s/awesome-framework-go5oh?file=/src/App.js:103-609
UPDATE END*
You can achieve the bouncy effect. There are 3 variable controlling the spring based animation:
mass
friction
tension
You can play with the pink square here: https://www.react-spring.io/docs/hooks/api
I recommend low mass and friction and high tension. You can set these variable in every animation type. For example:
useSpring({ ..., config: {mass: 1, tension: 500, friction: 10} });

React Native - What is the difference between StyleSheet.absoluteFill() and StyleSheet.absoluteFillObject()?

The documentation provided an example for StyleSheet.absoluteFillObject() whose behavior is also same while using with StyleSheet.absoluteFill():
const styles = StyleSheet.create({
wrapper: {
...StyleSheet.absoluteFillObject,
top: 10,
backgroundColor: 'transparent',
},
});
What is the difference between StyleSheet.absoluteFill() and StyleSheet.absoluteFillObject()? A little example will be more appreciated. Thanks !!!
absoluteFill is an easy way to set a view to be full screen and absolute positioned. It’s a short cut for:
{
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0
}
Use it to extend your other styles like this:
const styles = StyleSheet.create({
container: {
backgroundColor: 'red'
}
});
<View style={[StyleSheet.absoluteFill, styles.container]} />
absoluteFillObject
Say you want to absolute position your view, but bump it down 20px to offset for the status bar (for example).
You can spread StyleSheet.absoluteFillObject into your style and then override one of it’s values.
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
top: 20,
backgroundColor: 'red'
}
});
<View style={styles.container} />
There is no difference between those two. You can see this in StyleSheet.js:
/**
* A very common pattern is to create overlays with position absolute and zero positioning,
* so `absoluteFill` can be used for convenience and to reduce duplication of these repeated
* styles.
*/
absoluteFill: (absoluteFill: any), // TODO: This should be updated after we fix downstream Flow sites.
/**
* Sometimes you may want `absoluteFill` but with a couple tweaks - `absoluteFillObject` can be
* used to create a customized entry in a `StyleSheet`, e.g.:
*
* const styles = StyleSheet.create({
* wrapper: {
* ...StyleSheet.absoluteFillObject,
* top: 10,
* backgroundColor: 'transparent',
* },
* });
*/
absoluteFillObject: absoluteFill,
I may be late for the party. But there is some difference between absoluteFill and absoluteFillObject in typescript.
Mainly in typescript, the type of:
absoluteFill is RegisteredStyle<StyleSheet.AbsoluteFillStyle>
absoluteFillObject is StyleSheet.AbsoluteFillStyle
const styles = StyleSheet.create({
container: {
// must use "absoluteFillObject" in typescript
...StyleSheet.absoluteFillObject,
}
})
For JavaScript, there is no difference.
As of version 0.62, no difference at all according to the official document
In case you are using EXPO Snack like I do, the absoluteFill preview on web seems buggy at this time. On a real device, it should be fine.
Currently, there is no difference between using absoluteFill vs. absoluteFillObject.
I've tried to print the value of absoluteFill and absoluteFillObject.
They're no difference. They're the same value.
[LOG] absoluteFill: {"bottom": 0, "left": 0, "position": "absolute", "right": 0, "top": 0}
[LOG] absoluteFillObject: {"bottom": 0, "left": 0, "position": "absolute", "right": 0, "top": 0}
Currently (React Native 0.66), the documentation states:
there is no difference between using absoluteFill vs. absoluteFillObject.

Openlayers ol.interaction.Draw stroke style

I have the this jsfiddle, it has the ability to draw a polygon on a map which works perfectly. What I can't figure out is how to style the .Draw interaction.
Currently I have a dashed line for the sections of the polygon that the users has already draw and another dashed line connecting the first drawn point to the last drawn point.
When I write styles it seems to effect both lines.
What I need to have is a dashed black line joining points the user has already drawn, and no line (fully transparent) for the line connecting the last drawn point back to the first drawn point.
This is my current style object:
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 0.5)',
lineDash: [10, 10],
width: 3
}),
image: new ol.style.Circle({
fill: new ol.style.Fill({ color: [0, 0, 0, 0.2] }),
stroke: new ol.style.Stroke({
color: [0, 0, 0, 0.5],
width: 1
}),
radius: 4
})
})
I have tried adding arrays of colours and styles but can't seem to get it working.
Has anyone come across this and found a fix?
Ok I have cracked this one, I had to take a dive into the library's source to figure it out, so I'm gonna post the answer here in the hope it helps somebody else in the future, so here goes:
What I could see looking as the source code was that when you are using ol.interaction.Draw to draw a polygon there are multiple pieces of geometry being used. There is the underlying Polygon, this is the bit that has a stroke and fill and shows the connecting line (based on it's stroke style). There is a LineString which shows a line for the points the user has drawn only (no fill and no connecting line). And there is a point, which is attached to the mouse pointer. I have left a `console.log()' in the jsfiddle to show all this.
I have created this working jsfiddle. What I have done is, rather than set the styles directly inside ol.interaction.Draw I have used a styleFunction (see code below). I detect each geometry by type and set a specific style for it.
const styleFunction = feature => {
var geometry = feature.getGeometry();
console.log('geometry', geometry.getType());
if (geometry.getType() === 'LineString') {
var styles = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(255, 102, 0, 1)',
width: 3
})
})
];
return styles;
}
if (geometry.getType() === 'Polygon') {
var styles = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(255, 102, 0, 0)',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(255, 102, 0, 0.3)'
})
})
];
return styles;
}
return false;
};
Hope this helps 🤓

How to set a three color gradient in a qooxdoo widgets decorator?

I want to set a three color gradient in a qooxdoo widgets decorator. The relevant CSS is
linear-gradient(rgba(255,255,255,0.2) 0,
rgba(255,255,255,0.8) 30px,
rgba(255,255,255,0.6) 100%);
I wan't to achieve the hover effect in the icons in this page http://njdesktop.nagyervin.eu/
What I tried so far:
in my theme.Color file I defined three colors
"desktop-icon-top": qx.core.Environment.get("css.rgba") ? "rgba(255, 255, 255, 0.2)" : "white",
"desktop-icon-middle": qx.core.Environment.get("css.rgba") ? "rgba(255, 255, 255, 0.8)" : "white",
"desktop-icon-end": qx.core.Environment.get("css.rgba") ? "rgba(255, 255, 255, 0.6)" : "white"
but qx.ui.decoration.MLinearBackgroundGradient has properties only for gradient start and gradient end. Not for the middle.
I also tried to set it directly in the styles of theme.Decoration
"desktop-icon-hovered": {
style: {
radius: 5,
width: 2,
backgroundColor: "transparent",
color: "white",
// gradientStart: ["desktop-icon-middle", 30],
// gradientEnd: ["desktop-icon-end", 70]
backgroundImage: "linear-gradient(rgba(255,255,255,0.2) 0,rgba(255,255,255,0.8) 30px,rgba(255,255,255,0.6) 100%)"
}
but this doesn't render a gradient at all.
The only way I can do this is by using setStyle() in code but this means I will have to mess with event listeners and I won't be taking advantage of the decorator mechanism. Plus it feels ugly.
So how can I use three colors decorator in the Decoration.js?
If you are not worried about backward compatibility with older browsers then this should work:
Qooxdoo Playground Example
Put simply, you first create a Decorator Mixin that creates a property for your app code to access using the decorator mechanism.
Within your Application code you then include the new Mixin into your app's decorator class.
Run the generate.py source on your app. Then set your controls decorator property either directly or via the Decoration class and your set.

Resources