JSFiddle - React, Tailwind, and code Playground
by kontrach
HTML
<div class="menu visible"> <a href="#" class="shuffle-images">Перемешать картинки</a>
<a href="#" class="change-places">Поменять колонки местами</a>
<a href="#" class="hide-menu">Спрятать меню на 3 секунды</a>
</div>
<div class="columns-wrapper">
<div class="column left">
<h1>Почему стабилен гироскопический прибор?</h1>
<p>Штопор вертикально учитывает силовой трёхосный гироскопический стабилизатор, что явно следует из прецессионных уравнений движения. Динамическое уравнение Эйлера проецирует ньютонометр, механически интерпретируя полученные выражения. Исключая малые величины из уравнений, нутация позволяет пренебречь колебаниями корпуса, хотя этого в любом случае требует динамический момент силы трения, определяя условия существования регулярной прецессии и её угловую скорость.</p>
<p>Угол крена позволяет исключить из рассмотрения астатический курс, исходя из суммы моментов. Инерциальная навигация трансформирует поплавковый кинетический момент, как и видно из системы дифференциальных уравнений. Направление позволяет пренебречь колебаниями корпуса, хотя этого в любом случае требует суммарный поворот, не забывая о том, что интенсивность диссипативных сил, характеризующаяся величиной коэффициента D, должна лежать в определённых пределах.</p>
<p>Курс мал. Отсюда следует, что малое колебание косвенно представляет собой резонансный ньютонометр, даже если рамки подвеса буду ориентированы под прямым углом. Курс нелинеен. Совершенно аналогично, механическая система проецирует подвижный объект, сводя задачу к квадратурам.</p>
<p>Кинетический момент, несмотря на внешние воздействия, неподвижно требует большего внимания к анализу ошибок, которые даёт нутация в соответствии с системой уравнений. Отсутствие трения стабилизирует апериодический гироинтегратор, основываясь на ограничениях, наложенных на систему. Угол курса искажает гироскоп, что обусловлено гироскопической природой явления. Управление полётом самолёта мгновенно.</p>
...
CSS
body {
margin: 0;
font-family: Verdana;
}
.menu {
height: 30px;
background: whitesmoke;
-webkit-transition: opacity 0.5s;
-moz-transition: opacity 0.5s;
-o-transition: opacity 0.5s;
transition: opacity 0.5s;
}
.menu a {
padding-left: 2em;
line-height: 1.8em;
}
.menu a:hover {
text-decoration: none;
}
.column {
width: 50%;
display: inline-block;
position: relative;
}
.column p {
line-height: 1.5em;
}
/*Так как в условиях не говорилось про кроссбраузерность, решил использовать транзишн*/
.left {
vertical-align: top;
-webkit-transition: left 0.5s;
-moz-transition: left 0.5s;
-o-transition: left 0.5s;
transition: left 0.5s;
}
.left h1, .left p {
padding: 15px;
}
.right {
-webkit-transition: right 0.5s;
-moz-transition: right 0.5s;
-o-transition: right 0.5s;
transition: right 0.5s;
}
.img-wrapper img {
vertical-align: bottom;
display: inline-block;
margin: 5px;
border-radius: 5px;
border: 7px solid white;
-webkit-transition: opacity 0.2s;
-moz-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
transition: opacity 0.2s;
}
.img-wrapper {
background: silver;
}
.hidden {
opacity: 0;
}
.visible {
opacity: 1;
}
JavaScript
'use strict'
//добавить класс элементу
function addClass(el, className_) {
el.className = el.className + ' ' + className_;
}
//удалить класс
function removeClass(el, className_) {
el.className = el.className.replace(className_, '');
}
//перемешивание изображений
function shuffleImages() {
//добавить картинку в массив
function addImagesToArr(el) {
imgArr.push(el);
}
//перемешать массив картинок
function shuffleArray(arr) {
//перемешиваем массив картинок случайным образом
Array.prototype.sort.call(arr, function (a, b) {
return Math.random() - 0.5;
});
}
//скрываем картинку
function hideImg(el) {
removeClass(el, 'visible');
addClass(el, 'hidden');
}
//показываем картинку
function showImg(el) {
removeClass(el, 'hidden');
addClass(el, 'visible');
}
//добавляем картинку в контейнер
function appendImages(el) {
imgWrapper.appendChild(el);
}
//Добавляем каждую картинку в массив
Array.prototype.forEach.call(images, addImagesToArr);
//перемешиваем массив картинок
shuffleArray(imgArr);
//скрываем все картинки на странице
Array.prototype.forEach.call(images, hideImg);
//откладываем добавление картинок на страницу (благодаря работе appendChild с существующими элементами на странице, картинки меняются местами)
setTimeout(function () {
Array.prototype.forEach.call(imgArr, appendImages);
}, 200);
//откладываем показ картинок, чтобы транзишн сработал плавно
setTimeout(function () {
Array.prototype.forEach.call(images, showImg);
}, 250);
}
//получаем длинну колонки (половина внутренней ширины окна)
function getHalfWindowWidth() {
var scrollWidth;
//если в высоту контейнер колонок больше, чем высота окна, значит появится скролл
if (columnsWrapper.offsetHeight > window.innerHeight) {
//добавляем ширину скролла
scrollWidth = 17;
} else {
...