Skip to content

Commit

Permalink
[RNMobile] Refactor native gradient logic (#27307)
Browse files Browse the repository at this point in the history
* Refactor native gradient logic

* Make using 'length' conditional in serializing

* Move fixing logic directly to serializeGradientPosition

* Remove global from regex
  • Loading branch information
lukewalczak authored and cameronvoell committed Nov 27, 2020
1 parent f058d9f commit 14eb04e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 10 deletions.
6 changes: 3 additions & 3 deletions packages/components/src/color-palette/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ function ColorPalette( {
customIndicatorWrapperStyles,
} ) {
const customSwatchGradients = [
'linear-gradient(120deg, rgba(255,0,0,.8), 0%, rgba(255,255,255,1) 70.71%)',
'linear-gradient(240deg, rgba(0,255,0,.8), 0%, rgba(0,255,0,0) 70.71%)',
'linear-gradient(360deg, rgba(0,0,255,.8), 0%, rgba(0,0,255,0) 70.71%)',
'linear-gradient(120deg, rgba(255,0,0,.8) 0%, rgba(255,255,255,1) 70.71%)',
'linear-gradient(240deg, rgba(0,255,0,.8) 0%, rgba(0,255,0,0) 70.71%)',
'linear-gradient(360deg, rgba(0,0,255,.8) 0%, rgba(0,0,255,0) 70.71%)',
];

const scrollViewRef = useRef();
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/custom-gradient-picker/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ export function serializeGradientColor( { type, value } ) {
return `${ type }(${ value.join( ',' ) })`;
}

export function serializeGradientPosition( { type, value } ) {
export function serializeGradientPosition( position ) {
if ( ! position ) {
return '';
}
const { value, type } = position;
return `${ value }${ type }`;
}

Expand Down
68 changes: 62 additions & 6 deletions packages/components/src/mobile/gradient/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { View, Platform } from 'react-native';
import RNLinearGradient from 'react-native-linear-gradient';
import gradientParser from 'gradient-parser';
/**
* WordPress dependencies
*/
Expand All @@ -16,17 +17,72 @@ import { useResizeObserver } from '@wordpress/compose';
import styles from './style.scss';

function getGradientAngle( gradientValue ) {
const matchDeg = /(\d+)deg/g;
const matchAngle = /\(((\d+deg)|(to\s[^,]+))/;
const angle = matchAngle.exec( gradientValue )[ 1 ];
const angleBase = 45;

return Number( matchDeg.exec( gradientValue )[ 1 ] );
const angleType = angle.includes( 'deg' ) ? 'angle' : 'sideOrCorner';

if ( angleType === 'sideOrCorner' ) {
switch ( angle ) {
case 'to top':
return 0;
case 'to top right':
case 'to right top':
return angleBase;
case 'to right':
return 2 * angleBase;
case 'to bottom right':
case 'to right bottom':
return 3 * angleBase;
case 'to bottom':
return 4 * angleBase;
case 'to bottom left':
case 'to left bottom':
return 5 * angleBase;
case 'to left':
return 6 * angleBase;
case 'to top left':
case 'to left top':
return 7 * angleBase;
}
} else if ( angleType === 'angle' ) {
return parseFloat( angle );
} else return 180;
}

function getGradientColorGroup( gradientValue ) {
const matchColorGroup = /(rgba|rgb|#)(.+?)[\%]/g;
const colorNeedParenthesis = [ 'rgb', 'rgba' ];

const excludeSideOrCorner = /linear-gradient\(to\s+([a-z\s]+,)/;

// Parser has some difficulties with angle defined as a side or corner (e.g. `to left`)
// so it's going to be excluded in order to matching color groups
const modifiedGradientValue = gradientValue.replace(
excludeSideOrCorner,
'linear-gradient('
);

return [].concat(
...gradientParser.parse( modifiedGradientValue )?.map( ( gradient ) =>
gradient.colorStops?.map( ( color, index ) => {
const { type, value, length } = color;
const fallbackLength = `${
100 * ( index / ( gradient.colorStops.length - 1 ) )
}%`;
const colorLength = length
? `${ length.value }${ length.type }`
: fallbackLength;

return gradientValue
.match( matchColorGroup )
.map( ( color ) => color.split( ' ' ) );
if ( colorNeedParenthesis.includes( type ) ) {
return [ `${ type }(${ value.join( ',' ) })`, colorLength ];
} else if ( type === 'literal' ) {
return [ value, colorLength ];
}
return [ `#${ value }`, colorLength ];
} )
)
);
}

function getGradientBaseColors( gradientValue ) {
Expand Down

0 comments on commit 14eb04e

Please sign in to comment.