Implement GSAP Features in 'neler-yapariz-gsap' Template: Introduced a comprehensive set of GSAP animations and sections in the 'neler-yapariz-gsap' template, enhancing the visual dynamics of the page. This update includes new JavaScript and CSS files for various animations, such as flip, inertia, marquee, and scrolltrigger, along with a structured layout for improved user interaction. Additionally, localization support has been integrated for all text elements, ensuring a seamless experience for users across different languages.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
@extends('layouts.gsap', ['header' => 'partials.header', 'footer' => 'partials.footer'])
|
||||
|
||||
@section('title', t('Neler Yapıyoruz?') ?: 'Neler Yapıyoruz?')
|
||||
|
||||
@push('styles')
|
||||
@include('templates.neler-yapariz.external-links')
|
||||
<style>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/css/main.css')) !!}
|
||||
</style>
|
||||
<style>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/css/additional.css')) !!}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
@include('templates.neler-yapariz.navigation')
|
||||
|
||||
<div id="smooth-wrapper" data-start="hidden" class="scroll-wrapper">
|
||||
<main id="smooth-content" class="main">
|
||||
@include('templates.neler-yapariz.sections.hero')
|
||||
|
||||
@include('templates.neler-yapariz.sections.flip')
|
||||
@include('templates.neler-yapariz.sections.slider')
|
||||
@include('templates.neler-yapariz.sections.inertia')
|
||||
@include('templates.neler-yapariz.sections.text')
|
||||
@include('templates.neler-yapariz.sections.marquee')
|
||||
</div>
|
||||
|
||||
@include('templates.neler-yapariz.sections.footer')
|
||||
</main>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
@include('templates.neler-yapariz.external-scripts')
|
||||
|
||||
{{-- Navigation Scripts --}}
|
||||
@include('templates.neler-yapariz.js.nav')
|
||||
@include('templates.neler-yapariz.js.section-selector')
|
||||
|
||||
{{-- Hero Script --}}
|
||||
@include('templates.neler-yapariz.js.hero')
|
||||
|
||||
{{-- Section Scripts --}}
|
||||
@include('templates.neler-yapariz.js.flip')
|
||||
@include('templates.neler-yapariz.js.section-scroll')
|
||||
@include('templates.neler-yapariz.js.scrolltrigger')
|
||||
@include('templates.neler-yapariz.js.slider')
|
||||
@include('templates.neler-yapariz.js.inertia')
|
||||
@include('templates.neler-yapariz.js.text')
|
||||
@include('templates.neler-yapariz.js.marquee')
|
||||
|
||||
{{-- Footer Scripts --}}
|
||||
@include('templates.neler-yapariz.js.footerlogo')
|
||||
@include('templates.neler-yapariz.js.copybtn-buttons')
|
||||
|
||||
{{-- Global Scripts --}}
|
||||
@include('templates.neler-yapariz.js.global')
|
||||
|
||||
@endpush
|
||||
@@ -0,0 +1,128 @@
|
||||
<script>
|
||||
{
|
||||
/** -- Copy Button */
|
||||
const copybtn = () => {
|
||||
const copybtn = [...document.querySelectorAll("[data-module='copybtn']")];
|
||||
|
||||
// Create a map to store data for each button
|
||||
const buttonDataMap = new Map();
|
||||
|
||||
// Single event listener that checks which button's data to use
|
||||
document.addEventListener("copy", (event) => {
|
||||
const activeButtonData = buttonDataMap.get("active");
|
||||
if (activeButtonData) {
|
||||
event.preventDefault();
|
||||
event.clipboardData.setData(
|
||||
"application/json",
|
||||
JSON.stringify(activeButtonData)
|
||||
);
|
||||
event.clipboardData.setData(
|
||||
"text/plain",
|
||||
JSON.stringify(activeButtonData)
|
||||
);
|
||||
buttonDataMap.delete("active"); // Clear after copying
|
||||
}
|
||||
});
|
||||
|
||||
copybtn.forEach((btn) => {
|
||||
const url = btn.getAttribute("data-copy");
|
||||
const text = btn.children[0].children[0];
|
||||
const icon = btn.querySelector("svg");
|
||||
let isAnimating = false;
|
||||
|
||||
btn.onmouseenter = async () => {
|
||||
if (isAnimating) return;
|
||||
isAnimating = true;
|
||||
|
||||
await gsap.to(icon, {
|
||||
rotate: "+=360",
|
||||
duration: 0.3,
|
||||
ease: "expo.out",
|
||||
});
|
||||
|
||||
isAnimating = false;
|
||||
};
|
||||
|
||||
btn.onclick = async (evt) => {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
let data = await res.text();
|
||||
|
||||
// Try to parse as JSON in case it's JSON data
|
||||
try {
|
||||
const jsonData = JSON.parse(data);
|
||||
buttonDataMap.set("active", jsonData);
|
||||
} catch {
|
||||
buttonDataMap.set("active", data);
|
||||
}
|
||||
|
||||
// Trigger the copy command
|
||||
document.execCommand("copy");
|
||||
|
||||
text.textContent = "Copied!";
|
||||
console.log("copied successfully");
|
||||
|
||||
setTimeout(() => {
|
||||
text.textContent = "Copy this";
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
console.error("Failed to copy:", error);
|
||||
text.textContent = "Failed to copy";
|
||||
|
||||
setTimeout(() => {
|
||||
text.textContent = "Copy this";
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/** -- Split Text Button */
|
||||
const split = (text, type = "chars") => {
|
||||
text.setAttribute("aria-label", text.textContent);
|
||||
const splits = new SplitText(text, { type });
|
||||
splits[type].forEach((char) => char.setAttribute("aria-hidden", "true"));
|
||||
return splits[type];
|
||||
};
|
||||
|
||||
const buttons = () => {
|
||||
const buttons = [...document.querySelectorAll("[data-module='btn']")];
|
||||
|
||||
buttons.forEach((btn) => {
|
||||
const overflow = btn.children[0];
|
||||
const text = overflow.children[0];
|
||||
|
||||
overflow.appendChild(text.cloneNode(true));
|
||||
const splitText1 = split(overflow.children[0], "chars");
|
||||
const splitText2 = split(overflow.children[1], "chars");
|
||||
|
||||
const animation = {
|
||||
yPercent: "-=100",
|
||||
duration: 0.8,
|
||||
ease: "expo.out",
|
||||
stagger: 0.02,
|
||||
};
|
||||
|
||||
btn.onmouseenter = () => {
|
||||
gsap.to(splitText1, { ...animation, yPercent: -100 });
|
||||
gsap.to(splitText2, { ...animation, yPercent: -100 });
|
||||
};
|
||||
|
||||
btn.onmouseleave = () => {
|
||||
gsap.to(splitText1, { ...animation, yPercent: 0 });
|
||||
gsap.to(splitText2, { ...animation, yPercent: 0 });
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/** -- Controller */
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
copybtn();
|
||||
|
||||
// desktop only animations
|
||||
if (window.matchMedia("(min-width: 1024px)").matches) {
|
||||
buttons();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script>
|
||||
// https://codepen.io/GreenSock/pen/RwLepdQ?editors=1010
|
||||
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const wrapper = document.querySelector("[data-animate='flip']");
|
||||
const toggles = [...wrapper.querySelector("[data-flip='toggle']").children];
|
||||
const items = wrapper.querySelector("[data-flip='item']");
|
||||
|
||||
// console.log("flip", wrapper, toggles, items);
|
||||
|
||||
const flipGridList = () => {
|
||||
const state = Flip.getState(items.children);
|
||||
items.classList.toggle("list");
|
||||
|
||||
Flip.from(state, {
|
||||
duration: 0.8,
|
||||
ease: "expo.out",
|
||||
onComplete: () => {
|
||||
ScrollTrigger.refresh();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
toggles.forEach((toggle, index) => {
|
||||
toggle.addEventListener("click", () => {
|
||||
toggles[0].classList.toggle("current");
|
||||
toggles[1].classList.toggle("current");
|
||||
flipGridList();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,71 @@
|
||||
<script>
|
||||
{
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const wrapper = document.querySelector("[data-animate='footerlogo']");
|
||||
if (!wrapper) return;
|
||||
|
||||
const paths = [...wrapper.querySelectorAll("path")].reverse();
|
||||
const lastPath = paths[paths.length - 1];
|
||||
|
||||
// Configuration for the footer logo animation
|
||||
const FOOTER_ANIMATION_CONFIG = {
|
||||
STAGGER: 0.05,
|
||||
VISIBILITY_DURATION: 0.1,
|
||||
};
|
||||
|
||||
// Set initial state
|
||||
gsap.set(paths, {
|
||||
autoAlpha: 0,
|
||||
});
|
||||
|
||||
const animateFooterLogo = () => {
|
||||
// Reset the last path visibility before starting the animation
|
||||
gsap.set(lastPath, { autoAlpha: 0 });
|
||||
|
||||
const tl = gsap.timeline();
|
||||
|
||||
paths.forEach((path, index) => {
|
||||
const baseDelay = index * FOOTER_ANIMATION_CONFIG.STAGGER;
|
||||
const isLastPath = index === paths.length - 1;
|
||||
|
||||
// Flash animation
|
||||
tl.to(
|
||||
path,
|
||||
{
|
||||
autoAlpha: 1,
|
||||
duration: 0.1,
|
||||
ease: "none",
|
||||
},
|
||||
baseDelay
|
||||
);
|
||||
|
||||
// Only fade out if it's not the last path
|
||||
if (!isLastPath) {
|
||||
tl.to(
|
||||
path,
|
||||
{
|
||||
autoAlpha: 0,
|
||||
duration: 0.1,
|
||||
ease: "none",
|
||||
},
|
||||
baseDelay + FOOTER_ANIMATION_CONFIG.VISIBILITY_DURATION
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return tl;
|
||||
};
|
||||
|
||||
// Create the scroll trigger
|
||||
ScrollTrigger.create({
|
||||
trigger: wrapper,
|
||||
start: "top bottom",
|
||||
end: "bottom top",
|
||||
onEnter: () => animateFooterLogo(),
|
||||
onEnterBack: () => animateFooterLogo(),
|
||||
});
|
||||
|
||||
// console.log(event.detail);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,81 @@
|
||||
<script>
|
||||
{
|
||||
let lenis;
|
||||
|
||||
const initScroll = () => {
|
||||
lenis = new Lenis({});
|
||||
lenis.on("scroll", ScrollTrigger.update);
|
||||
gsap.ticker.add((time) => lenis.raf(time * 1000));
|
||||
gsap.ticker.lagSmoothing(0);
|
||||
};
|
||||
|
||||
function initGsapGlobal() {
|
||||
/** Do everything that needs to happen
|
||||
* before triggering all
|
||||
* the gsap animations */
|
||||
|
||||
initScroll();
|
||||
|
||||
// match reduced motion media
|
||||
// const media = gsap.matchMedia();
|
||||
|
||||
/** Send a custom
|
||||
* event to all your
|
||||
* gsap animations
|
||||
* to start them */
|
||||
|
||||
const sendGsapEvent = () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("GSAPReady", {
|
||||
detail: {
|
||||
lenis,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
// Check if fonts are already loaded
|
||||
if (document.fonts.status === "loaded") {
|
||||
sendGsapEvent();
|
||||
} else {
|
||||
document.fonts.ready.then(() => {
|
||||
sendGsapEvent();
|
||||
});
|
||||
}
|
||||
|
||||
/** We need specific handling because the
|
||||
* grid/list changes the scroll height of the whole container
|
||||
*/
|
||||
|
||||
let resizeTimeout;
|
||||
const onResize = () => {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(() => {
|
||||
ScrollTrigger.refresh();
|
||||
}, 50);
|
||||
};
|
||||
|
||||
window.addEventListener("resize", () => onResize());
|
||||
const resizeObserver = new ResizeObserver((entries) => onResize());
|
||||
resizeObserver.observe(document.body);
|
||||
|
||||
queueMicrotask(() => {
|
||||
gsap.to("[data-start='hidden']", {
|
||||
autoAlpha: 1,
|
||||
duration: 0.1,
|
||||
delay: 0.2,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// this only for dev
|
||||
const documentReady =
|
||||
document.readyState === "complete" || document.readyState === "interactive";
|
||||
|
||||
if (documentReady) {
|
||||
initGsapGlobal();
|
||||
} else {
|
||||
addEventListener("DOMContentLoaded", (event) => initGsapGlobal());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,265 @@
|
||||
<script>
|
||||
{
|
||||
const split = (text, type = "chars") => {
|
||||
// Handle both single elements and arrays of elements
|
||||
const elements = Array.isArray(text) ? text : [text];
|
||||
|
||||
// Set aria labels
|
||||
elements.forEach((element) => {
|
||||
if (element && typeof element.setAttribute === "function") {
|
||||
element.setAttribute("aria-label", element.textContent);
|
||||
}
|
||||
});
|
||||
|
||||
// Split text and set aria-hidden
|
||||
const splits = new SplitText(text, { type });
|
||||
splits[type].forEach((char) => {
|
||||
if (char && typeof char.setAttribute === "function") {
|
||||
char.setAttribute("aria-hidden", "true");
|
||||
}
|
||||
});
|
||||
|
||||
return splits[type];
|
||||
};
|
||||
|
||||
/** -- Setup and Utils */
|
||||
|
||||
let titleSplit,
|
||||
parSplit,
|
||||
layerItems,
|
||||
isIn = false;
|
||||
|
||||
const animateIn = async (delay = 0) => {
|
||||
isIn = true;
|
||||
animateStripesOut();
|
||||
|
||||
gsap.to(parSplit, {
|
||||
autoAlpha: 1,
|
||||
yPercent: 0,
|
||||
duration: 0.8,
|
||||
delay: 0.65,
|
||||
ease: "expo.out",
|
||||
stagger: {
|
||||
each: 0.08,
|
||||
},
|
||||
});
|
||||
|
||||
await gsap.to(titleSplit.flat(), {
|
||||
yPercent: 0,
|
||||
duration: 1.2,
|
||||
delay: delay,
|
||||
ease: "expo.out",
|
||||
stagger: {
|
||||
each: 0.01,
|
||||
from: "end",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const animateOut = async () => {
|
||||
isIn = false;
|
||||
animateStripesIn();
|
||||
|
||||
gsap.to(parSplit, {
|
||||
autoAlpha: 0,
|
||||
yPercent: 100,
|
||||
duration: 0.8,
|
||||
ease: "expo.out",
|
||||
stagger: {
|
||||
each: 0.08,
|
||||
},
|
||||
});
|
||||
|
||||
await gsap.to(titleSplit.flat(), {
|
||||
yPercent: 110,
|
||||
duration: 0.8,
|
||||
ease: "expo.out",
|
||||
delay: 0.1,
|
||||
stagger: {
|
||||
each: 0.01,
|
||||
from: "center",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/** -- Scribble Animaiton */
|
||||
let isScribbling = false;
|
||||
const SCRIBBLE_CONFIG = {
|
||||
ROTATION_RANGE: 20,
|
||||
TIME_BETWEEN_SCRIBBLES: 0.015,
|
||||
VISIBILITY_DURATION: 0.01,
|
||||
REVERSE_ORDER: true,
|
||||
};
|
||||
|
||||
const animateScribble = (scribble) => {
|
||||
if (isScribbling) return;
|
||||
isScribbling = true;
|
||||
|
||||
gsap.set(scribble, { autoAlpha: 0, rotation: 0 });
|
||||
|
||||
const tl = gsap.timeline();
|
||||
|
||||
const scribblesToAnimate = [...scribble].reverse();
|
||||
|
||||
scribblesToAnimate.forEach((item, index) => {
|
||||
const randomRotation =
|
||||
Math.random() * SCRIBBLE_CONFIG.ROTATION_RANGE -
|
||||
SCRIBBLE_CONFIG.ROTATION_RANGE / 2;
|
||||
const baseDelay = index * SCRIBBLE_CONFIG.TIME_BETWEEN_SCRIBBLES;
|
||||
|
||||
tl.add(
|
||||
gsap.set(item, {
|
||||
autoAlpha: 1,
|
||||
rotation: randomRotation,
|
||||
delay: baseDelay,
|
||||
})
|
||||
);
|
||||
|
||||
tl.add(
|
||||
gsap.set(item, {
|
||||
autoAlpha: 0,
|
||||
delay: baseDelay + SCRIBBLE_CONFIG.VISIBILITY_DURATION,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
tl.call(() => {
|
||||
isScribbling = false;
|
||||
});
|
||||
};
|
||||
|
||||
// hero stripes animation
|
||||
let heroStripes,
|
||||
stripes,
|
||||
stripesAnimation = null;
|
||||
|
||||
const calcX = (i) => {
|
||||
return i % 2 === 0
|
||||
? -heroStripes[i].scrollWidth
|
||||
: heroStripes[i].scrollWidth;
|
||||
};
|
||||
|
||||
const animateStripesIn = () => {
|
||||
if (stripesAnimation) {
|
||||
stripesAnimation.kill();
|
||||
}
|
||||
|
||||
// play video on the hero
|
||||
document.querySelector("video").play()
|
||||
|
||||
gsap.set(heroStripes, {
|
||||
autoAlpha: 1,
|
||||
x: (i) => calcX(i),
|
||||
yPercent: (i) => (heroStripes.length / 2 - i) * 80,
|
||||
});
|
||||
|
||||
gsap.set(stripes, {
|
||||
rotation: (i) => Math.random() * 30,
|
||||
ease: "expo.out",
|
||||
});
|
||||
|
||||
stripesAnimation = gsap.to(heroStripes, {
|
||||
x: 0,
|
||||
delay: 0.2,
|
||||
duration: (i) => Math.random() + 1.2,
|
||||
ease: "expo.out",
|
||||
});
|
||||
};
|
||||
|
||||
const animateStripesOut = () => {
|
||||
if (stripesAnimation) {
|
||||
stripesAnimation.kill();
|
||||
}
|
||||
|
||||
stripesAnimation = gsap.to(heroStripes, {
|
||||
x: (i) => calcX(i),
|
||||
duration: 0.8,
|
||||
ease: "expo.out",
|
||||
});
|
||||
};
|
||||
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const wrapper = document.querySelector("[data-module='hero']");
|
||||
if (!wrapper) return;
|
||||
|
||||
const layer = wrapper.querySelector("[data-hero='layer']");
|
||||
layerItems = layer.children;
|
||||
const title = wrapper.querySelector("[data-hero='title']");
|
||||
const toggle = wrapper.querySelector("[data-hero='toggle']");
|
||||
const alpha = document.querySelectorAll("[data-hero='alpha']");
|
||||
const par = document.querySelectorAll("[data-hero='par']");
|
||||
const scribble = [
|
||||
...document.querySelector("[data-hero='scribble']").children[0].children,
|
||||
];
|
||||
|
||||
stripes = [...layer.children];
|
||||
heroStripes = stripes.map((item) => item.children[0]);
|
||||
gsap.set(heroStripes, { autoAlpha: 0 });
|
||||
|
||||
gsap.to(layer, {
|
||||
yPercent: 10,
|
||||
scrollTrigger: {
|
||||
trigger: layer,
|
||||
start: "top top",
|
||||
end: "+=100%",
|
||||
scrub: true,
|
||||
},
|
||||
});
|
||||
|
||||
// split
|
||||
titleSplit = split(title.children, "chars");
|
||||
parSplit = split(par, "lines");
|
||||
|
||||
// initial state
|
||||
gsap.set(titleSplit.flat(), { yPercent: -110 });
|
||||
gsap.set(layer, { autoAlpha: 1 });
|
||||
gsap.set(toggle, { scale: 3, rotation: 360 });
|
||||
gsap.set(parSplit, { autoAlpha: 0, yPercent: 100 });
|
||||
gsap.set(alpha, { autoAlpha: 0, scale: 0.7 });
|
||||
gsap.set(scribble, { autoAlpha: 0 });
|
||||
|
||||
animateIn(0.6);
|
||||
|
||||
gsap.to(toggle, {
|
||||
scale: 1,
|
||||
rotation: 0,
|
||||
delay: 0,
|
||||
duration: 1.2,
|
||||
ease: "expo.inOut",
|
||||
});
|
||||
|
||||
gsap.to(parSplit, {
|
||||
autoAlpha: 1,
|
||||
yPercent: 0,
|
||||
duration: 0.8,
|
||||
delay: 0.65,
|
||||
ease: "expo.out",
|
||||
stagger: {
|
||||
each: 0.08,
|
||||
},
|
||||
});
|
||||
|
||||
gsap.to(alpha, {
|
||||
autoAlpha: 1,
|
||||
scale: 1,
|
||||
duration: 0.8,
|
||||
delay: 0.9,
|
||||
ease: "expo.out",
|
||||
});
|
||||
|
||||
toggle.querySelector("input").addEventListener("change", (event) => {
|
||||
if (event.target.checked) {
|
||||
animateOut();
|
||||
} else {
|
||||
animateIn();
|
||||
}
|
||||
});
|
||||
|
||||
toggle.onmouseenter = () => {
|
||||
if (!isIn) return;
|
||||
// console.log("mouseenter");
|
||||
animateScribble(scribble);
|
||||
};
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,166 @@
|
||||
<script>
|
||||
{
|
||||
/** Utility Functions */
|
||||
const split = (text, type = "chars") => {
|
||||
text.setAttribute("aria-label", text.textContent);
|
||||
const splits = new SplitText(text, { type });
|
||||
splits[type].forEach((char) => char.setAttribute("aria-hidden", "true"));
|
||||
return splits[type];
|
||||
};
|
||||
|
||||
const getParams = (item) => {
|
||||
const { duration, delay, stagger, ease, type } = item.dataset;
|
||||
const params = {
|
||||
duration: 1.2,
|
||||
delay: 0,
|
||||
type: "chars",
|
||||
};
|
||||
|
||||
if (duration) params.duration = parseFloat(duration);
|
||||
if (delay) params.delay = parseFloat(delay);
|
||||
if (type && (type === "chars" || type === "words" || type === "lines"))
|
||||
params.type = type;
|
||||
|
||||
return params;
|
||||
};
|
||||
|
||||
const baseAnimation = (item) => {
|
||||
const params = getParams(item);
|
||||
return {
|
||||
duration: params.duration,
|
||||
delay: params.delay,
|
||||
ease: "expo.out",
|
||||
// stagger each item so the letters come in one after the other
|
||||
stagger: {
|
||||
each: 0.04,
|
||||
from: "start",
|
||||
},
|
||||
scrollTrigger: {
|
||||
trigger: item,
|
||||
// use scrolltrigger to trigger on enter and reset on exit
|
||||
toggleActions: "play reset play reset",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/** (1) Split Reveal Animation */
|
||||
function createSplitRevealAnimation(item) {
|
||||
const params = getParams(item); // 1. get params from attributes
|
||||
const text = split(item, params.type); // 2. split the text
|
||||
item.style.overflow = "hidden"; // 3. set container to overflow
|
||||
|
||||
// 4. create the animation
|
||||
return gsap.fromTo(
|
||||
text,
|
||||
{ yPercent: 120 },
|
||||
{
|
||||
...baseAnimation(item),
|
||||
yPercent: 0,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createScrambledAnimation(item) {
|
||||
const text = item.textContent;
|
||||
const randomText = Array(text.length)
|
||||
.fill()
|
||||
.map(() => String.fromCharCode(Math.floor(Math.random() * (90 - 65) + 65)))
|
||||
.join("")
|
||||
.toLowerCase();
|
||||
|
||||
return gsap.fromTo(
|
||||
item.children[0],
|
||||
{
|
||||
scrambleText: randomText,
|
||||
},
|
||||
{
|
||||
...baseAnimation(item),
|
||||
scrambleText: text,
|
||||
chars: text,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createAlphaAnimation(item) {
|
||||
|
||||
const params = getParams(item); // 1. get params from attributes
|
||||
const text = split(item, "chars"); // 2. split the text
|
||||
|
||||
return gsap.fromTo(
|
||||
text,
|
||||
{ autoAlpha: 0 },
|
||||
{
|
||||
...baseAnimation(item),
|
||||
autoAlpha: 1,
|
||||
stagger: {
|
||||
each: 0.02,
|
||||
from: "random",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createSideAnimation(item) {
|
||||
const params = getParams(item);
|
||||
const outer = split(item, "chars");
|
||||
outer.forEach((char) => {
|
||||
char.style.overflow = "hidden";
|
||||
});
|
||||
const inner = split(item.children[0], "chars");
|
||||
|
||||
return gsap.fromTo(
|
||||
inner,
|
||||
{ x: 100 },
|
||||
{
|
||||
...baseAnimation(item),
|
||||
x: 0,
|
||||
stagger: {
|
||||
each: 0.02,
|
||||
from: "end",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createUpDownAnimation(item) {
|
||||
const params = getParams(item);
|
||||
const outer = split(item, "chars");
|
||||
outer.forEach((char) => {
|
||||
char.style.overflow = "hidden";
|
||||
});
|
||||
const inner = split(item.children[0], "chars");
|
||||
|
||||
return gsap.fromTo(
|
||||
inner,
|
||||
{
|
||||
yPercent: (i) => {
|
||||
return i % 2 === 0 ? 100 : -100;
|
||||
},
|
||||
},
|
||||
{
|
||||
...baseAnimation(item),
|
||||
yPercent: 0,
|
||||
stagger: {
|
||||
each: 0.02,
|
||||
from: "random",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** Main Text Effect Wrapper */
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const texts = [...document.querySelectorAll('[data-animate="text"]')];
|
||||
|
||||
texts.forEach((item) => {
|
||||
if (item.dataset.type === "chars") createSplitRevealAnimation(item);
|
||||
else if (item.dataset.type === "words") createSplitRevealAnimation(item);
|
||||
else if (item.dataset.type === "scramble") createScrambledAnimation(item);
|
||||
else if (item.dataset.type === "alpha") createAlphaAnimation(item);
|
||||
else if (item.dataset.type === "side") createSideAnimation(item);
|
||||
else if (item.dataset.type === "updown") createUpDownAnimation(item);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script>
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
// console.log("marquee");
|
||||
const wrapper = document.querySelector("[data-animate='marquee']");
|
||||
if (!wrapper) return;
|
||||
|
||||
const sections = [...wrapper.querySelectorAll("[data-marquee='line']")];
|
||||
|
||||
gsap.fromTo(
|
||||
sections,
|
||||
{
|
||||
x: (i) =>
|
||||
i % 2 === 0
|
||||
? sections[i].offsetWidth / 4
|
||||
: -sections[i].offsetWidth / 4,
|
||||
},
|
||||
{
|
||||
x: (i) =>
|
||||
i % 2 === 0
|
||||
? -sections[i].offsetWidth / 4
|
||||
: sections[i].offsetWidth / 4,
|
||||
scrollTrigger: {
|
||||
trigger: wrapper,
|
||||
start: "top bottom",
|
||||
end: "bottom top",
|
||||
scrub: true,
|
||||
// invalidateOnRefresh: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,46 @@
|
||||
<script>
|
||||
{
|
||||
const params = {
|
||||
duration: 0.8,
|
||||
ease: "expo.out",
|
||||
};
|
||||
|
||||
const handleSecondaryVisibility = (secondary) => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
gsap.to(secondary, {
|
||||
yPercent: 200,
|
||||
...params,
|
||||
});
|
||||
} else {
|
||||
gsap.to(secondary, {
|
||||
yPercent: 0,
|
||||
...params,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
{
|
||||
threshold: 0.02,
|
||||
rootMargin: "-10% 0px",
|
||||
}
|
||||
);
|
||||
|
||||
const contentElement = document.getElementById("content");
|
||||
if (contentElement) {
|
||||
observer.observe(contentElement);
|
||||
}
|
||||
};
|
||||
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const wrapper = document.querySelector("[data-module='nav']");
|
||||
if (!wrapper) return;
|
||||
const main = wrapper.children[0];
|
||||
const secondary = wrapper.children[1].children[0];
|
||||
|
||||
handleSecondaryVisibility(secondary);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,110 @@
|
||||
<script>
|
||||
const split = (text, type = "chars") => {
|
||||
text.setAttribute("aria-label", text.textContent);
|
||||
const splits = new SplitText(text, { type });
|
||||
splits[type].forEach((char) => char.setAttribute("aria-hidden", "true"));
|
||||
return splits[type];
|
||||
};
|
||||
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
|
||||
const section = document.querySelector("[data-animate='videogrow']");
|
||||
const video = section.querySelector("[data-videogrow='video']");
|
||||
const img = video.children[0];
|
||||
|
||||
const title = split(
|
||||
section.querySelector("[data-videogrow='title']"),
|
||||
"chars"
|
||||
);
|
||||
|
||||
const tl = gsap.timeline({
|
||||
scrollTrigger: {
|
||||
trigger: section,
|
||||
start: "top center",
|
||||
end: "bottom bottom+=100%",
|
||||
invalidateOnRefresh: true,
|
||||
scrub: 1,
|
||||
},
|
||||
});
|
||||
|
||||
gsap.set(
|
||||
title,
|
||||
{
|
||||
scale: 0,
|
||||
rotation: (i) => Math.random() * 360 - 180,
|
||||
})
|
||||
|
||||
tl.to(
|
||||
title,
|
||||
{
|
||||
scale: 1,
|
||||
duration: 0.2,
|
||||
rotation: 0,
|
||||
ease: "expo.out",
|
||||
stagger: {
|
||||
each: 0.05,
|
||||
from: "random",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
tl.fromTo(
|
||||
video,
|
||||
{
|
||||
clipPath: "inset(10% 50% 10% 50%)",
|
||||
yPercent: 100,
|
||||
},
|
||||
{
|
||||
ease: "power3",
|
||||
clipPath: "inset(0% 0% 0% 0%)",
|
||||
duration: 1,
|
||||
yPercent: 0,
|
||||
},
|
||||
".3"
|
||||
);
|
||||
|
||||
tl.fromTo(
|
||||
video,
|
||||
{
|
||||
scale: 0.5,
|
||||
// rotation: 180,
|
||||
},
|
||||
{
|
||||
ease: "back.inOut(.2)",
|
||||
scale: 1,
|
||||
duration: 0.8,
|
||||
// rotation: 0,
|
||||
},
|
||||
"<"
|
||||
);
|
||||
|
||||
tl.fromTo(
|
||||
img,
|
||||
{
|
||||
scale: 2.8,
|
||||
yPercent: 40,
|
||||
},
|
||||
{
|
||||
scale: 1.2,
|
||||
duration: 0.8,
|
||||
delay: 0.2,
|
||||
yPercent: 0,
|
||||
},
|
||||
"<"
|
||||
);
|
||||
|
||||
tl.to(video, {
|
||||
scale: 0.9,
|
||||
ease: "linear",
|
||||
});
|
||||
|
||||
tl.to(
|
||||
img,
|
||||
{
|
||||
scale: 1,
|
||||
ease: "linear",
|
||||
},
|
||||
"<"
|
||||
);
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,97 @@
|
||||
asdsada<nav class="hr-bottom">
|
||||
<button id="section1Btn">Section 1</button>
|
||||
<button id="section2Btn">Section 2</button>
|
||||
<button id="section3Btn">Section 3</button>
|
||||
</nav>
|
||||
|
||||
<h2 class="heading-scroll heading-l" id="section1">Section 1</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nibh quam, egestas eu eros molestie, eleifend viverra augue. Suspendisse potenti. Quisque commodo consectetur quam, non pretium orci viverra at. Maecenas eget iaculis nunc. </p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
|
||||
<h2 class="heading-scroll heading-l" id="section2">Section 2</h2>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
|
||||
<h2 class="heading-scroll heading-l" id="section3">Section 3</h2>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementes, nascetur ridiculus mus.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nibh quam, egestas eu eros molestie, eleifend viverra augue. Suspendisse potenti. Quisque commodo consectetur quam, non pretium orci viverra at. Maecenas eget iaculis nunc. </p>
|
||||
<p>Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<p>consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa.</p>
|
||||
<p>Praesent at pellentesque augue. Nunc sed ullamcorper risus. Duis tincidunt consectetur condimentum. Suspendisse pharetra purus urna, ac pretium mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
<p>Mi elementum et. Praesent dui nibh, ullamcorper in justo sed, volutpat cursus orci. Etiam vitae sodales massa. Cum sociis natoque penatibus et magnis dis parturient montes,</p>
|
||||
<style>
|
||||
/* Global styles come from external css */
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 20px;
|
||||
padding-top: 4rem;
|
||||
width: 100%;
|
||||
max-width: 80ch;
|
||||
}
|
||||
|
||||
nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
background: var(--color-just-black);
|
||||
margin: 0;
|
||||
padding: 1rem 10px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: var(--color-surface-white);
|
||||
font-size: 2rem;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: transparent;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
document.querySelectorAll("nav button").forEach((btn, index) => {
|
||||
btn.addEventListener("click", () => {
|
||||
gsap.to(window, {duration: 1, scrollTo:{y:"#section" + (index + 1), offsetY:120}});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,95 @@
|
||||
<script>
|
||||
{
|
||||
/** Section Selector */
|
||||
const createObserver = (section, cb) => {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && entry.intersectionRatio >= 0.1) {
|
||||
cb(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.2 // This means the callback will fire when at least 10% is visible
|
||||
});
|
||||
observer.observe(section);
|
||||
};
|
||||
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const { lenis } = event.detail;
|
||||
|
||||
const wrapper = document.querySelector("[data-animate='sectionselector']");
|
||||
const items = [...wrapper.children];
|
||||
const highlight = wrapper.querySelector("[data-selector='highlight']");
|
||||
let currentIndex = 0;
|
||||
|
||||
const sections = [...document.querySelectorAll("section")];
|
||||
|
||||
// Navigation height'ini hesapla (logo height'i ve üst/alt boşluklar için)
|
||||
const navWrapper = document.querySelector("[data-module='nav']");
|
||||
const navElement = navWrapper?.querySelector(".nav");
|
||||
const logoElement = navWrapper?.querySelector(".logo-banner-w");
|
||||
const getNavHeight = () => {
|
||||
if (navWrapper && navElement) {
|
||||
// Navigation element'inin toplam height'ini al (padding dahil)
|
||||
const navHeight = navElement.offsetHeight;
|
||||
|
||||
// Logo element'inin üstündeki boşluğu hesapla
|
||||
if (logoElement) {
|
||||
const logoRect = logoElement.getBoundingClientRect();
|
||||
const navRect = navElement.getBoundingClientRect();
|
||||
const topSpace = logoRect.top - navRect.top;
|
||||
|
||||
// Logo height'i + üstündeki boşluk + altındaki boşluk
|
||||
return navHeight + topSpace;
|
||||
}
|
||||
|
||||
return navHeight;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
sections.forEach((section, index) => {
|
||||
createObserver(section, () => {
|
||||
items[currentIndex].classList.remove("current");
|
||||
currentIndex = index;
|
||||
items[currentIndex].classList.add("current");
|
||||
moveHighlightTo(index);
|
||||
});
|
||||
});
|
||||
|
||||
let flipAnimation = null
|
||||
const moveHighlightTo = (index) => {
|
||||
const state = Flip.getState(highlight);
|
||||
items[index].appendChild(highlight);
|
||||
|
||||
if (flipAnimation) flipAnimation.kill()
|
||||
flipAnimation = Flip.from(state, {
|
||||
duration: 0.5,
|
||||
ease: "expo.out",
|
||||
});
|
||||
};
|
||||
|
||||
items.forEach((item, index) => {
|
||||
item.addEventListener("click", () => {
|
||||
const targetSection = document.getElementById(items[index].dataset.to);
|
||||
if (targetSection) {
|
||||
const navHeight = getNavHeight();
|
||||
lenis.scrollTo(targetSection, {
|
||||
offset: -navHeight
|
||||
});
|
||||
} else {
|
||||
lenis.scrollTo("#" + items[index].dataset.to);
|
||||
}
|
||||
});
|
||||
|
||||
item.addEventListener("mouseenter", () => {
|
||||
moveHighlightTo(index);
|
||||
});
|
||||
|
||||
item.addEventListener("mouseleave", () => {
|
||||
moveHighlightTo(currentIndex);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,380 @@
|
||||
<script>
|
||||
// https://codepen.io/GreenSock/pen/gOvvJee?editors=1010
|
||||
// https://gsap.com/docs/v3/HelperFunctions/helpers/seamlessLoop/
|
||||
|
||||
// https://codepen.io/GreenSock/pen/gOvvJee?editors=1010
|
||||
// https://gsap.com/docs/v3/HelperFunctions/helpers/seamlessLoop/
|
||||
|
||||
function horizontalLoop(items, config) {
|
||||
let timeline;
|
||||
items = gsap.utils.toArray(items);
|
||||
config = config || {};
|
||||
gsap.context(() => {
|
||||
// use a context so that if this is called from within another context or a gsap.matchMedia(), we can perform proper cleanup like the "resize" event handler on the window
|
||||
let onChange = config.onChange,
|
||||
lastIndex = 0,
|
||||
tl = gsap.timeline({
|
||||
repeat: config.repeat,
|
||||
onUpdate:
|
||||
onChange &&
|
||||
function () {
|
||||
let i = tl.closestIndex();
|
||||
if (lastIndex !== i) {
|
||||
lastIndex = i;
|
||||
onChange(items[i], i);
|
||||
}
|
||||
},
|
||||
paused: config.paused,
|
||||
defaults: { ease: "none" },
|
||||
onReverseComplete: () =>
|
||||
tl.totalTime(tl.rawTime() + tl.duration() * 100),
|
||||
}),
|
||||
length = items.length,
|
||||
startX = items[0].offsetLeft,
|
||||
times = [],
|
||||
widths = [],
|
||||
spaceBefore = [],
|
||||
xPercents = [],
|
||||
curIndex = 0,
|
||||
indexIsDirty = false,
|
||||
center = config.center,
|
||||
pixelsPerSecond = (config.speed || 1) * 100,
|
||||
snap =
|
||||
config.snap === false ? (v) => v : gsap.utils.snap(config.snap || 1), // some browsers shift by a pixel to accommodate flex layouts, so for example if width is 20% the first element's width might be 242px, and the next 243px, alternating back and forth. So we snap to 5 percentage points to make things look more natural
|
||||
timeOffset = 0,
|
||||
container =
|
||||
center === true
|
||||
? items[0].parentNode
|
||||
: gsap.utils.toArray(center)[0] || items[0].parentNode,
|
||||
totalWidth,
|
||||
getTotalWidth = () =>
|
||||
items[length - 1].offsetLeft +
|
||||
(xPercents[length - 1] / 100) * widths[length - 1] -
|
||||
startX +
|
||||
spaceBefore[0] +
|
||||
items[length - 1].offsetWidth *
|
||||
gsap.getProperty(items[length - 1], "scaleX") +
|
||||
(parseFloat(config.paddingRight) || 0),
|
||||
populateWidths = () => {
|
||||
let b1 = container.getBoundingClientRect(),
|
||||
b2;
|
||||
|
||||
// Reset all items to their natural position first
|
||||
gsap.set(items, {
|
||||
x: 0,
|
||||
xPercent: 0,
|
||||
clearProps: "transform",
|
||||
});
|
||||
|
||||
// Force a reflow
|
||||
items[0].offsetWidth;
|
||||
|
||||
// Get the container's new position after reset
|
||||
startX = items[0].offsetLeft;
|
||||
|
||||
items.forEach((el, i) => {
|
||||
// Get the natural width without any transforms
|
||||
widths[i] = el.offsetWidth;
|
||||
|
||||
// Calculate the space between items
|
||||
b2 = el.getBoundingClientRect();
|
||||
spaceBefore[i] = b2.left - (i ? b1.right : b1.left);
|
||||
b1 = b2;
|
||||
|
||||
// Reset xPercent to 0 for accurate calculations
|
||||
xPercents[i] = 0;
|
||||
});
|
||||
|
||||
// Set all items to their calculated positions
|
||||
gsap.set(items, {
|
||||
xPercent: (i) => xPercents[i],
|
||||
});
|
||||
|
||||
// Calculate total width after all items are positioned
|
||||
totalWidth = getTotalWidth();
|
||||
},
|
||||
timeWrap,
|
||||
populateOffsets = () => {
|
||||
timeOffset = center
|
||||
? (tl.duration() * (container.offsetWidth / 2)) / totalWidth
|
||||
: 0;
|
||||
center &&
|
||||
times.forEach((t, i) => {
|
||||
times[i] = timeWrap(
|
||||
tl.labels["label" + i] +
|
||||
(tl.duration() * widths[i]) / 2 / totalWidth -
|
||||
timeOffset
|
||||
);
|
||||
});
|
||||
},
|
||||
getClosest = (values, value, wrap) => {
|
||||
let i = values.length,
|
||||
closest = 1e10,
|
||||
index = 0,
|
||||
d;
|
||||
while (i--) {
|
||||
d = Math.abs(values[i] - value);
|
||||
if (d > wrap / 2) {
|
||||
d = wrap - d;
|
||||
}
|
||||
if (d < closest) {
|
||||
closest = d;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
},
|
||||
populateTimeline = () => {
|
||||
let i, item, curX, distanceToStart, distanceToLoop;
|
||||
tl.clear();
|
||||
for (i = 0; i < length; i++) {
|
||||
item = items[i];
|
||||
curX = (xPercents[i] / 100) * widths[i];
|
||||
distanceToStart = item.offsetLeft + curX - startX + spaceBefore[0];
|
||||
distanceToLoop =
|
||||
distanceToStart + widths[i] * gsap.getProperty(item, "scaleX");
|
||||
tl.to(
|
||||
item,
|
||||
{
|
||||
xPercent: snap(((curX - distanceToLoop) / widths[i]) * 100),
|
||||
duration: distanceToLoop / pixelsPerSecond,
|
||||
},
|
||||
0
|
||||
)
|
||||
.fromTo(
|
||||
item,
|
||||
{
|
||||
xPercent: snap(
|
||||
((curX - distanceToLoop + totalWidth) / widths[i]) * 100
|
||||
),
|
||||
},
|
||||
{
|
||||
xPercent: xPercents[i],
|
||||
duration:
|
||||
(curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond,
|
||||
immediateRender: false,
|
||||
},
|
||||
distanceToLoop / pixelsPerSecond
|
||||
)
|
||||
.add("label" + i, distanceToStart / pixelsPerSecond);
|
||||
times[i] = distanceToStart / pixelsPerSecond;
|
||||
}
|
||||
timeWrap = gsap.utils.wrap(0, tl.duration());
|
||||
},
|
||||
refresh = (deep) => {
|
||||
let progress = tl.progress();
|
||||
tl.progress(0, true);
|
||||
|
||||
// Reset only the x transforms while preserving other properties
|
||||
gsap.set(items, {
|
||||
x: 0,
|
||||
xPercent: 0,
|
||||
});
|
||||
|
||||
// Force a reflow
|
||||
items[0].offsetWidth;
|
||||
|
||||
populateWidths();
|
||||
deep && populateTimeline();
|
||||
populateOffsets();
|
||||
|
||||
if (deep && tl.draggable && tl.paused()) {
|
||||
tl.time(times[curIndex], true);
|
||||
} else {
|
||||
tl.progress(progress, true);
|
||||
}
|
||||
},
|
||||
onResize = () => {
|
||||
if (window.resizeTimeout) clearTimeout(window.resizeTimeout);
|
||||
window.resizeTimeout = setTimeout(() => {
|
||||
refresh(true);
|
||||
}, 100);
|
||||
},
|
||||
proxy;
|
||||
gsap.set(items, { x: 0 });
|
||||
populateWidths();
|
||||
populateTimeline();
|
||||
populateOffsets();
|
||||
window.addEventListener("resize", onResize);
|
||||
function toIndex(index, vars) {
|
||||
vars = vars || {};
|
||||
Math.abs(index - curIndex) > length / 2 &&
|
||||
(index += index > curIndex ? -length : length); // always go in the shortest direction
|
||||
let newIndex = gsap.utils.wrap(0, length, index),
|
||||
time = times[newIndex];
|
||||
if (time > tl.time() !== index > curIndex && index !== curIndex) {
|
||||
// if we're wrapping the timeline's playhead, make the proper adjustments
|
||||
time += tl.duration() * (index > curIndex ? 1 : -1);
|
||||
}
|
||||
if (time < 0 || time > tl.duration()) {
|
||||
vars.modifiers = { time: timeWrap };
|
||||
}
|
||||
curIndex = newIndex;
|
||||
vars.overwrite = true;
|
||||
gsap.killTweensOf(proxy);
|
||||
return vars.duration === 0
|
||||
? tl.time(timeWrap(time))
|
||||
: tl.tweenTo(time, vars);
|
||||
}
|
||||
tl.toIndex = (index, vars) => toIndex(index, vars);
|
||||
tl.closestIndex = (setCurrent) => {
|
||||
let index = getClosest(times, tl.time(), tl.duration());
|
||||
if (setCurrent) {
|
||||
curIndex = index;
|
||||
indexIsDirty = false;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
tl.current = () => (indexIsDirty ? tl.closestIndex(true) : curIndex);
|
||||
tl.next = (vars) => toIndex(tl.current() + 1, vars);
|
||||
tl.previous = (vars) => toIndex(tl.current() - 1, vars);
|
||||
tl.times = times;
|
||||
tl.progress(1, true).progress(0, true); // pre-render for performance
|
||||
if (config.reversed) {
|
||||
tl.vars.onReverseComplete();
|
||||
tl.reverse();
|
||||
}
|
||||
if (config.draggable && typeof Draggable === "function") {
|
||||
proxy = document.createElement("div");
|
||||
let wrap = gsap.utils.wrap(0, 1),
|
||||
ratio,
|
||||
startProgress,
|
||||
draggable,
|
||||
dragSnap,
|
||||
lastSnap,
|
||||
initChangeX,
|
||||
wasPlaying,
|
||||
align = () =>
|
||||
tl.progress(
|
||||
wrap(startProgress + (draggable.startX - draggable.x) * ratio)
|
||||
),
|
||||
syncIndex = () => tl.closestIndex(true);
|
||||
typeof InertiaPlugin === "undefined" &&
|
||||
console.warn(
|
||||
"InertiaPlugin required for momentum-based scrolling and snapping. https://greensock.com/club"
|
||||
);
|
||||
draggable = Draggable.create(proxy, {
|
||||
trigger: items[0].parentNode,
|
||||
type: "x",
|
||||
onPressInit() {
|
||||
let x = this.x;
|
||||
gsap.killTweensOf(tl);
|
||||
wasPlaying = !tl.paused();
|
||||
tl.pause();
|
||||
startProgress = tl.progress();
|
||||
refresh();
|
||||
ratio = 1 / totalWidth;
|
||||
initChangeX = startProgress / -ratio - x;
|
||||
gsap.set(proxy, { x: startProgress / -ratio });
|
||||
},
|
||||
onDrag: align,
|
||||
onThrowUpdate: align,
|
||||
overshootTolerance: 0,
|
||||
inertia: true,
|
||||
snap(value) {
|
||||
//note: if the user presses and releases in the middle of a throw, due to the sudden correction of proxy.x in the onPressInit(), the velocity could be very large, throwing off the snap. So sense that condition and adjust for it. We also need to set overshootTolerance to 0 to prevent the inertia from causing it to shoot past and come back
|
||||
if (Math.abs(startProgress / -ratio - this.x) < 10) {
|
||||
return lastSnap + initChangeX;
|
||||
}
|
||||
let time = -(value * ratio) * tl.duration(),
|
||||
wrappedTime = timeWrap(time),
|
||||
snapTime = times[getClosest(times, wrappedTime, tl.duration())],
|
||||
dif = snapTime - wrappedTime;
|
||||
Math.abs(dif) > tl.duration() / 2 &&
|
||||
(dif += dif < 0 ? tl.duration() : -tl.duration());
|
||||
lastSnap = (time + dif) / tl.duration() / -ratio;
|
||||
return lastSnap;
|
||||
},
|
||||
onRelease() {
|
||||
syncIndex();
|
||||
draggable.isThrowing && (indexIsDirty = true);
|
||||
},
|
||||
onThrowComplete: () => {
|
||||
syncIndex();
|
||||
wasPlaying && tl.play();
|
||||
},
|
||||
})[0];
|
||||
tl.draggable = draggable;
|
||||
}
|
||||
tl.closestIndex(true);
|
||||
lastIndex = curIndex;
|
||||
onChange && onChange(items[curIndex], curIndex);
|
||||
timeline = tl;
|
||||
return () => window.removeEventListener("resize", onResize); // cleanup
|
||||
});
|
||||
return timeline;
|
||||
}
|
||||
|
||||
/* -- Global Params */
|
||||
const sliderParams = {
|
||||
duration: 0.5,
|
||||
ease: "power2.out",
|
||||
};
|
||||
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const wrapper = document.querySelector("[data-animate='slider']");
|
||||
const slides = [...wrapper.querySelector("[data-slider='slides']").children];
|
||||
|
||||
/* -- Setup Slider UI */
|
||||
const progress = wrapper.querySelector("[data-slider='progress']");
|
||||
const next = wrapper.querySelector("[data-slider='next']");
|
||||
const prev = wrapper.querySelector("[data-slider='prev']");
|
||||
let currentIndex = 0;
|
||||
|
||||
const dots = [...wrapper.querySelector("[data-slider='dots']").children].map(
|
||||
(item, index) => {
|
||||
const btn = item.children[0];
|
||||
btn.addEventListener("click", () => {
|
||||
loop.toIndex(index, sliderParams);
|
||||
});
|
||||
|
||||
return btn;
|
||||
}
|
||||
);
|
||||
|
||||
/* -- Helper Functions */
|
||||
const updateCurrent = (index) => {
|
||||
// handle dots
|
||||
dots[currentIndex].classList.remove("current");
|
||||
dots[index].classList.add("current");
|
||||
slides[currentIndex].classList.remove("current");
|
||||
slides[index].classList.add("current");
|
||||
// handle slides
|
||||
// ...
|
||||
gsap.to(progress.children[0], {
|
||||
width: `${(index / (slides.length - 1)) * 100}%`,
|
||||
duration: 0.6,
|
||||
ease: "expo.out",
|
||||
});
|
||||
|
||||
// save the previous position
|
||||
currentIndex = index;
|
||||
};
|
||||
|
||||
/* -- Setup Slider */
|
||||
let loop;
|
||||
setTimeout(() => {
|
||||
loop = horizontalLoop(slides, {
|
||||
paused: true,
|
||||
draggable: true,
|
||||
// draggableOptions: {
|
||||
// dragResistance: 10,
|
||||
// resistance: 10,
|
||||
// },
|
||||
center: true,
|
||||
onChange: (element, index) => {
|
||||
updateCurrent(index);
|
||||
},
|
||||
});
|
||||
}, 500);
|
||||
// (*) THIS IS JUST TO CHECK PLEASE REMOVE
|
||||
|
||||
next.addEventListener("click", () => {
|
||||
loop.next(sliderParams);
|
||||
});
|
||||
|
||||
prev.addEventListener("click", () => {
|
||||
loop.previous(sliderParams);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,167 @@
|
||||
<script>
|
||||
{
|
||||
|
||||
/** Utility Functions */
|
||||
const split = (text, type = "chars") => {
|
||||
text.setAttribute("aria-label", text.textContent);
|
||||
const splits = new SplitText(text, { type });
|
||||
splits[type].forEach((char) => char.setAttribute("aria-hidden", "true"));
|
||||
return splits[type];
|
||||
};
|
||||
|
||||
const getParams = (item) => {
|
||||
const { duration, delay, stagger, ease, type } = item.dataset;
|
||||
const params = {
|
||||
duration: 1.2,
|
||||
delay: 0,
|
||||
type: "chars",
|
||||
};
|
||||
|
||||
if (duration) params.duration = parseFloat(duration);
|
||||
if (delay) params.delay = parseFloat(delay);
|
||||
if (type && (type === "chars" || type === "words" || type === "lines"))
|
||||
params.type = type;
|
||||
|
||||
return params;
|
||||
};
|
||||
|
||||
const baseAnimation = (item) => {
|
||||
const params = getParams(item);
|
||||
return {
|
||||
duration: params.duration,
|
||||
delay: params.delay,
|
||||
ease: "expo.out",
|
||||
// stagger each item so the letters come in one after the other
|
||||
stagger: {
|
||||
each: 0.04,
|
||||
from: "start",
|
||||
},
|
||||
scrollTrigger: {
|
||||
trigger: item,
|
||||
// use scrolltrigger to trigger on enter and reset on exit
|
||||
toggleActions: "play reset play reset",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/** (1) Split Reveal Animation */
|
||||
function createSplitRevealAnimation(item) {
|
||||
const params = getParams(item); // 1. get params from attributes
|
||||
const text = split(item, params.type); // 2. split the text
|
||||
item.style.overflow = "hidden"; // 3. set container to overflow
|
||||
|
||||
// 4. create the animation
|
||||
return gsap.fromTo(
|
||||
text,
|
||||
{ yPercent: 120 },
|
||||
{
|
||||
...baseAnimation(item),
|
||||
yPercent: 0,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createScrambledAnimation(item) {
|
||||
const text = item.textContent;
|
||||
const randomText = Array(text.length)
|
||||
.fill()
|
||||
.map(() => String.fromCharCode(Math.floor(Math.random() * (90 - 65) + 65)))
|
||||
.join("")
|
||||
.toLowerCase();
|
||||
|
||||
return gsap.fromTo(
|
||||
item.children[0],
|
||||
{
|
||||
scrambleText: randomText,
|
||||
},
|
||||
{
|
||||
...baseAnimation(item),
|
||||
scrambleText: text,
|
||||
chars: text,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createAlphaAnimation(item) {
|
||||
|
||||
const params = getParams(item); // 1. get params from attributes
|
||||
const text = split(item, "chars"); // 2. split the text
|
||||
|
||||
return gsap.fromTo(
|
||||
text,
|
||||
{ autoAlpha: 0 },
|
||||
{
|
||||
...baseAnimation(item),
|
||||
autoAlpha: 1,
|
||||
stagger: {
|
||||
each: 0.02,
|
||||
from: "random",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createSideAnimation(item) {
|
||||
const params = getParams(item);
|
||||
const outer = split(item, "chars");
|
||||
outer.forEach((char) => {
|
||||
char.style.overflow = "hidden";
|
||||
});
|
||||
const inner = split(item.children[0], "chars");
|
||||
|
||||
return gsap.fromTo(
|
||||
inner,
|
||||
{ x: 100 },
|
||||
{
|
||||
...baseAnimation(item),
|
||||
x: 0,
|
||||
stagger: {
|
||||
each: 0.02,
|
||||
from: "end",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createUpDownAnimation(item) {
|
||||
const params = getParams(item);
|
||||
const outer = split(item, "chars");
|
||||
outer.forEach((char) => {
|
||||
char.style.overflow = "hidden";
|
||||
});
|
||||
const inner = split(item.children[0], "chars");
|
||||
|
||||
return gsap.fromTo(
|
||||
inner,
|
||||
{
|
||||
yPercent: (i) => {
|
||||
return i % 2 === 0 ? 100 : -100;
|
||||
},
|
||||
},
|
||||
{
|
||||
...baseAnimation(item),
|
||||
yPercent: 0,
|
||||
stagger: {
|
||||
each: 0.02,
|
||||
from: "random",
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** Main Text Effect Wrapper */
|
||||
addEventListener("GSAPReady", (event) => {
|
||||
const texts = [...document.querySelectorAll('[data-animate="text"]')];
|
||||
|
||||
texts.forEach((item) => {
|
||||
if (item.dataset.type === "chars") createSplitRevealAnimation(item);
|
||||
else if (item.dataset.type === "words") createSplitRevealAnimation(item);
|
||||
else if (item.dataset.type === "scramble") createScrambledAnimation(item);
|
||||
else if (item.dataset.type === "alpha") createAlphaAnimation(item);
|
||||
else if (item.dataset.type === "side") createSideAnimation(item);
|
||||
else if (item.dataset.type === "updown") createUpDownAnimation(item);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -1,82 +1,10 @@
|
||||
@extends('layouts.gsap', ['header' => 'partials.header', 'footer' => 'partials.footer'])
|
||||
<?php $headerTemplate = 'Blog Header'; ?>
|
||||
@extends('layouts.site', ['header' => 'partials.header', 'footer' => 'partials.footer'])
|
||||
|
||||
@section('title', t('Neler Yapıyoruz?') ?: 'Neler Yapıyoruz?')
|
||||
|
||||
@push('styles')
|
||||
@include('templates.neler-yapariz.external-links')
|
||||
<style>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/css/main.css')) !!}
|
||||
</style>
|
||||
<style>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/css/additional.css')) !!}
|
||||
</style>
|
||||
@endpush
|
||||
@section('title', 'Anasayfa')
|
||||
|
||||
@section('content')
|
||||
@include('templates.neler-yapariz.navigation')
|
||||
|
||||
<div id="smooth-wrapper" data-start="hidden" class="scroll-wrapper">
|
||||
<main id="smooth-content" class="main">
|
||||
@include('templates.neler-yapariz.sections.hero')
|
||||
|
||||
@include('templates.neler-yapariz.sections.flip')
|
||||
@include('templates.neler-yapariz.sections.slider')
|
||||
@include('templates.neler-yapariz.sections.inertia')
|
||||
@include('templates.neler-yapariz.sections.text')
|
||||
@include('templates.neler-yapariz.sections.marquee')
|
||||
</div>
|
||||
|
||||
@include('templates.neler-yapariz.sections.footer')
|
||||
</main>
|
||||
</div>
|
||||
@include('templates.neler-yapariz.hero')
|
||||
|
||||
@include('templates.home.contact')
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
@include('templates.neler-yapariz.external-scripts')
|
||||
|
||||
{{-- Navigation Scripts --}}
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/nav.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/section-selector.js')) !!}
|
||||
</script>
|
||||
|
||||
{{-- Hero Script --}}
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/hero.js')) !!}
|
||||
</script>
|
||||
|
||||
{{-- Section Scripts --}}
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/flip.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/scrolltrigger.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/slider.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/inertia.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/text.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/marquee.js')) !!}
|
||||
</script>
|
||||
|
||||
{{-- Footer Scripts --}}
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/footerlogo.js')) !!}
|
||||
</script>
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/copybtn-buttons.js')) !!}
|
||||
</script>
|
||||
|
||||
{{-- Global Scripts --}}
|
||||
<script>
|
||||
{!! file_get_contents(resource_path('views/templates/neler-yapariz/js/global.js')) !!}
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
<section class="wrapper !bg-[#edf2fc]">
|
||||
<div class="container pt-10 pb-36 xl:pt-[4.5rem] lg:pt-[4.5rem] md:pt-[4.5rem] xl:pb-40 lg:pb-40 md:pb-40 !text-center">
|
||||
<div class="flex flex-wrap mx-[-15px]">
|
||||
<div class="md:w-8/12 lg:w-7/12 xl:w-6/12 xxl:w-5/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto !mb-12">
|
||||
<h1 class="!text-[calc(1.365rem_+_1.38vw)] font-bold !leading-[1.2] xl:!text-[2.4rem] !mb-3">{{ t('neler-yapariz.hero.title') }}</h1>
|
||||
<p class="lead !leading-[1.65] text-[0.9rem] font-medium lg:!px-7 xl:!px-7 xxl:!px-6">{{ t('neler-yapariz.hero.subtitle') }} <span class="relative z-[2] whitespace-nowrap after:content-[''] after:block after:absolute after:w-[102.5%] after:h-[30%] after:left-[-1.5%] after:z-[-1] after:transition-all after:duration-[0.2s] after:ease-in-out after:!mt-0 after:rounded-[5rem] after:bottom-[9%] motion-reduce:after:transition-none after:bg-[rgba(63,120,224,.12)]">{{ t('neler-yapariz.hero.highlight') }}</span> {{ t('neler-yapariz.hero.subtitle_end') }}</p>
|
||||
</div>
|
||||
<!-- /column -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</section>
|
||||
<section class="wrapper !bg-[#ffffff] angled upper-end !relative border-0 before:top-[-4rem] before:border-l-transparent before:border-r-[100vw] before:border-t-[4rem] before:border-[#fefefe] before:content-[''] before:block before:absolute before:z-0 before:!border-y-transparent before:border-0 before:border-solid before:right-0 after:top-[-4rem] after:border-l-transparent after:border-r-[100vw] after:border-t-[4rem] after:border-[#fefefe] after:content-[''] after:block after:absolute after:z-0 after:!border-y-transparent after:border-0 after:border-solid after:right-0">
|
||||
<div class="container !pb-[4.5rem] xl:!pb-24 lg:!pb-24 md:!pb-24">
|
||||
<div class="flex flex-wrap mx-[-15px] !mb-8">
|
||||
<div class="w-full flex-[0_0_auto] !px-[15px] max-w-full !mt-[-10rem]">
|
||||
<figure class="rounded-[0.4rem]"><img class="rounded-[0.4rem]" src="{{ asset('html/assets/img/photos/about5.jpg') }}" alt="{{ t('neler-yapariz.image_alt') }}"></figure>
|
||||
<div class="flex flex-wrap mx-[-15px]">
|
||||
<div class="xl:w-10/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto">
|
||||
<div class="card image-wrapper bg-full bg-image bg-overlay bg-overlay-400 !text-white !mt-[-1.25rem] xl:!mt-0 lg:!mt-0 xl:-translate-y-2/4 lg:-translate-y-2/4 bg-cover [background-size:100%] bg-[center_center] bg-no-repeat !bg-scroll !relative z-0 before:rounded-[0.4rem] before:bg-[rgba(30,34,40,.4)] before:content-[''] before:block before:absolute before:z-[1] before:w-full before:h-full before:left-0 before:top-0" data-image-src="{{ asset('html/assets/img/photos/bg3.jpg') }}" style="background-image: url('{{ asset('html/assets/img/photos/bg3.jpg') }}');">
|
||||
<div class="card-body p-[2.25rem] xl:!p-[2.5rem]">
|
||||
<div class="flex flex-wrap mx-[-15px] items-center counter-wrapper !mt-[-20px] !text-center">
|
||||
<div class="w-6/12 xl:w-3/12 lg:w-3/12 flex-[0_0_auto] !px-[15px] max-w-full !mt-[20px]">
|
||||
<h3 class="counter counter-lg !text-white xl:!text-[2.2rem] !text-[calc(1.345rem_+_1.14vw)] !tracking-[normal] !leading-none !mb-2" style="visibility: visible;">7518</h3>
|
||||
<p class="!text-[0.8rem] font-medium !mb-0 !text-white">{{ t('neler-yapariz.stats.completed_projects') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="w-6/12 xl:w-3/12 lg:w-3/12 flex-[0_0_auto] !px-[15px] max-w-full !mt-[20px]">
|
||||
<h3 class="counter counter-lg !text-white xl:!text-[2.2rem] !text-[calc(1.345rem_+_1.14vw)] !tracking-[normal] !leading-none !mb-2" style="visibility: visible;">3472</h3>
|
||||
<p class="!text-[0.8rem] font-medium !mb-0 !text-white">{{ t('neler-yapariz.stats.satisfied_customers') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="w-6/12 xl:w-3/12 lg:w-3/12 flex-[0_0_auto] !px-[15px] max-w-full !mt-[20px]">
|
||||
<h3 class="counter counter-lg !text-white xl:!text-[2.2rem] !text-[calc(1.345rem_+_1.14vw)] !tracking-[normal] !leading-none !mb-2" style="visibility: visible;">2184</h3>
|
||||
<p class="!text-[0.8rem] font-medium !mb-0 !text-white">{{ t('neler-yapariz.stats.expert_employees') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="w-6/12 xl:w-3/12 lg:w-3/12 flex-[0_0_auto] !px-[15px] max-w-full !mt-[20px]">
|
||||
<h3 class="counter counter-lg !text-white xl:!text-[2.2rem] !text-[calc(1.345rem_+_1.14vw)] !tracking-[normal] !leading-none !mb-2" style="visibility: visible;">4523</h3>
|
||||
<p class="!text-[0.8rem] font-medium !mb-0 !text-white">{{ t('neler-yapariz.stats.awards_won') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
</div>
|
||||
<!--/.row -->
|
||||
</div>
|
||||
<!--/.card-body -->
|
||||
</div>
|
||||
<!--/.card -->
|
||||
</div>
|
||||
<!-- /column -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /column -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
<div class="flex flex-wrap mx-[-15px] xl:mx-[-20px] lg:mx-[-20px] !mt-[25px] md:!mt-[4.5rem] lg:!mt-0 xl:!mt-0 !mb-20 items-center">
|
||||
<div class="xl:w-6/12 lg:w-6/12 w-full flex-[0_0_auto] px-[20px] !mt-[40px] max-w-full xl:!order-2 lg:!order-2">
|
||||
<div class="flex flex-wrap mx-[-15px] xl:mx-[-12.5px] lg:mx-[-12.5px] md:mx-[-12.5px] !mt-[-25px]">
|
||||
<div class="xl:w-4/12 lg:w-4/12 md:w-4/12 w-full flex-[0_0_auto] !px-[15px] max-w-full xl:!ml-[16.66666667%] lg:!ml-[16.66666667%] md:!ml-[16.66666667%] !self-end !mt-[25px]">
|
||||
<figure class="rounded-[0.4rem]"><img class="rounded-[0.4rem]" src="{{ asset('html/assets/img/photos/g1.jpg') }}" alt="{{ t('neler-yapariz.gallery.image_1_alt') }}"></figure>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] px-[12.5px] max-w-full !self-end !mt-[25px]">
|
||||
<figure class="rounded-[0.4rem]"><img class="rounded-[0.4rem]" src="{{ asset('html/assets/img/photos/g2.jpg') }}" alt="{{ t('neler-yapariz.gallery.image_2_alt') }}"></figure>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] px-[12.5px] max-w-full xl:!ml-[8.33333333%] lg:!ml-[8.33333333%] md:!ml-[8.33333333%] !mt-[25px]">
|
||||
<figure class="rounded-[0.4rem]"><img class="rounded-[0.4rem]" src="{{ asset('html/assets/img/photos/g3.jpg') }}" alt="{{ t('neler-yapariz.gallery.image_3_alt') }}"></figure>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="xl:w-4/12 lg:w-4/12 md:w-4/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !self-start !mt-[25px]">
|
||||
<figure class="rounded-[0.4rem]"><img class="rounded-[0.4rem]" src="{{ asset('html/assets/img/photos/g4.jpg') }}" alt="{{ t('neler-yapariz.gallery.image_4_alt') }}"></figure>
|
||||
</div>
|
||||
<!--/column -->
|
||||
</div>
|
||||
<!--/.row -->
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="xl:w-6/12 lg:w-6/12 w-full flex-[0_0_auto] xl:!px-[20px] lg:!px-[20px] !px-[15px] !mt-[40px] max-w-full">
|
||||
<h2 class="!text-[calc(1.305rem_+_0.66vw)] font-bold xl:!text-[1.8rem] !leading-[1.3] !mb-3">{{ t('neler-yapariz.what_we_do.title') }}</h2>
|
||||
<p class="lead !mb-8 xxl:!pr-2 !text-[1.05rem] !leading-[1.6]">{{ t('neler-yapariz.what_we_do.description') }} <span class="relative z-[2] whitespace-nowrap after:content-[''] after:block after:absolute after:w-[102.5%] after:h-[30%] after:left-[-1.5%] after:z-[-1] after:transition-all after:duration-[0.2s] after:ease-in-out after:!mt-0 after:rounded-[5rem] after:bottom-[9%] motion-reduce:after:transition-none after:bg-[rgba(63,120,224,.12)]">{{ t('neler-yapariz.what_we_do.highlight') }}</span> {{ t('neler-yapariz.what_we_do.description_end') }}</p>
|
||||
<div class="flex flex-wrap mx-[-15px] xl:mx-[-25px] !mt-[-30px]">
|
||||
<div class="md:w-6/12 lg:w-full xl:w-6/12 w-full flex-[0_0_auto] xl:!px-[25px] !px-[15px] max-w-full !mt-[30px]">
|
||||
<div class="flex flex-row">
|
||||
<div>
|
||||
<div class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mr-5 xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none p-0 !rounded-[100%]"> <i class="!text-[calc(1.255rem_+_0.06vw)] before:content-['\ec50'] uil uil-phone-volume"></i> </div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.services.support_24_7.title') }}</h4>
|
||||
<p class="!mb-0">{{ t('neler-yapariz.services.support_24_7.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="md:w-6/12 lg:w-full xl:w-6/12 w-full flex-[0_0_auto] xl:!px-[25px] !px-[15px] max-w-full !mt-[30px]">
|
||||
<div class="flex flex-row">
|
||||
<div>
|
||||
<div class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mr-5 xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none p-0 !rounded-[100%]"> <i class="!text-[calc(1.255rem_+_0.06vw)] before:content-['\ecb3'] uil uil-shield-exclamation"></i> </div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.services.secure_payments.title') }}</h4>
|
||||
<p class="!mb-0">{{ t('neler-yapariz.services.secure_payments.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="md:w-6/12 lg:w-full xl:w-6/12 w-full flex-[0_0_auto] xl:!px-[25px] !px-[15px] max-w-full !mt-[30px]">
|
||||
<div class="flex flex-row">
|
||||
<div>
|
||||
<div class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mr-5 xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none p-0 !rounded-[100%]"> <i class="!text-[calc(1.255rem_+_0.06vw)] before:content-['\ebb2'] uil uil-laptop-cloud"></i> </div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.services.daily_updates.title') }}</h4>
|
||||
<p class="!mb-0">{{ t('neler-yapariz.services.daily_updates.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="md:w-6/12 lg:w-full xl:w-6/12 w-full flex-[0_0_auto] xl:!px-[25px] !px-[15px] max-w-full !mt-[30px]">
|
||||
<div class="flex flex-row">
|
||||
<div>
|
||||
<div class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mr-5 xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none p-0 !rounded-[100%]"> <i class="!text-[calc(1.255rem_+_0.06vw)] before:content-['\e9d3'] uil uil-chart-line"></i> </div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.services.market_research.title') }}</h4>
|
||||
<p class="!mb-0">{{ t('neler-yapariz.services.market_research.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/column -->
|
||||
</div>
|
||||
<!--/.row -->
|
||||
</div>
|
||||
<!--/column -->
|
||||
</div>
|
||||
<!--/.row -->
|
||||
<h2 class="!text-[calc(1.305rem_+_0.66vw)] font-bold xl:!text-[1.8rem] !leading-[1.3] !mb-3">{{ t('neler-yapariz.how_we_do_it.title') }}</h2>
|
||||
<p class="lead !mb-8 !text-[1.05rem] !leading-[1.6]">{{ t('neler-yapariz.how_we_do_it.description') }} <span class="relative z-[2] whitespace-nowrap after:content-[''] after:block after:absolute after:w-[102.5%] after:h-[30%] after:left-[-1.5%] after:z-[-1] after:transition-all after:duration-[0.2s] after:ease-in-out after:!mt-0 after:rounded-[5rem] after:bottom-[9%] motion-reduce:after:transition-none after:bg-[rgba(63,120,224,.12)]">{{ t('neler-yapariz.how_we_do_it.highlight') }}</span> {{ t('neler-yapariz.how_we_do_it.description_end') }}</p>
|
||||
<div class="flex flex-wrap mx-[-15px] xl:mx-[-35px] lg:mx-[-20px] !mt-[-30px] process-wrapper line">
|
||||
<div class="md:w-6/12 lg:w-3/12 xl:w-3/12 w-full flex-[0_0_auto] !px-[15px] xl:!px-[35px] lg:!px-[20px] !mt-[30px] max-w-full !relative after:w-full after:absolute after:content-[''] after:h-px after:z-[1] after:border-t-[rgba(164,174,198,0.2)] after:border-t after:border-solid after:left-[3rem] after:top-6 after:bg-inherit max-lg:after:!hidden"> <span class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mb-4 !relative z-[2] xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none !p-0 !rounded-[100%]"><span class="number">01</span></span>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.process.step_1.title') }}</h4>
|
||||
<p>{{ t('neler-yapariz.process.step_1.description') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="md:w-6/12 lg:w-3/12 xl:w-3/12 w-full flex-[0_0_auto] !px-[15px] xl:!px-[35px] lg:!px-[20px] !mt-[30px] max-w-full !relative after:w-full after:absolute after:content-[''] after:h-px after:z-[1] after:border-t-[rgba(164,174,198,0.2)] after:border-t after:border-solid after:left-[3rem] after:top-6 after:bg-inherit max-lg:after:!hidden"> <span class="icon btn btn-circle btn-lg btn-primary !text-white !bg-[#3f78e0] border-[#3f78e0] hover:text-white hover:bg-[#3f78e0] hover:!border-[#3f78e0] active:text-white active:bg-[#3f78e0] active:border-[#3f78e0] disabled:text-white disabled:bg-[#3f78e0] disabled:border-[#3f78e0] pointer-events-none !mb-4 !relative z-[2] xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none p-0 !rounded-[100%]"><span class="number">02</span></span>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.process.step_2.title') }}</h4>
|
||||
<p>{{ t('neler-yapariz.process.step_2.description') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="md:w-6/12 lg:w-3/12 xl:w-3/12 w-full flex-[0_0_auto] !px-[15px] xl:!px-[35px] lg:!px-[20px] !mt-[30px] max-w-full !relative after:w-full after:absolute after:content-[''] after:h-px after:z-[1] after:border-t-[rgba(164,174,198,0.2)] after:border-t after:border-solid after:left-[3rem] after:top-6 after:bg-inherit max-lg:after:!hidden"> <span class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mb-4 !relative z-[2] xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none !p-0 !rounded-[100%]"><span class="number">03</span></span>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.process.step_3.title') }}</h4>
|
||||
<p>{{ t('neler-yapariz.process.step_3.description') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
<div class="md:w-6/12 lg:w-3/12 xl:w-3/12 w-full flex-[0_0_auto] !px-[15px] xl:!px-[35px] lg:!px-[20px] !mt-[30px] max-w-full"> <span class="icon btn btn-circle btn-lg btn-soft-primary pointer-events-none !mb-4 !relative z-[2] xl:!text-[1.3rem] w-12 h-12 !text-[calc(1.255rem_+_0.06vw)] inline-flex items-center justify-center leading-none !p-0 !rounded-[100%]"><span class="number">04</span></span>
|
||||
<h4 class="!mb-1">{{ t('neler-yapariz.process.step_4.title') }}</h4>
|
||||
<p>{{ t('neler-yapariz.process.step_4.description') }}</p>
|
||||
</div>
|
||||
<!--/column -->
|
||||
</div>
|
||||
<!--/.row -->
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</section>
|
||||
Reference in New Issue
Block a user