css смешивание / размытие / объединение фоновых изображений - PullRequest
0 голосов
/ 01 апреля 2020

Я работаю на веб-сайте, это просто демо здесь ReactJS: https://poc-b-i-o-meteo.netlify.com/

Проблема с фоном.

Концепция проста, приложение состоит из 4 частей, верхняя часть с метео без фона и 3 части с разным фоном. Приложение должно быть мобильным и отзывчивым, каждая часть имеет разный контент, поэтому разной высоты.

enter image description here

Теперь я хочу сделать приятный эффект между каждой частью (météo & 1; 1 & 2; 2 & 3) следующим образом:

enter image description here

Итак, как сделать, чтобы каждая часть находилась над нижней частью предыдущей части для некоторого пикселя и чтобы она хорошо сочеталась друг с другом (как мы можем сделать с помощью 2 png в фотошопе). с прозрачностью). Этот эффект должен быть сделан в css, потому что он должен быть там с мобильного на широкий экран.

Ранее я пробовал:

  1. с 3 PNG, который содержал прозрачность, он не работать на двоих PNG очень тяжелый и показывает только точную ширину экрана.
  2. путем добавления относительной зоны к низу / верху компонента Categorie с помощью linear-gradient, но визуализируем немного уродливым

1) APP. JS

import Meteo from "./components/Meteo";
import Categorie from "./components/Categorie";

function App() {
  return (
    <div className="App">
      <h5 style={{ paddingLeft: 15 }}>Météo</h5>
      <header className="App-header">
        <Meteo />
        <Categorie name="air" display="Air" bgpos="bottom" {/* bottomOpacity*/} />

        <Categorie name="sol" display="Sol" bgpos="center"  {/*  bottomOpacity topOpacity*/} />

        <Categorie name="eau" display="Eau" bgpos="top" {/* topOpacity */}/>

      </header>
    </div>
  );
}

2) Категория ie. js

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  leftText: {
    textAlign: "left",
    width: "auto",
    display: "inline-block"
  },
  responsive: {
    width: "100%",
    maxWidth: "1000px",
    height: "auto"
  },
  container: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    justifyContent: "center"
  },
  overlay: {
    backgroundColor: "rgba(13,53,78, 0.6)",

    color: "white",
    position: "relative"
  },

  topOpacity: {
    position: "absolute",
    top: -2,
    width: "100%",
    height: 75,
    background: "linear-gradient( to top, transparent , rgba(13,53,78,0.9 ) )",
    backgroundRepeat: "no-repeat"
  },
  bottomOpacity: {
    position: "absolute",
    bottom: -2,
    width: "100%",
    height: 75,
    background:
      "linear-gradient( to bottom, transparent , rgba(13,53,78, 0.9 ) )",
    backgroundRepeat: "no-repeat"
  },

  padding: {
    padding: "auto",
    paddingTop: 85,
    paddingBottom: 85
  }
}));

export default function Categorie(props) {
  const classes = useStyles();

  let ref = useRef(null);
  let size = useComponentSize(ref);
  let { width, height } = size;

  const filename = {
    air: "air.jpg",
    eau: "eau.jpg",
    sol: "sol.jpg"
  };

  let backgd = {
    backgroundImage: `url('./photos/${filename[props.name]}')  `,
    backgroundPosition: props.bgpos || "center",
    backgroundSize: "cover",
    backgroundRepeat: `${width}px ${height}px`,
    width: "100%"
  };

  return (
    <div style={backgd} ref={ref}>
      <div className={classes.overlay}>
        {props.topOpacity && <div className={classes.topOpacity} />}
        <div className={classes.padding}>
          ... CONTENT
        </div>
        {props.bottomOpacity && <div className={classes.bottomOpacity} />}
      </div>
    </div>
  );
}

1 Ответ

1 голос
/ 01 апреля 2020

это можно сделать с помощью маски.

Вот упрощенный пример:

.box {
  height:60vh;
  font-size:50px;
  text-align:center;
  color:#fff;
  position:relative;
  z-index:0;
}
.box:before {
  content:"";
  position:absolute;
  z-index:-1;
  left:0;
  right:0;
  top:-50px;
  bottom:-50px;
  background:var(--img) center/cover;
  -webkit-mask:linear-gradient(transparent ,#fff 50px calc(100% - 50px),transparent);
          mask:linear-gradient(transparent ,#fff 50px calc(100% - 50px),transparent);
}
<div class="box" style="--img:url(https://i.picsum.photos/id/1002/800/800.jpg)">text 1</div>
<div class="box" style="--img:url(https://i.picsum.photos/id/109/800/800.jpg)">text 2</div>
<div class="box" style="--img:url(https://i.picsum.photos/id/107/800/800.jpg)">text 3</div>
<div class="box" style="--img:url(https://i.picsum.photos/id/177/800/800.jpg)">text 4</div>
...