Tabs
Circle Animated Tabs
17 Oct 2022
Circle Animated Tabs
HTML
SCSS
PostCSS
JS
<section class="specialisms-list" data-default-transform="0deg">
<div class="container">
<div class="specialisms-items">
<div class="logo">
<img src="./images/Logo.svg" alt="" />
</div>
<div class="specialisms_text"></div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Manufacturing and Production</p>
<div class="icon">
<img src="./images/benefit-1.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Materials Management</p>
<div class="icon">
<img src="./images/benefit-2.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Admin and office management</p>
<div class="icon">
<img src="./images/benefit-3.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Supply Chain, Inventory and Planning</p>
<div class="icon">
<img src="./images/benefit-4.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Commercial & Business Development</p>
<div class="icon">
<img src="./images/benefit-5.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Purchasing & Procurement</p>
<div class="icon">
<img src="./images/benefit-6.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Consultancy</p>
<div class="icon">
<img src="./images/benefit-7.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Freight & Shipping/import and export management</p>
<div class="icon">
<img src="./images/benefit-8.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Project Management /Business Transformation</p>
<div class="icon">
<img src="./images/benefit-9.svg" alt="" />
</div>
</div>
</div>
<div class="specialisms-wrap">
<div class="specialism_item">
<p>Warehousing and Distribution</p>
<div class="icon">
<img src="./images/benefit-10.svg" alt="" />
</div>
</div>
</div>
</div>
</div>
</section>
.specialisms-list {
padding-top: 200px;
padding-bottom: 100px;
width: 100%;
.container {
width: 89%;
margin: 0 auto;
}
}
.specialisms-items {
position: relative;
flex-shrink: 0;
width: min(80vh, 80vw);
height: min(80vh, 80vw);
max-width: 848px;
max-height: 848px;
margin: 0 auto;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
.logo {
position: absolute;
width: 300px;
top: 50%;
transform: translateY(-50%);
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
&.active {
top: 35%;
transform: translateY(-50%) scale(0.8);
}
}
@include media(550) {
width: 440px;
height: 440px;
margin-left: -160px;
.logo {
width: 180px;
}
}
@include media(371) {
width: 380px;
height: 380px;
.logo {
margin-right: -100px;
}
}
}
.specialisms-wrap {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transform-origin: center;
transform: rotate(0deg);
display: flex;
justify-content: center;
align-items: center;
text-align: center;
transition: ease-in-out 0.5s;
}
.specialism_item {
border-radius: 50%;
width: min(15vh, 15vw);
height: min(15vh, 15vw);
max-width: 221px;
max-height: 221px;
position: absolute;
top: 0;
transform: translateY(-50%);
transform-origin: top;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
transition: ease-in-out 0.5s;
opacity: 0.5;
&.active {
opacity: 1;
}
p {
display: none;
}
.icon {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
img {
width: min(100%, 72px);
height: min(100%, 72px);
object-fit: contain;
}
}
}
.specialisms_text {
position: absolute;
text-align: center;
max-width: 80%;
p {
font-size: ac(22px, 14px);
}
@include media(550) {
width: 200px;
margin-right: -50px;
margin-top: 40px;
}
@include media(371) {
margin-right: -100px;
margin-top: 40px;
width: 170px;
}
}
.specialisms-list {
padding-top: 200px;
padding-bottom: 100px;
width: 100%;
.container {
width: 89%;
margin: 0 auto;
}
}
.specialisms-items {
position: relative;
flex-shrink: 0;
width: min(80vh, 80vw);
height: min(80vh, 80vw);
max-width: 848px;
max-height: 848px;
margin: 0 auto;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
.logo {
position: absolute;
width: 300px;
top: 50%;
transform: translateY(-50%);
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
&.active {
top: 35%;
transform: translateY(-50%) scale(0.8);
}
}
@mixin media 550 {
width: 440px;
height: 440px;
margin-left: -160px;
.logo {
width: 180px;
}
}
@mixin media 371 {
width: 380px;
height: 380px;
.logo {
margin-right: -100px;
}
}
}
.specialisms-wrap {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transform-origin: center;
transform: rotate(0deg);
display: flex;
justify-content: center;
align-items: center;
text-align: center;
transition: ease-in-out 0.5s;
}
.specialism_item {
border-radius: 50%;
width: min(15vh, 15vw);
height: min(15vh, 15vw);
max-width: 221px;
max-height: 221px;
position: absolute;
top: 0;
transform: translateY(-50%);
transform-origin: top;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
transition: ease-in-out 0.5s;
opacity: 0.5;
&.active {
opacity: 1;
}
p {
display: none;
}
.icon {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
img {
width: min(100%, 72px);
height: min(100%, 72px);
object-fit: contain;
}
}
}
.specialisms_text {
position: absolute;
text-align: center;
max-width: 80%;
p {
font-size: ac(22px, 14px);
}
@mixin media 550 {
width: 200px;
margin-right: -50px;
margin-top: 40px;
}
@mixin media 371 {
margin-right: -100px;
margin-top: 40px;
width: 170px;
}
}
function isInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
// CIRCLE
const specialismCircleBlock =
document.getElementsByClassName(`specialisms-list`)[0];
if (specialismCircleBlock) {
const container = specialismCircleBlock.querySelector(".container");
const wrapArr = Array.from(
specialismCircleBlock.querySelectorAll(`.specialisms-wrap`)
);
const itemArr = Array.from(
specialismCircleBlock
.querySelector(".specialisms-items")
.querySelectorAll(`.specialism_item`)
);
const logo = specialismCircleBlock.querySelector(".logo");
function rotateAnimation() {
itemArr.forEach((elem) => elem.classList.remove("active"));
logo.classList.add("active");
let activeIndex = 1;
itemArr[0].classList.add("active");
textWrap.innerHTML = `<p>${wrapArr[0].querySelector("p").innerHTML}</p>`;
setInterval(function () {
let trueIndex = itemArr.length - (activeIndex % wrapArr.length);
let previousActiveItem = itemArr[(trueIndex + 1) % itemArr.length];
let activeItem = itemArr[trueIndex % itemArr.length];
let activeWrap = wrapArr[trueIndex % wrapArr.length];
textWrap.innerHTML = `<p>${activeWrap.querySelector("p").innerHTML}</p>`;
previousActiveItem.classList.remove("active");
activeItem.classList.add("active");
wrapArr.forEach((elem, index) => {
elem.style.transform = `rotate(${
(activeIndex + index) * step + defaultTransform
}deg)`;
elem.children[0].style.transform = `rotate(${
-1 * ((activeIndex + index) * step + defaultTransform)
}deg) translateY(-50%)`;
});
activeIndex += 1;
}, 3200);
}
itemArr.forEach((elem) => elem.classList.add("active"));
const textWrap = specialismCircleBlock.querySelector(".specialisms_text");
const step = 360 / wrapArr.length;
let newStep = step * 2;
const defaultTransform = +specialismCircleBlock
.getAttribute("data-default-transform")
.replace("deg", "");
wrapArr.forEach((elem, index) => {
elem.style.transform = `rotate(${index * step + defaultTransform}deg)`;
elem.children[0].style.transform = `rotate(${
-1 * (index * step + defaultTransform)
}deg) translateY(-50%)`;
});
let scrollFlag = isInViewport(container);
if (scrollFlag) rotateAnimation();
document.addEventListener("scroll", function () {
if (scrollFlag) return;
scrollFlag = isInViewport(container);
if (scrollFlag) rotateAnimation();
});
}
Коло, яке автоматично, кожні 3 секунди, обертається і міняється контент в середині. Айтеми автоматично розташовуються по всьому колу рівномірно.
Підходить добре для секцій з бенефітсами чи спеціалізацією.
Є можливість, завдяки дата-атрибуту data-default-transform, задати дефолтний поворот всього коло, якщо в дизайні воно трохи повернуто.
В цьому варіанті на телефонах секція зсувається трошки вліво, за межі екрану.