Реагировать на собственный линейный градиент Закругленный край зерна - PullRequest
0 голосов
/ 03 января 2019

Как видно на изображении, первый круг приводит к тому, что грань граната, второй круг №.

Второй круг создается с помощью: LinearGradient di expo, "response-native-community".

Первый круг сделан с использованием js-кода, который вы найдете написанным ниже, речь идет о rn-градиентах, о которых я сообщил код по причинам, чтобы лучше понятьоперация состоит в том, чтобы решить эту проблему.

Я пытался сделать много попыток, но я не мог решить эту проблему.

Я хотел бы попытаться решить эту проблему, потому что модуль очень легкий по сравнениюк тому, чтобы реагировать на нативное сообщество, и тогда не нужно связывать.

Может кто-нибудь дать мне несколько советов?

Ссылка: Экспо

Код:

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { LinearGradient } from './rn-gradients/index.js';
import { LinearGradient as LinearGradient2 } from 'expo';

export default class App extends Component {
  render() {
    var size = 80;
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: '#000',
        }}>
        <LinearGradient
          colors={['#8a49a1', '#c1558b', '#e56969', '#ffc273', '#ffdf9e']}
          height={size}
          width={size}
          rotation={90}
          style={{
            borderRadius: size / 2,
            alignItems: 'center',
            justifyContent: 'center',
          }}>
          <Text
            style={{
              fontSize: 10,
            }}>
            LinearGradient
          </Text>
        </LinearGradient>
        <LinearGradient2
          colors={['#8a49a1', '#c1558b', '#e56969', '#ffc273', '#ffdf9e']}
          height={size}
          width={size}
          rotation={90}
          style={{
            borderRadius: size / 2,
            marginTop: 10,
            alignItems: 'center',
            justifyContent: 'center',
          }}>
          <Text
            style={{
              fontSize: 10,
            }}>
            LinearGradient2
          </Text>
        </LinearGradient2>
      </View>
    );
  }
}

LinearGradient:

import React from 'react';
import PropTypes from 'prop-types';
import { View, StyleSheet, Animated, Dimensions } from 'react-native';
//const {height as heightD, width as widthD} = Dimensions.get('window');
import { normalizeIntervals, degToRad } from './utils';

const { hairlineWidth } = StyleSheet;
const doubleHairlineWidth = hairlineWidth * 2;
const negativeHairlineWidth = -hairlineWidth;

export default class LinearGradient extends React.Component {
  render() {
    const { style, height, width, colors, children } = this.props;
    let { intervals, rotation } = this.props;

    rotation %= 360; // set rotation greater than 360° to its less than 360° equivalent

    if (rotation < 0) {
      rotation = 360 + rotation; // set negative rotation to its positive equivalent
    }

    let normalizedRotation = rotation;
    let scaleX = 1;
    let scaleY = 1;

    if (rotation >= 90) {
      if (rotation <= 180) {
        normalizedRotation = 180 - normalizedRotation;
        scaleY = -1;
      } else if (rotation < 270) {
        normalizedRotation %= 90;
        scaleX = -1;
        scaleY = -1;
      } else if (rotation < 360) {
        normalizedRotation = 360 - normalizedRotation;
        scaleX = -1;
      }
    }

    const sin1 = Math.sin(degToRad(90 - normalizedRotation));
    const sin2 = Math.sin(degToRad(normalizedRotation));
    const gradientYLength = height * sin1 + width * sin2;
    const gradientXLength = width * sin1 + height * sin2;
    const gradientArrayLength = Math.ceil(gradientYLength / hairlineWidth);
    const normalIntervals = normalizeIntervals(
      intervals,
      colors,
      gradientArrayLength
    );

    return (
      <View
        style={[style, { height, width, overflow: 'hidden' }]}>
        <View style={styles.container}>
          <View
            style={{
              transform: [
                { scaleX },
                { scaleY },
                { rotate: `${normalizedRotation}deg` },
              ],
            }}>
            {[...Array(gradientArrayLength)].map((_, i) => {
              return (
                <Animated.View
                  key={i}
                  style={{
                    height: doubleHairlineWidth,
                    marginTop: negativeHairlineWidth,
                    width: gradientXLength,
                    backgroundColor: new Animated.Value(i).interpolate({
                      inputRange: normalIntervals,
                      outputRange: colors,
                    }),
                  }}
                />
              );
            })}
          </View>
        </View>
        {children}
      </View>
    );
  }
}

LinearGradient.defaultProps = {
  height: 5,
  width: 5,
  rotation: 0,
};

LinearGradient.propTypes = {
  height: PropTypes.any,
  width: PropTypes.any,
  colors: PropTypes.arrayOf(PropTypes.string).isRequired,
  intervals: PropTypes.arrayOf(PropTypes.number),
  rotation: PropTypes.number, // in degrees - NOT radians.
};

const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFill,
    justifyContent: 'center',
    alignItems: 'center',
    //overflow: 'hidden',
  },
});

утилит:

export function normalizeIntervals(intervals, colors, gradientArrayLength) {
  if (intervals) {
    if (intervals.length !== colors.length) {
      throw new Error('intervals.length should be equal to colors.length');
    }
    if (!intervals.every((e, i, a) => !i || e > a[i - 1])) {
      throw new Error(
        'Each consecutive interval must be greater than the previous one'
      );
    }
  } else if (!intervals) {
    const { length } = colors;
    intervals = [...Array(length)].map((_, i) => i / (length - 1));
  }

  return intervals.map(num => num * (gradientArrayLength - 1));
}

const DEG_PER_RAD = Math.PI / 180;
export const degToRad = deg => deg * DEG_PER_RAD;

export const getHypotenuse = (a, b) => Math.sqrt(a ** 2 + b ** 2);
...