css3 mix-blend-mode属性的学习总结

192 阅读2分钟

mix-blend-mode 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。

const mixBlendModeEnum = new Map([
    ['normal', '正常'],
    ['multiply', '正片叠底'],
    ['screen', '滤色'],
    ['overlay', '叠加'],
    ['darken', '变暗'],
    ['lighten', '变亮'],
    ['color-dodge', '颜色减淡'],
    ['color-burn', '颜色加深'],
    ['hard-light', '强光'],
    ['soft-light', '柔光'],
    ['difference', '差值'],
    ['exclusion', '排除'],
    ['hue', '色相'],
    ['saturation', '饱和度'],
    ['color', '颜色'],
    ['luminosity', '亮度'],
    ['initial', '初始'],
    ['inherit', '继承'],
    ['unset', '复原'],
]);

以下为不同混合模式效果 image.png

const colorList = [{
  label: '正常',
  value: 'normal',
  foreColor: '#d78c33',
  bgColor: '#075ecb',

}, {
  label: '正片叠底',
  value: 'multiply',
  foreColor: '#e43535',
  bgColor: '#075ecb',
}, {
  label: '滤色',
  value: 'screen',
  foreColor: '#7009e9',
  bgColor: '#075ecb',

}, {
  label: '叠加',
  value: 'overlay',
  foreColor: '#fff7ef',
  bgColor: '#075ecb',

}, {
  label: '变暗',
  value: 'darken',
  foreColor: '#d78c33',
  bgColor: '#075ecb',

}, {
  label: '变亮',
  value: 'lighten',
  foreColor: '#a94cf8',
  bgColor: '#075ecb',

}, {
  label: '颜色减淡',
  value: 'color-dodge',
  foreColor: '#c0c770',
  bgColor: '#075ecb',

}, {
  label: '颜色加深',
  value: 'color-burn',
  foreColor: '#f0e301',
  bgColor: '#075ecb',
}, {
  label: '强光',
  value: 'hard-light',
  foreColor: '#8b1b7c',
  bgColor: '#075ecb',

}, {
  label: '柔光',
  value: 'soft-light',
  foreColor: '#f7f1e3',
  bgColor: '#075ecb',

}, {
  label: '差值',
  value: 'difference',
  foreColor: '#0671f1',
  bgColor: '#075ecb',

}, {
  label: '排除',
  value: 'exclusion',
  foreColor: '#2080f1',
  bgColor: '#075ecb',

}, {
  label: '色相',
  value: 'hue',
  foreColor: '#a94cf8',
  bgColor: '#075ecb',

}, {
  label: '饱和度',
  value: 'saturation',
  foreColor: '#838383',
  bgColor: '#075ecb',

}, {
  label: '颜色',
  value: 'color',
  foreColor: '#ffeeda',
  bgColor: '#075ecb',

}, {
  label: '亮度',
  value: 'luminosity',
  foreColor: '#929292',
  bgColor: '#075ecb',

}, {
  label: '初始',
  value: 'initial',
  foreColor: '#d78c33',
  bgColor: '#075ecb',

}, {
  label: '继承',
  value: 'inherit',
  foreColor: '#f0e301',
  bgColor: '#075ecb',

}, {
  label: '复原',
  value: 'unset',
  foreColor: '#929292',
  bgColor: '#075ecb',

}];

<div className={prefixCls}>
  <div className={prefixCls + '-main'}>
    {colorList?.map(({ foreColor, bgColor, value, label }) => {
        return (
           <dl>
             <dd>
               <div className='bgColor' style={{ background: bgColor }} />
               <div className='foreColor' style={{ background: foreColor, mixBlendMode: value }} />
             </dd>
             <dt>{label} {value}</dt>
           </dl>
        );
    })}
 </div>
</div >


以mix-blend-mode: screen; 为例,实现镂空的文字、图片和图片、图片和视频video的混合结果

image.png

.color-filter-test {
  width: 100%;
  height: 100%;

  &-list {
    .list-item {
      display: flex;
      padding: 10px 0;
      border-bottom: 1px solid #f1f1f1;

      dl {
        display: flex;
        flex-direction: column;
        margin-right: 12px;

        dt {
          margin-bottom: 10px;
        }

        dd {
          position: relative;
          width: 150px;
          height: 200px;
          overflow: hidden;

          img {
            width: 100%;
            height: 100%;
            object-fit: cover;

            &:nth-child(2) {
              position: absolute;
              top: 0;
              left: 0;
              mix-blend-mode: screen;
            }
          }

          video {
            &:nth-child(2) {
              position: absolute;
              top: 0;
              left: 0;
              width: 100%;
              mix-blend-mode: screen;
            }
          }

          h1 {
            padding: 6px 12px;
            font-size: 28px;
            font-weight: 600;
            font-family: microsoft yahei;
            text-align: center;
            background-color: grey;

            &:nth-child(2) {
              position: absolute;
              top: 120px;
              left: 0;
              width: 100%;
              mix-blend-mode: screen;
            }
          }
        }
      }
    }
  }
}

import React, { useState, useEffect } from 'react';
import './index.less';
import pic1 from './images/landscape-s.jpg';
import pic2 from './images/shandian_2.png';
import video1 from './images/rains-s.mp4';

const prefixCls = 'color-filter-test';

export default function ColorFilterTest() {
    return (
        <div className={prefixCls}>
            <div className={prefixCls + '-list'}>
                <div className='list-item'>
                    <dl>
                        <dt>文字和图片混合结果</dt>
                        <dd className='effect'>
                            <img src={pic1} />
                            <h1>文字效果</h1>
                        </dd>
                    </dl>
                </div>

                <div className='list-item'>
                    <dl>
                        <dt>背景图</dt>
                        <dd><img src={pic1} /></dd>
                    </dl>
                    <dl>
                        <dt>前景图</dt>
                        <dd><img src={pic2} /></dd>
                    </dl>
                    <dl>
                        <dt>背景图和前景图混合后的效果图</dt>
                        <dd className='effect'>
                            <img src={pic1} />
                            <img src={pic2} />
                        </dd>
                    </dl>
                </div>

                <div className='list-item'>
                    <dl>
                        <dt>背景图</dt>
                        <dd><img src={pic1} /></dd>
                    </dl>
                    <dl>
                        <dt>前景图</dt>
                        <dd><video autoPlay loop muted src={video1} /></dd>
                    </dl>
                    <dl>
                        <dt>背景图和前景图混合后的效果图</dt>
                        <dd className='effect'>
                            <img src={pic1} />
                            <video autoPlay loop muted src={video1} />
                        </dd>
                    </dl>
                </div>
            </div>
        </div >
    );
}