Css градиент, где значения цвета получены из реквизита элемента - PullRequest
1 голос
/ 15 февраля 2020

Я рендеринг карт данных для покемонов. Каждый тип покемонов имеет связанный цвет. Огонь красный, вода голубая, трава зеленая. У некоторых покемонов есть один тип, у некоторых покемонов есть 2 типа.

Я хочу, чтобы цвет фона был либо solid, если у покемона есть один тип, но сложная часть: я хочу, чтобы фон был градиентом, если покемон имеет два типа. Например, у покемона Огня будет красный фон solid, тогда как у покера воды / травы будет градиент сине-зеленого цвета.

Существует 18 типов покемонов. Всего 324 комбинации. Я знаю, что могу жестко закодировать классы для каждой комбинации .fire-ice {colors}, но должно быть лучшее решение.

Как достичь этого программно? Я использую sass и реагирую

Ответы [ 2 ]

0 голосов
/ 15 февраля 2020

Вы можете сделать это, установив стиль (CSS) для вашего элемента динамически на основе пропущенных реквизитов. Вам просто нужно сопоставить тип Pokemon с цветом, а затем просто проверить, существует ли только один тип или два, и использовать его для установки background-color или background-image (с использованием линейного градиента).

Например:

const POKEMON_TYPES = {
    FIRE: "Fire",
    WATER: "Water",
    GRASS: "Grass",
}


const POKEMON_TYPE_COLORS = {
    [POKEMON_TYPES.FIRE]: "#ff0000",
    [POKEMON_TYPES.WATER]: "#0000ff",
    [POKEMON_TYPES.GRASS]: "#00ff00",
}


const App = () => {
    return (
        <div>
            <PokemonCard name="Fire Only" types={ [POKEMON_TYPES.FIRE] }/>
            <PokemonCard name="Fire And Water" types={ [POKEMON_TYPES.FIRE, POKEMON_TYPES.WATER] }/>
            <PokemonCard name="Water And Grass" types={ [POKEMON_TYPES.WATER, POKEMON_TYPES.GRASS] }/>
        </div>
    )
}


const PokemonCard = props => {
    const { name, types } = props;

    let style;
    if (types.length === 2) {
        const typeColor1 = POKEMON_TYPE_COLORS[types[0]];
        const typeColor2 = POKEMON_TYPE_COLORS[types[1]];
        style = {"backgroundImage": `linear-gradient(45deg, ${typeColor1}, ${typeColor2})`};
    } else {
        const typeColor = POKEMON_TYPE_COLORS[types[0]];
        style = {"backgroundColor": typeColor};
    }

    return (
        <div className="pokemon-card" style={ style }>
            { name }
        </div>
    )
}


ReactDOM.render(<App/>, document.querySelector("#root"));
.pokemon-card {
    color: #fff;
    width: 10rem;
    height: 5rem;
    padding: .75rem 1rem;
    margin-bottom: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="root"/>

Вы можете добавить обработку для сортировки типов, чтобы каждая комбинация всегда отображалась одинаково (без переворотов). Также вы можете рассмотреть возможность использования type и types в качестве отдельного реквизита (не уверен, как вы его настроили в настоящее время), но должно быть ясно, как сделать это изменение.

Вы также можете установить цвет текста по-разному в зависимости от цвета фона, этот пост может быть полезен для вас: { ссылка }.

0 голосов
/ 15 февраля 2020

1 - Настройка объекта для сопоставления power:color.

2 - Превратить массив мощностей покемонов в массив цветов и присоединить его к строке

3 - поместите строку цветов внутри background:linear-gradient(...) встроенный стиль

Посмотрите на код ниже:

 const colors = {
  grass: 'green',
  fire: 'red',
  water: 'blue'
 }
 function getColor(powers){
  if(powers.length === 1) return colors[powers[0]];
  return 'linear-gradient('+powers.map(p=> colors[p]).join()+')';
 }

 // testing..
 const powers = [
  ['grass'],
  ['fire','water'],
  ['fire'],
  ['fire','water','grass']
 ];
 powers.forEach(p => console.log(getColor(p)));

для реакции, используйте <div style={{background: getColor(this.props.powers)}}/>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...