Красота "ручного" сайта ne.studio

Привет, на связи веб-разработчик диджитал агентства ne.studio. Недавно мы выпустили в продакшн сайт агентства, при разработке которого мы решили полностью отказаться от использования ноу-код платформ. Как и зачем это было сделано?

Мы сделали сайт без использования ноу-код платформ. Зачем так сложно для начинающей студии? Во-первых, такой подход был выбран, чтобы повысить уникальность и интерактивность сайта, сделать его более гибким и зрелищным.

Кроме того, нам было важно показать нашим клиентам возможности живого кодинга сайтов, преимущества такого подхода перед более шаблонными ноу-код платформами.

Оценить получившийся сайт вы можете по ссылке ниже, а здесь мы разберем некоторые особенности сайта ne.studio. Погнали)

1. Использование неформатной ширины

На этапе формирования идеи сайта нам захотелось, чтобы сайт хорошо выглядел не только на экранах стандартной ширины, но и широкоэкранных мониторах, которыми сейчас все чаще пользуются и дизайнеры, и программисты. Поэтому стартовая ширина контейнера была выбрана нами в 1440px вместо стандартных 1100-1200px. Да, такой подход имеет ряд сложностей, так как нужно уделять много внимания мелким деталям при написании адаптивов к сайту. Зато сайт не выглядит урезанным на больших мониторах.

Так главный экран сайта выглядит на мониторе с диагональю в 29 дюймов.

Красота "ручного" сайта ne.studio

2. Гибкая анимация

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

//здесь представлен не полный код, а лишь его часть для демонстрации $(window).scroll(function() { let scroll = $(window).scrollTop(); let radius=40; let scaleX=0.13+scroll/1000; let scaleY = scaleX; let translateY = scroll/1; let translateX = 0; let translateBtn=scroll/0.67; $(".zoom-video>video").css({ transform: 'translate3d('+(translateX)+'px, '+(translateY)+'px, 0) scaleX('+(scaleX)+') scaleY('+(scaleY)+')', borderRadius: +(radius)+'px', }); $(".offer-btn").css({ transform: 'translateY('+(translateBtn)+'px)', }); });

Необычная цикличная анимация есть и на странице "об агентстве". Само по себе представление команды агентства заслуживает отдельного внимания, участники расположены вдоль кривой линии, которая как-бы ведет их за собой. С определенной периодичностью размер фотографий меняется в соответствии с отделом агентства (графический или веб), к которому относится участник команды. Чтобы вставить в статью анимацию, пришлось уменьшить масштаб на сайте, уж очень большая у нас команда.

//здесь представлен не полный код, а лишь его часть для демонстрации changeScale = () => { $('.gallery-item-big').css({ transform: 'scale(0.28)' }) $('.gallery-item-small').css({ transform: 'scale(3.6)' }) } returnScale = () => { $('.gallery-item-big').css({ transform: 'scale(1)' }) $('.gallery-item-small').css({ transform: 'scale(1)' }) } const interval1 = setInterval(changeScale, 2500); const interval2 = setInterval(returnScale, 5000);

3. Работа с массивами данных

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

Красота "ручного" сайта ne.studio
//здесь представлен не полный код, а лишь его часть для демонстрации const webDesigners = [ { id: 0, name: 'Татьяна Плющ', position: 'Консультант <br/> по виртуальному лечению сайтов <br/>и онлайн-консультациям' }, ......... { id: 7, name: 'Ольга Калафат', position: 'Магистр веб дизайн <br/> и бросания чар' } ] const graphDesigners = [ { id: 0, name: 'Андрей Миланин', position: 'Директор <br/> по межпланетной коммуникации' }, ... { id: 5, name: 'Татьяна Хахаева', position: 'Король магического контента и создания вирусных видео-роликов' }, ] $('.gallery-item').click(function(e){ $('.gallery-popup-wrapper').css({ display: 'block', }) const webers = Array.from($('.gallery-item-big')); let indexW = webers.indexOf(e.target); const graphs = Array.from($('.gallery-item-small')); let indexG = graphs.indexOf(e.target); const portrait = $('.person-portrait'); const name = $('.person-name'); const position = $('.person-position'); if (indexG==-1){ portrait.css({ backgroundImage: "url(./assets/image/portrait-color/v-foto"+(indexW+1)+".png)", backgroundSize: 'contain', }) name.html(webDesigners[indexW].name); position.html(webDesigners[indexW].position); } else { portrait.css({ backgroundImage: "url(./assets/image/portrait-color/g-foto"+(indexG+1)+".png)", backgroundSize: 'contain', backgroundRepeat: 'no-repeat', }) name.html(graphDesigners[indexG].name); position.html(graphDesigners[indexG].position); }

и кейсами портфолио:

//здесь представлен не полный код, а лишь его часть для демонстрации const portfolioItems = [ { id: 0, tags: '#лого #фирменныйстиль #экомастерская #2022', title: 'Натюр', cover: './assets/image/natyur.gif', link: 'https://www.behance.net/gallery/164725235/Natur-branding-for-eco-workshop', filter: ['all', 'logo', 'brand'] }, ... { id: 6, tags: '#лого #фирменныйстиль #кардиодиабет #2023', title: 'Кардио<br/>диабет', cover: './assets/image/cardio.gif', link: 'https://www.behance.net/gallery/167808637/National-Medical-Association-of-Cardiodiabetologists', filter: ['all', 'logo', 'brand', 'motion'] }, ] portfolioItems.reverse(); for (let i=0; i<casesArr.length; i++){ for (let j=0; j<portfolioItems[i].filter.length; j++){ casesArr[i].classList.add(portfolioItems[i].filter[j]) } hashTags[i].innerHTML=portfolioItems[i].tags; caseTitle[i].innerHTML=portfolioItems[i].title; caseCover[i].href=portfolioItems[i].link; caseTitle[i].href=portfolioItems[i].link; caseCover[i].style.backgroundImage = 'url('+(portfolioItems[i].cover)+')'; caseCover[i].style.backgroundSize = 'cover'; caseCover[i].style.backgroundRepeat = 'no-repeat'; }

4. Выбор валюты

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

//здесь представлен не полный код, а лишь его часть для демонстрации const api = "https://api.exchangerate-api.com/v4/latest/RUB"; // Include api for currency change const selectCurrency = document.getElementById('currency'); const tarifPrices = Array.from(document.querySelectorAll('.tarif-price')); const servicePrices = Array.from(document.querySelectorAll('.price-value')); const startTarifs = []; for (let i=0; i<tarifPrices.length; i++){ startTarifs.push(+tarifPrices[i].innerHTML); } const startServicePrices = []; for (let j=0; j<servicePrices.length; j++){ startServicePrices.push(+servicePrices[j].innerHTML); } let currentCur='RUB'; let rate; selectCurrency.addEventListener('change', (e)=>{ currentCur=`${e.target.value}`; getResults(); }) function getResults() { fetch(`${api}`) .then(currency =>{ return currency.json(); }).then(displayResults); } function displayResults(currency) { let rate = currency.rates[currentCur]; let curTarif; let curPrice; for (let i=0; i<tarifPrices.length; i++){ let sign = document.createElement('span'); if (currentCur=='RUB'){ sign.innerHTML=' &#8381'; tarifPrices[i].innerHTML = (startTarifs[i] * rate).toFixed(0); } else if (currentCur=='KZT'){ sign.innerHTML=' &#8376'; curTarif = (startTarifs[i] * rate*0.95).toFixed(0); switch(Array.from(String(curTarif)).length) { case 6: tarifPrices[i].innerHTML = Math.round(curTarif/1000)*1000; break; default: tarifPrices[i].innerHTML = curTarif; } } ....//далее аналогично для оставшихся валют } tarifPrices[i].appendChild(sign); } for (let j=0; j<servicePrices.length; j++){ let sign = document.createElement('span'); if (currentCur=='RUB'){ sign.innerHTML=' &#8381'; servicePrices[j].innerHTML = (startServicePrices[j] * rate).toFixed(0); } else if (currentCur=='KZT'){ sign.innerHTML=' &#8376'; curPrice = (startServicePrices[j] * rate*0.9).toFixed(0); switch(Array.from(String(curPrice)).length) { case 6: servicePrices[j].innerHTML = Math.round(curPrice/1000)*1000; break; case 5: servicePrices[j].innerHTML = Math.round(curPrice/100)*100; break; case 4: servicePrices[j].innerHTML = Math.round(curPrice/100)*100; break; default: servicePrices[j].innerHTML = curPrice; } ....//далее аналогично для оставшихся валют } } servicePrices[j].appendChild(sign); } }

На сайте есть еще множество особенностей, которые вы сами сможете заметить, самостоятельно изучив его)

Если же вы сами подумываете над тем, чтобы обратиться в наше агентство за сайтом для вашего бизнеса, то сам сайт ne.studio поможет вам определиться, какой подход к созданию сайтов подходит лично вам - верстка сайта с использованием ноу-код платформ таких, как Tilda и Webflow, или же разработка сайта с помощью ручного кода. У обоих подходов есть как минусы, так и плюсы, подробнее узнать о них и понять, что больше подходит вам, вы сможете, проконсультировавшись с нашей командой)

Все проекты диджитал агентства ne.studio можно посмотреть тут, заглядывайте!

77
Начать дискуссию