Животињска висина - прави начин

Будимо искрени. Животна висина може бити велика мука. За мене је то била стална битка између жеље за лепим анимацијама и неспремности да платим огромне трошкове перформанси повезаних са анимирањем висине. Сад - то је све готово.

Све је почело када сам радио на свом споредном пројекту - креатору резимеа где можете делити линкове до свог животописа који су активни само одређено време.

Желео сам да имам лепу анимацију за све одељке у биографији и изградио сам компоненту реакције која је изводила анимацију. Међутим, убрзо сам открио да је ова компонента апсолутно уништила перформансе на нижим уређајима и у неким прегледачима. Дођавола, чак се и мој врхунски Мацбоок про трудио да одржи анимацију у глатком фпс-у.

Разлог томе је наравно што анимирање својства висине у ЦСС-у доводи до тога да прегледач изводи скупе операције изгледа и фарбања на сваком оквиру. Постоји фантастичан одељак о приказивању перформанси у Гоогле Веб Фундаменталс, предлажем да то погледате.

Укратко, ипак - кад год промените геометријско својство у цсс-у, прегледач мора да прилагоди и изврши прорачуне како та промена утиче на изглед странице, тада ће страницу морати поново приказати у кораку који се назива паинт.

Зашто бисмо уопште бринули о перформансама?

Може бити примамљиво занемарити перформансе. Није мудро, али може бити примамљиво. Из пословне перспективе, штедите много времена које се иначе може потрошити на изградњу нових функција.

Међутим, учинак може директно утицати на ваш крајњи резултат. Каква је корист од тога што се гради пуно функција ако их нико не користи? Вишеструке студије које су урадили Амазон и Гоогле показују да је то истина. Перформансе су директно повезане са употребом апликација и приходом.

Друга страна перформанси је једнако важна. Ми смо као програмери одговорни за то да веб остане доступан свима - то радимо зато што је то исправно. Будући да интернет није намењен само вама и мени, он је свима.

Као што се види из изврсног чланка Аддија Османија, уређајима нижег нивоа је потребно знатно више времена за рашчлањивање и извршавање јавасцрипта у поређењу са старијим колегама.

Да бисмо избегли стварање класне поделе на Интернету, морамо бити неумољиви у тежњи за учинком. За мене је то значило бити креативан и пронаћи друго средство за постизање својих анимација без жртвовања перформанси.

Анимирајте висину на прави начин

Ако вам није стало до тога како и желите само да видите пример уживо, погледајте доње везе за демо локацију, примере и нпм пакет за реакцију:

  • Демо сајт који користи технику
  • Пример уживо у ванили ЈС
  • Једноставан пример у реакцији
  • НПМ пакет и документација за реаговање

Питање које сам себи поставио било је како бих могао да избегнем трошкове перформанси који настају анимирањем висине. Једноставан одговор - не можете.

Уместо тога, требало је да будем креативан са другим ЦСС својствима која не сносе те трошкове. Наиме трансформише.

Пошто трансформације немају начин да утичу на висину. Не можемо једноставно применити једноставно својство на елемент и бити готови. Морамо бити паметнији од тога.

Начин на који ћемо користити за постизање перформансне анимације висине је заправо лажирањем са трансформ: сцалеИ. Анимација се врши у неколико корака:

Ево примера:

 ${this.markup} `
  • Прво морамо добити почетну висину контејнера са елементима. Затим смо поставили спољну висину контејнера да буде експлицитна на ову висину. То ће проузроковати да се било који променљиви садржај преплави контејнером, уместо да прошири свог родитеља.
  • Унутар спољног контејнера имамо још један див који је апсолутно позициониран тако да обухвата целу ширину и висину див-а. Ово је наша позадина и биће скалирано када променимо трансформацију.
  • Такође имамо унутрашњи контејнер. Унутрашњи контејнер садржи ознаку и мењаће своју висину у складу са садржајем који садржи.
  • Ево трика:  Једном када пребацимо догађај који мења ознаке, узимамо нову висину унутрашњег контејнера и израчунавамо количину коју позадина треба да скалира како би се прилагодила новој висини. Затим поставимо позадину на скалу И за нови износ.
  • У ванилин јавасцрипту ово значи неку варку са двоструким приказима. Једном да бисте добили висину унутрашњег контејнера за израчунавање скале. Затим поново применити скалу на позадински див тако да ће извршити трансформацију.

Пример уживо можете видети овде у ванилин ЈС.

У овом тренутку, наша позадина је правилно скалирана да би створила илузију висине. Али шта је са околним садржајем? Будући да више не прилагођавамо изглед, промене не погађају околни садржај.

Да се ​​околни садржај покрене. Морамо да прилагодимо садржај помоћу трансформИ. Трик је у томе да узмете количину коју је садржај проширио и помоћу ње преместите околни садржај помоћу трансформација. Погледајте горњи пример.

Анимирајућа висина у Реацт-у

Као што сам раније поменуо, ову методу сам развио радећи на личном пројекту у Реацт-у. Ова демо локација користи ову методу искључиво у свим својим „висинским анимацијама“. Погледајте демо страницу овде.

Након што сам ово успешно применио, узео сам времена да додам ову компоненту и неке пратеће компоненте у малу библиотеку анимација коју сам направио у Реацт-у. Ако сте заинтересовани, релевантне информације можете пронаћи овде:

  • погледајте библиотеку о НПМ овде
  • Документацију можете пронаћи овде.

Најважније компоненте у овој библиотеци су АниматеХеигхт и АниматеХеигхтЦонтаинер. Хајде да их испитамо:

// Inside a React component // handleAnimateHeight is called inside AnimateHeight and is passed the // transitionAmount and optionally selectedId if you pass that as a prop to // AnimateHeight. This means that you can use the transitionAmount to // transition your surrounding content.const handleAnimateHeight = (transitionAmount, selectedId) => { this.setState({ transitionAmount, selectedId }); }; // Takes a style prop, a shouldchange prop and a callback. shouldChange // determines when the AnimateHeight component should trigger, which is // whenever the prop changes. The same prop is used to control which // content to show.  {this.state.open && } {!this.state.open && } 
  • Пример померања околног садржаја

Горњи примери показују вам како да користите АниматеХеигхт и ручно покренете прилагођавање околног садржаја. Али шта ако имате пуно садржаја и не желите да ручно радите овај поступак? У том случају можете користити АниматеХеигхт заједно са АниматеХеигхтЦонтаинер.

Да бисте користили АниматеХеигхтЦонтаинер, требате пружити свој деци највишег нивоа реквизит под називом аниматеХеигхтИд, који такође треба проследити вашим компонентама АниматеХеигхт:

// Inside React Component const handleAnimateHeight = (transitionAmount, selectedId) => { this.setState({ transitionAmount, selectedId }); }; // AnimateHeight receives the transitionAmount and the active id of the AnimateHeight that fired. {this.state.open &&  {!this.state.open && }  // When AnimateHeight is triggered by state change // this content will move because the animateHeightId // is greater than the id of the AnimateHeight component above I will move I will also move 

Као што можете видети из овог примера, АниматеХеигхт прима информације потребне за подешавање садржаја када се компонента АниматеХеигхт покрене променом стања.

Једном када се то догоди, компонента АниматеХеигхт ће покренути повратни позив и поставити својства у стање. Унутар АниматеХеигхт изгледа отприлике овако (поједностављено):

// Inside AnimateHeight componentDidUpdate() { if (update) { doUpdate() callback(transitionAmount, this.props.animateHeightId) } } // Equivalent to calling this function: const handleAnimateHeight = (transitionAmount, selectedId) => { this.setState({ transitionAmount, selectedId }); }; handleAnimateHeight(transitionAmount, this.props.animateHeight)

Сада сте износ који је садржај прешао у пикселима и ИД компоненте АниматеХеигхт која се активирала. Једном када проследите ове вредности у АниматеХеигхтЦонтаинер, он ће их узети и пребацити остале компоненте у себе, под условом да сте поставили прираштање аниматеХеигхтИдс на деци највишег нивоа.

Напреднији примери:

  • Премештање околног садржаја помоћу АниматеХеигхтЦонтаинер
  • Пример хармонике

НАПОМЕНА: Ако користите овај метод за анимирање висине и померања околног садржаја, треба да додате износ прелаза на висину странице.

Закључак

Можда сте приметили у овом чланку да заправо не анимирамо висину - и називамо је погрешном. У праву си, потпуно у праву. Међутим, чврсто верујем да оно што ми зовемо није важно. Важно је да постигнемо жељени ефекат уз најниже могуће трошкове за перформансе.

Иако мислим да сам пронашао начин који је бољи од директног анимирања својства висине, не тврдим да сам измислио или на неки други начин смислио нешто што раније није откривено. Нити судим. Можда вам анимирање висине одговара у вашем сценарију - Нема проблема.

Све што желим је да омогућим и поједноставим ефекте које сви морамо да урадимо, али понекад имају трошкове које је тешко поднети. У најмању руку, желим да покренем дискусију коју вреди водити. Како можемо побољшати интернет за све?