CSS transition scale () - странная задержка

Способ иметь отдельную реализацию выглядит следующим образом.

//inner_foo.h

template <typename T>
struct Foo
{
    void doSomething(T param);
};


//foo.tpp
#include "inner_foo.h"
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}


//foo.h
#include <foo.tpp>

//main.cpp
#include <foo.h>

inner_foo имеет форвардные объявления. foo.tpp имеет реализацию и включает inner_foo.h; и foo.h будет иметь только одну строку, чтобы включить foo.tpp.

Во время компиляции содержимое foo.h копируется в foo.tpp, а затем весь файл копируется в foo.h после который он компилирует. Таким образом, ограничений нет, и именование согласовано в обмен на один дополнительный файл.

Я делаю это, потому что статические анализаторы для кода разбиваются, когда он не видит передовые объявления класса в * .tpp. Это раздражает при написании кода в любой среде IDE или с помощью YouCompleteMe или других.

3
задан Temani Afif 3 March 2019 в 21:39
поделиться

2 ответа

Вот такие же идеи, как и в другом ответе, где вы можете сделать это только с одним элементом.

Увеличение ширины / высоты.

const outer = document.querySelector('.outer');

outer.addEventListener('click', () => {
  outer.classList.toggle('outer--active');
});
body { overflow: hidden; }

.outer {
  width: calc(100px * var(--s,1));
  height: calc(100px * var(--s,1));
  border-radius: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: 
    url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/49240/14.jpg') center ;
  transition: all 1.5s;
  cursor: pointer;
  border: 1px solid black;
}

.outer--active {
  --s:4;
}
<div class="outer">
</div>

Учитывая clip-path, где я добавляю radial-gradient для создания границы

[1122 ]
const outer = document.querySelector('.outer');

outer.addEventListener('click', () => {
  outer.classList.toggle('outer--active');
});
body { overflow: hidden; }

.outer {
  width: 400px;
  height: 400px;
  border-radius: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: 
    radial-gradient(farthest-side,transparent calc(100% - 3px),#000 100%),
    url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/49240/14.jpg');
  background-size:40% 40%,auto;
  background-position:center;
  transition: all 1.5s;
  cursor: pointer;
  -webkit-clip-path: circle(20% at 50% 50%);
  clip-path: circle(20% at 50% 50%);
}

.outer--active {
  -webkit-clip-path: circle(50% at 50% 50%);
  clip-path: circle(50% at 50% 50%);
  background-size:100% 100%,auto;
}
<div class="outer">
</div>

Вы также можете рассмотреть только radial-gradient, но область щелчка будет больше, и вы не будете иметь прозрачность:

const outer = document.querySelector('.outer');

outer.addEventListener('click', () => {
  outer.classList.toggle('outer--active');
});
body { overflow: hidden; }

.outer {
  width: 400px;
  height: 400px;
  border-radius: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: 
    radial-gradient(farthest-side,transparent calc(40% - 3px),#000 40%,#fff calc(40% + 1px)),
    url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/49240/14.jpg');
  background-size:100% 100%,auto;
  background-position:center;
  transition: all 1.5s;
  cursor: pointer;
}

.outer--active {
  background-size:240% 240%,auto;
}
<div class="outer">
</div>

0
ответ дан Temani Afif 3 March 2019 в 21:39
поделиться

Проблема

То, что вы видите, это не «ошибка браузера», а скорее неправильное понимание того, как работает вычисление двух комбинированных масштабов.

Для простоты, давайте предположим, что функцией перехода является linear (а не ease, которая является функцией синхронизации по умолчанию). В этом случае графики обеих шкал будут следующими: scaling functions

Поскольку мы хотим, чтобы конечная шкала внутреннего элемента оставалась постоянной, то (функция масштабирования) × (функция масштабирования) = 1 для всех временных аргументов. К сожалению, если мы сделаем умножение, в результате мы получим квадратную функцию (в нашем случае это -¾x² + 3x + ¾). Это удар по окончательному масштабированию, который вы можете увидеть в середине перехода. Чтобы избежать этого, вместо перехода к значению scale(n) нам нужно было бы масштабировать правило m в scale(1/m) css. К сожалению, мы не можем этого сделать, даже если мы использовали переменные css, поскольку они (пока) не допускают переходов (см. этот ответ)

Чтобы смягчить это, мы могли бы создать пользовательская функция синхронизации cubic-bezier, которая была бы обратной к квадратной функции, но я не смог сделать это вручную, и, вероятно, cubic-bezier не дал бы точную кривую для всех значений времени, особенно если бы мы хотели иметь основание функция синхронизации ничего, кроме linear.

Решение

Подход 1: Вместо масштабирования мы могли бы изменить размеры внешнего div, как показано ниже:

const outer = document.querySelector('.outer');

outer.addEventListener('click', () => {
  outer.classList.toggle('outer--active');
});
body { overflow: hidden; }

.outer {
  width: 100px;
  height: 100px;
  overflow: hidden;
  border-radius: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transform-origin: top left;
  transition: all 1s;
  cursor: pointer;
  border: 1px solid black;
}

.outer--active {
  width: 400px;
  height: 400px;
}

.inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 400px;
  height: 400px;
  background: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/49240/14.jpg') center repeat;
  transform-origin: top left;
  transition: transform 1s;
}
<div class="outer">
  <div class="inner"></div>
</div>

Плюсы: сохраняет текущую структуру разметки html

Минусы: анимация прерывистая из-за ошибок браузера, связанных с сглаживанием субпиксельных переходов (например, Отчет об ошибках в Firefox )


Подход 2: Используйте обтравочную маску для эффекта круглого выреза, добавьте div для границы:

const outer = document.querySelector('.outer');

outer.addEventListener('click', () => {
  outer.classList.toggle('outer--active');
});
[ 114]
<div class="outer">
  <div class="inner"></div>
  <div class="rim"></div>
</div>

Плюсы: плавно масштабируется

Минусы: необходимо добавить еще один тег HTML для круглой границы / обода. Обод может иногда выглядеть отделенным от внутреннего образа.

0
ответ дан Piotr Wicijowski 3 March 2019 в 21:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: