【问题标题】:Css gradient where color values are derived from element propsCss渐变,其中颜色值来自元素道具
【发布时间】:2020-02-15 00:29:01
【问题描述】:

我正在为 Pokemon 渲染数据卡。每个口袋妖怪类型都有一个相关的颜色。火是红色的,水是蓝色的,草是绿色的。有些口袋妖怪有一种类型,有些口袋妖怪有两种类型。

如果口袋妖怪有一种类型,我希望背景颜色是纯色,但棘手的部分是如果口袋妖怪有两种类型,我希望背景是渐变色。例如,火系宝可梦的背景为纯红色,而水/草系宝可梦的背景为蓝/绿渐变。

有 18 种口袋妖怪类型。共有 324 种组合。我知道我可以为每个组合 .fire-ice{colors} 硬编码类,但必须有更好的解决方案。

如何以编程方式实现这一目标?我正在使用 sass 并做出反应

【问题讨论】:

  • 始终考虑 2 种颜色,如果是一种类型,则两种颜色相同,因此您将始终以两种颜色的渐变结束,您可以轻松设置内联或使用 CSS 变量

标签: javascript css reactjs sass gradient


【解决方案1】:

1 - 设置一个对象来映射power:color

2 - 将 pokemon powers 数组转换为 colors 数组并将其连接到一个字符串中

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)}}/>

【讨论】:

    【解决方案2】:

    您可以通过根据传递的道具动态设置元素的样式 (CSS) 来做到这一点。您只需要从 Pokemon 类型到颜色的映射,然后只需检查是否只有一种或两种类型,然后使用它来设置 background-colorbackground-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"/>

    您可能希望添加处理以首先对类型进行排序,以便每个组合始终显示相同(不翻转)。您也可以考虑使用typetypes 作为单独的道具(不确定您目前是如何设置的),但应该清楚如何进行更改。

    您可能还想根据背景颜色设置不同的文本颜色,这篇文章可能对您有所帮助:https://stackoverflow.com/a/3943023/8068625

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 2016-10-10
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      相关资源
      最近更新 更多