Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds " 5 easy steps" scroller for company landing page #60

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions offerzen/global/company/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
.easy-steps {
margin: auto;
max-width: 1200px;
padding: 0 20px;
display: none;
padding-top: 100px;
}

.easy-steps.visible {
display: block !important;
}

.easy-steps-content {
display: flex;
gap: 20px;
flex-direction: row;
margin-top: -220px;
margin-bottom: -20vh;
}

.easy-steps-content>* {
flex: 1 0;
}

.easy-steps-header {
position: sticky;
top: 60px;
backdrop-filter: blur(4px);
background: #ffffffb0;
margin: 0;
text-align: center;
z-index: 1;
margin-bottom: 220px;
}

.easy-steps-header h2 {
margin: 0 auto;
max-width: 650px;
line-height: 120%;
font-weight: 700;
font-size: 28px;
color: #0e204b;
padding: 20px;
}

@media (min-width: 700px) and (min-height: 600px) {
.easy-steps-header h2 {
font-size: 40px;
}
}

.easy-steps-header h2 strong {
color: #2f96f4;
}

.easy-steps-list-image {
position: sticky;
top: 0;
background: #d8deff;
max-height: 100vh;
display: none;
}

@media (min-width: 700px) and (min-height: 600px) {
.easy-steps-list-image {
display: block;
}
}

.easy-steps-list-image .easy-steps-list-item {
position: absolute;
padding: 30px;
}

.easy-steps-list-image .easy-steps-list-item__image {
background: rgba(0, 0, 0, 0.3);
max-width: 100%;
box-shadow: -1px -1px 0 3px rgba(0, 0, 0, 0.3);
border-radius: 5px;
transform-origin: center top;
overflow: hidden;
transition: transform 0.2s ease-out;
}

@media (min-width: 700px) and (min-height: 600px) {
.easy-steps-list-text {
padding-top: 30vh;
padding-bottom: 30vh;
}
}

.easy-steps-list-text .easy-steps-list-item {
display: flex;
flex-direction: column;
justify-content: flex-start;
padding-bottom: 10vh;
align-items: center;
}

@media (min-width: 700px) and (min-height: 600px) {
.easy-steps-list-text .easy-steps-list-item {
height: 80vh;
}

.easy-steps-list-text .easy-steps-list-item:last-child {
height: 40vh;
}
}

.easy-steps-list-text .easy-steps-list-item__container {
max-width: 600px;
}

.easy-steps-list-text .easy-steps-list-item__mobile {
max-width: 100%;
}

@media (min-width: 700px) and (min-height: 600px) {
.easy-steps-list-text .easy-steps-list-item__mobile {
display: none;
}
}

.easy-steps-list-text .easy-steps-list-item__mobile-image {
max-width: 100%;
}

.easy-steps-list-text .easy-steps-list-item__number {
margin-right: 12px;
}

.easy-steps-list-text .easy-steps-list-item__title {
display: flex;
align-items: center;
}

.easy-steps-list-text .easy-steps-list-item__number {
border-radius: 50px;
color: #fff;
display: inline-flex;
justify-content: center;
align-items: center;
background: #1e8dee;
min-width: 29px;
min-height: 29px;
border: 3px solid #000;
box-shadow: inset 1px 1px 3px 0 rgba(255, 255, 255, 0.7);
}

@media (min-width: 700px) and (min-height: 600px) {
.easy-steps-list-text .easy-steps-list-item:first-child {
padding-top: 20vh;
}
}

.easy-steps-cta {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
position: relative;
z-index: 1;
background: #fff;
height: 220px;
}
83 changes: 83 additions & 0 deletions offerzen/global/company/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
window.$loaded(function (window, document, $, undefined) {
const stepsEl = $('[data-js="steps"]')
const textContentEl = $('[data-js="text-list"]')
const textListItemEls = textContentEl.find('[data-js="text-list-item"]')
const imageContentEl = $('[data-js="image-list"]')
const imageListItemEls = imageContentEl.find('[data-js="image-list-item"]')

function clamp(val, min = 0, max = 1) {
return Math.max(min, Math.min(val, max))
}

function clampPercent(val, min, max) {
const clampedVal = clamp(val, min, max)

const area = max - min
return (clampedVal - min) / area
}

function domain(val, [min, max], [toMin, toMax]) {
val = clamp(val, min, max)
const range = ((val - min) / (max - min)) * (toMax - toMin) + toMin
return range
}

function update(index, textNode) {
const deadZoneAbove = 0 // percent
const deadZoneBelow = 0.1 // percent
const textContainerEl = $(textNode)
const textEl = textContainerEl.find(':first-child') // wrapping div
const imageEl = $(imageListItemEls[index])
const imageInnerEl = imageEl.find(':first-child')
const scrollY = window.scrollY
const position = textEl.offset().top + textEl.height() / 2 - scrollY // position of middle of content
const scrollArea = window.innerHeight
const positionPercent = clamp(position / scrollArea) // percent of text el on screen (0 = top, 1 = bottom)
const fadeSpeed = 3 // integer, higher is faster
const scrollSpeed = 3 // integer, higher is faster
const imageTargetPercent = 0.4
let adjustedPositionPercent = 1
let opacity = 0
let scale = 1

if (positionPercent < imageTargetPercent) {
adjustedPositionPercent =
clampPercent(positionPercent, 0, imageTargetPercent - deadZoneAbove) - 1
opacity = 1 + adjustedPositionPercent
scale = Math.pow(domain(opacity, [0, 1], [0.8, 1]), 2)
} else {
adjustedPositionPercent = clampPercent(
positionPercent,
0.5 + deadZoneBelow,
1
)
adjustedPositionPercent = Math.pow(adjustedPositionPercent, scrollSpeed)
opacity = 1 - domain(adjustedPositionPercent, [0, 1], [0, 0.6])
}
opacity = Math.pow(opacity, fadeSpeed)
opacity = domain(opacity, [0, 1], [0.3, 1])

const imageAreaPadding = 20 // move image offscreen by this amount
const imageOffset = -imageEl.height() / 2 // center image to imageTargetPercent
const imageArea = scrollArea * (1 - imageTargetPercent)
const adjustedImageArea = imageArea - imageOffset + imageAreaPadding // account for offset and add some padding
const imageTarget = scrollArea * imageTargetPercent
const imagePosition =
imageTarget + adjustedImageArea * adjustedPositionPercent + imageOffset

imageEl.css({
transform: `translate3d(0, ${imagePosition}px, 1px)`,
opacity
})
imageInnerEl.css({
transform: `scale(${scale})`
})
}

// init
textListItemEls.each(update)
window.addEventListener('resize', (e) => textListItemEls.each(update))
document.addEventListener('scroll', (e) => textListItemEls.each(update))

stepsEl.addClass('visible')
})