Вы все еще используете изображения в качестве направляющих масок?

внешний интерфейс

Автор: Глубокий горный муравей

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

阴影

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

Маскирование по изображению имеет несколько существенных недостатков:

  1. Большие изображения влияют на загрузку
  2. Содержимое картинок является подделкой и не соответствует реальному содержимому дна.
  3. Для полноэкранного маскированного изображения ширина и высота изображения не соответствуют ширине и высоте экрана, и изображение остается черным с обеих сторон или имеет эффект сжатия.
  4. Главное положение изображения не может быть нажато.
  5. низкий? не круто?

В этой статье описаны шесть идей по реализации управляемой маскировки.

  • z-index реализует маскировку
  • Реализация динамической непрозрачности
  • пограничная реализация
  • реализация box-shadow
  • Реализация репликации узла
  • реализация холста

Вышеупомянутые шесть идей реализации маски руководства могут удовлетворить потребности бизнеса при определенных обстоятельствах, и маска руководства может быть реализована с разных точек зрения. Z-индекс самый простой, а холст самый гибкий.Лично я предпочитаю реализацию динамической маски непрозрачности в стиле скелетного экрана, которая интереснее и крутее!!!

Идея 1: Используйте z-индекс

  • Добавьте новый div, установите его как полупрозрачную область, размер покрывает всю страницу
  • Z-индекс полупрозрачной области маски больше, чем элемент страницы
  • Область содержимого начальной загрузки больше, чем z-index области полупрозрачной маски

Это легко понять. Элементы страницы иерархичны. Нам нужно только установить область содержимого направляющей на верхний уровень и установить слой маски под областью содержимого направляющей. Z-индексы других элементов содержимого находятся внутри этой маски. слой. Давайте рассмотрим простой пример.

.z1{
  position:absolute;
  left:50px;
  top:50px;
  width:50px;
  height:50px;
  background:blue;
  z-index:1;
}
.z2{
  position:absolute;
  left:60px;
  top:60px;
  width:50px;
  height:50px;
  background:red;
  z-index:2;
}
.z3{
  position:absolute;
  left:70px;
  top:70px;
  width:50px;
  height:50px;
  background:yellow;
  z-index:3;
}

z-index

Давайте изменим стиль z2.

.z2{
  position:absolute;
  left:50px;
  top:50px;
  width:50px;
  height:50px;
  background:black;
  opacity:0.5;
  z-index:2;
  animation:z_index 2s linear infinite alternate;
}
@keyframes z_index {
    from {
      left:50px;
      top:50px;
      width:50px;
      height:50px;
    }
    to {
      left:0px;
      top:0px;
      width:200px;
      height:200px;
    }
  }

z-index

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

Идея 2: Используйте непрозрачность, чтобы сделать незамаскированные элементы полупрозрачными

  • Область содержимого Bootstrap изменять не нужно.
  • Другие элементы узлов на странице полупрозрачны.

Мы больше не добавляем новый слой-маску, а полностью манипулируем узлами страницы, устанавливаем полупрозрачными узлы, которые необходимо замаскировать, и полностью отображается содержимое направляющего слоя-маски. Эффект страницы не такой, как у слоя-маски, для пустого места мы все равно полностью отображаем его, но даем полупрозрачные элементы с содержимым, аналогично эффекту каркасного экрана.
Чтобы продемонстрировать эффект, давайте рассмотрим следующий пример:
На странице установлено 6 элементов.

<div class="wrap">
    <div class="z z1"></div>
    <div class="z z2"></div>
    <div class="z z3"></div>
    <div class="z z4"></div>
    <div class="z z5"></div>
    <div class="z z6"></div>
  </div>

Элементы макета рядом с flex.

.wrap{
  display:flex;
  flex-wrap:wrap;
  width:150px;
}
.z{
  width:50px;
  height:50px;
  transition:all 1s;
}
.z1{
  background:blue;
}
.z2{
  background:black;
}
.z3{
  background:yellow;
}
.z4{
  background:red;
}
.z5{
  background:green;
}
.z6{
  background:orange;
}

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

let arry = Array.from(document.querySelectorAll(".z"));
let index = -1;
let direct = 1;
setInterval(()=>{
  if(index>=5) direct = -1;
  else if(index<=0) direct = 1;
  index = index+direct;
  arry.forEach((d,i)=>{
    d.style.opacity = 1;
  });
  setTimeout(()=>{
    arry.forEach((d,i)=>{
      if(i==index) return;
      d.style.opacity = 0.1;
    });
  },1000);
},2000)

z-index

Глядя на этот пример, мы можем ясно увидеть процесс реализации этой направляющей маски. Этот тип направляющей маски на самом деле более забавен и интересен. Он похож на популярный в настоящее время экран-скелет. Содержимое, которое необходимо замаскировать для других существующих элементов, — это серая часть экрана-скелета, а содержимое ключевой маски должно быть отображается.
интересно! ! !

Идея 3: Используйте метод границы для достижения

Правильно, его вообще нет в общей границе, и видим следующее:

div {
    border:1px solid #red;
}

Итак, как использовать границу для реализации направляющей маски?

1. Сначала разберитесь с нижним треугольником

Давайте рассмотрим простой пример:

<div class="border_1"></div>
.border_1{
    width: 100px;
    height: 100px;
    border-top:50px solid red;
    border-right: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 50px solid transparent;
    box-sizing:border-box;
}

border_1

Реализуя перевернутый треугольник, в этом приложении больше сценариев применения, и будет использоваться много подсказок и меток. Вместо этого я видел этот перевернутый треугольник, используя картинку.
Если внимательно посмотреть на этот код, можно выделить три основных момента:

  1. Границы установлены со всех сторон
  2. Ширина и высота обе по 100px, то есть сумма верхней и нижней, левой и правой рамок таблицы, по факту она меньше или равна этому значению.
  3. Только верхняя граница красная, остальные границы прозрачные.

Чтобы понять приведенную выше реализацию, давайте посмотрим на следующий код:

.border_2{
    width: 100px;
    height: 100px;
    background-color:green;
    border-style:solid;
    border-color:red yellow blue black;
    border-width:50px;
    animation:border_ani 2s linear infinite alternate;
    box-sizing:border-box;
}
@keyframes border_ani {
    from {
        border-width:50px;
    }
    to {
      border-width:0;
    }
  }

animation

На рисунке хорошо видно, что при изменении ширины границы меняется зеленый фон всего div.

  • Когда border-width=0, вся страница имеет только зеленый фон, то есть размер содержимого
  • Когда border-width=50, размер всего блока div заполняется рамкой, а верхняя, нижняя, левая и правая части делятся поровну на 1/4, то есть на четыре перевернутых треугольника.

Таким образом, мы можем ясно получить:

Когда граница справа, граница слева и граница снизу прозрачны, а граница сверху красна, вы видите перевернутый треугольник.

Таким же образом мы также можем установить размер границы непостоянным, и мы можем реализовать косой треугольник:

.border_3{
    width: 0;
    height: 0;
    border-top:30px solid red;
    border-right: 10px solid transparent;
    border-bottom: 20px solid transparent;
    border-left: 100px solid transparent;
    box-sizing:border-box;
}

斜三角

Также можно реализовать часто встречающуюся в работе трапецию:

.border_4{
    width: 150px;
    height: 150px;
    border-top:50px solid red;
    border-right: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 50px solid transparent;
    box-sizing:border-box;
}

梯形

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

2. Посмотрите на реализацию маски руководства

  • Добавьте div в качестве замаскированного элемента
  • Средний размер div точно такого же размера, как элемент содержимого начальной загрузки, а позиция просто перекрывается
  • Граница div должна быть полупрозрачной и бесконечно увеличенной.

После понимания реализации вышеуказанного треугольника предполагается, что вы также сможете понять, как сделать направляющую маску. Div имеет четыре границы.Если мы установим все границы полупрозрачными, а затем установим среднюю область (зеленый цвет border_2 выше) полностью прозрачной, будет ли достигнута маска направляющей области? Затем установите границу так, чтобы она превышала размер экрана, который является маской направляющей панорамы!

.border_5{
    width: 150px;
    height: 150px;
    border-top:50px solid rgba(0,0,0,.5);
    border-right: 50px solid rgba(0,0,0,.5);
    border-bottom: 50px solid rgba(0,0,0,.5);
    border-left: 50px solid rgba(0,0,0,.5);
    box-sizing:border-box;
}

蒙层

Это маска области размером 150 пикселей, как видно из следующего примера:

.border_6{
    width: 20px;
    height: 20px;
    border-style:solid;
    border-color:rgba(0,0,0,.5);
    border-width:20px;
    animation:border_ani 2s linear infinite alternate;
    box-sizing:content-box;
}
@keyframes border_ani {
    from {
        border-width:20px;
    }
    to {
      border-width:100px;
    }
  }

蒙层

Конечно, мы также можем установить border-radius для получения круглой маскируемой области следующим образом:

border-radius

Конечно, все значения размера границы здесь жестко закодированы, и конкретная реализация должна быть изменена или динамически изменена в соответствии с содержимым страницы.

А если это эллипс?

Суммировать:

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

Идея 4, используйте box-shadow для достижения

  • Добавьте div в качестве замаскированного элемента
  • Размер div точно такой же, как размер элемента контента, а позиция просто перекрывается
  • Размер тени блока-тени div установлен на полупрозрачный и установлен на относительно большой размер около 2000 пикселей.

box-shadow, с ним все знакомы, это тень ящика.Давайте сначала разберемся в его основном использовании:

.boxshadow_1{
    width:50px;
    height:50px;
    background:blue;
    box-shadow: 10px 10px 5px 4px #000;
}

阴影

В div с шириной и высотой 50 пикселей его тень составляет 10 пикселей по горизонтали и вертикали, расстояние размытия тени составляет 5 пикселей, размер тени составляет 4 пикселя, а тень имеет цвет #000 (здесь желтый цвет фона). добавляется к телу для облегчения дифференциации).

Сначала мы делаем тень прозрачной:

.boxshadow_2{
    width:50px;
    height:50px;
    background:blue;
    box-shadow: 10px 10px 5px 4px rgba(0,0,0,.5);
}

阴影

Так как же сделать так, чтобы тень покрывала всю страницу?

  • Горизонтальное и вертикальное расстояние тени относится к расстоянию от исходного dev.Эта настройка не даст эффекта, а только заставит тень больше отклоняться от элемента.
  • Расстояние размытия тени относится к расстоянию, на котором край тени постепенно размывается.Чем больше расстояние, тем длиннее размытие, и размер слоя маски не изменится.
  • Размер тени, это относится к размеру тени, тогда мы устанавливаем размер тени очень большим? да это оно

Глядя на следующий пример, мы настраиваем размер тени:

.boxshadow_3 {
  width:50px;
  height:50px;
  background:blue;
  box-shadow: 0px 0px 5px 0px rgba(0,0,0,.5);
  animation:box_ani 2s linear infinite alternate;
}
@keyframes box_ani {
    from {
        box-shadow: 10px 10px 5px 0px rgba(0,0,0,.5);
    }
    to {
        box-shadow: 10px 10px 5px 100px rgba(0,0,0,.5);
    }
  }

Как и выше, нам нужно только увеличить размер тени, чтобы получить направляющую маску.
Что, если вам нужно управлять замаскированным состоянием и при этом реагировать на события? Просто добавьте атрибут pointer-events.

Расстояние тени box-shadow не должно быть слишком большим вслепую.После тестирования, если значение слишком велико, например, 4000 пикселей, тень не может отображаться на некоторых мобильных телефонах. После практики лучше поставить 2000px.

Идея 5: Используйте репликацию узла страницы

  • Добавьте два элемента div, полупрозрачный элемент с маской и область содержимого с маской.
  • Скопируйте содержимое начальной загрузки узла страницы в область маскированного содержимого.
  • Полностью совместить размер и положение замаскированной области содержимого с исходным содержимым направляющей узла.

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

<div class="content one">我是第一个div,我是第一个div</div>
<div class="content two">我是第二个div,我是第二个div</div>
<div class="content three">我是第三个div,我是第三个div</div>
<div class="content four">我是第四个div,我是第四个div</div>
<div class="mask"></div>
<div id="maskContent"></div>

Здесь задана фиксированная маска, и фиксированный элемент содержимого маски, нам нужно только заполнить его.

.content{
    padding:10px;
    z-index:0;
}
.mask{
    position:fixed;
    left:0;
    top:0;
    width:100%;
    height:100%;
    background:rgba(0,0,0,.8);
    z-index:900
  }
  #maskContent{
    position:fixed;
    z-index:999;
    display:inline-block;
    background-color: #fff;
  }

Здесь вся область содержимого равна 0, затем маска равна 900, а наш элемент маски равен 999, что является верхним слоем.

function renderContent(cls){
    let targetNode = document.querySelector(`.${cls}`);
    let maskContent = document.getElementById("maskContent");
    maskContent.innerHTML = targetNode.outerHTML;
    let pos = targetNode.getBoundingClientRect();
    maskContent.style.top=pos.top+"px";
    maskContent.style.left=pos.left+"px";
    maskContent.style.width=pos.width+"px";
    maskContent.style.height=pos.height+"px";
 }
let i = 0;
setInterval(()=>{
    renderContent(['one','two','three','four'][i]);
    if(++i>=4) i = 0;
},1000)

Здесь для демонстрации эффекта добавлен таймер для смены разных слоев маски. Легко понять, посмотрите на эффект:

z-index

Идея 6: Используйте холст для реализации

  • Добавьте холст и дважды нарисуйте графику
  • Первый раз: нарисуйте полноэкранную полупрозрачную тень
  • Второй раз: используйте xor, чтобы нарисовать область, точно совпадающую с размером и положением области содержимого направляющей.

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

Используйте свойство холста globalCompositeOperation для достижения содержимого, ссылка на которое находится по адресу http://www.tutorialspoint.com/html5/canvas_composition.htm.

Сосредоточьтесь на xor: фигуры становятся прозрачными там, где они перекрываются, и рисуются нормально везде.
Перевод: фигуры, нарисованные на холсте, станут прозрачными везде, где они перекрываются, а все остальное, что не перекрывается, будет нормально рисовать содержимое.

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

 <div class="content one">我是第一个div,我是第一个div</div>
<div class="content two">我是第二个div,我是第二个div</div>
<div class="content three">我是第三个div,我是第三个div</div>
<div class="conteent four">我是第四个div,我是第四个div</div>
<canvas id="mask"></canvas>

Добавьте узел холста на страницу. Установите прозрачность всего холста, а затем используйте xor для рисования содержимого.

 function mask(cls){
    let targetNode = document.querySelector(`.${cls}`);
    let pos = targetNode.getBoundingClientRect();
    let canvas = document.getElementById("mask");
    let width = window.innerWidth;
    let height = window.innerHeight;;
    canvas.setAttribute("width", width);
    canvas.setAttribute("height",height);
    var ctx = canvas.getContext("2d"); 
    ctx.globalCompositeOperation = 'source-over';
    ctx.fillStyle ='rgba(255, 255, 255, 0.9)';
    ctx.fillRect(0, 0, width, height);
    ctx.fill();
    ctx.fillStyle ='white';
    ctx.globalCompositeOperation="xor";
    ctx.fillRect(pos.left,pos.top,pos.width,pos.height);
    ctx.fill();
 }
let array = ['one','two','three','four'];
let i = 0;
setInterval(()=>{
    mask(array[i]);
    i++;
    if(i>=4) i = 0;
},1000)

z-index

После прочтения приведенных выше реализаций, какая реализация вам нравится больше всего?


Если вы считаете, что этот контент ценен для вас, поставьте лайк и подпишитесь на нас.Официальный сайтА на нашем официальном аккаунте WeChat (WecTeam) каждую неделю публикуются качественные статьи:

WecTeam