Skip to content

Commit 3b90efd

Browse files
committed
All sorts of tweaks I forgot to commit, but mainly colour theming.
1 parent f39a9e2 commit 3b90efd

4 files changed

Lines changed: 253 additions & 70 deletions

File tree

images/landing/elephpant.png

98.1 KB
Loading

js/landing.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
function initInfiniteScroll(parentContainer, speed = 50) {
2+
if (!parentContainer) return null;
3+
4+
// 1. Extract the fixed width from the data-width attribute
5+
const dataWidth = parentContainer.dataset.width;
6+
if (!dataWidth) {
7+
console.error("InfiniteScroll Error: Missing 'data-width' attribute on the container.");
8+
return null;
9+
}
10+
11+
const widthNum = parseInt(dataWidth, 10);
12+
const widthStr = `${widthNum}px`;
13+
14+
// 2. Gather the existing child elements currently inside the parent
15+
const elements = Array.from(parentContainer.children);
16+
if (elements.length === 0) return null;
17+
18+
// 3. Prepare the parent container styling
19+
parentContainer.style.overflow = 'hidden';
20+
parentContainer.style.position = 'relative';
21+
parentContainer.style.width = '100%';
22+
23+
// 4. Create the scrolling track
24+
const track = document.createElement('div');
25+
track.style.display = 'flex';
26+
track.style.width = 'max-content';
27+
track.style.willChange = 'transform';
28+
29+
// 5. Apply widths and move existing elements into the track
30+
elements.forEach(el => {
31+
el.style.width = widthStr;
32+
el.style.flexShrink = '0';
33+
track.appendChild(el); // Automatically removes it from parentContainer and places it in track
34+
});
35+
36+
// 6. Append the track to the parent container
37+
parentContainer.appendChild(track);
38+
39+
// 7. Clone elements to ensure a seamless loop with no blank gaps
40+
const parentWidth = parentContainer.offsetWidth || window.innerWidth;
41+
const originalTotalWidth = elements.length * widthNum;
42+
43+
let currentTrackWidth = originalTotalWidth;
44+
while (currentTrackWidth < parentWidth + originalTotalWidth) {
45+
elements.forEach(el => {
46+
const clone = el.cloneNode(true);
47+
clone.style.width = widthStr;
48+
clone.style.flexShrink = '0';
49+
track.appendChild(clone);
50+
});
51+
currentTrackWidth += originalTotalWidth;
52+
}
53+
54+
// 8. Generate a unique CSS keyframe animation dynamically
55+
const animationName = `infiniteScroll_${Math.random().toString(36).substr(2, 9)}`;
56+
const styleNode = document.createElement('style');
57+
styleNode.textContent = `
58+
@keyframes ${animationName} {
59+
0% { transform: translateX(0); }
60+
100% { transform: translateX(-${originalTotalWidth}px); }
61+
}
62+
`;
63+
document.head.appendChild(styleNode);
64+
65+
// 9. Apply the animation (speed is pixels per second)
66+
const duration = originalTotalWidth / speed;
67+
track.style.animation = `${animationName} ${duration}s linear infinite`;
68+
69+
// 10. Return playback and cleanup controls
70+
return {
71+
pause: () => track.style.animationPlayState = 'paused',
72+
play: () => track.style.animationPlayState = 'running',
73+
destroy: () => {
74+
// Puts original elements back and cleans up the DOM
75+
elements.forEach(el => parentContainer.appendChild(el));
76+
track.remove();
77+
styleNode.remove();
78+
}
79+
};
80+
}

landing.php

Lines changed: 78 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -236,70 +236,75 @@ function drawBranchInfo(array $release): void
236236
);
237237
}
238238

239+
$foundationSponsors = [
240+
['name' => 'JetBrains', 'icon' => 'https://images.opencollective.com/jetbrains/fe76f99/logo.png'],
241+
['name' => 'Private Packagist', 'icon' => 'https://images.opencollective.com/packagist/2ac48ff/logo.png'],
242+
['name' => 'Cybozu', 'icon' => 'https://images.opencollective.com/cybozu/933e46d/logo.png'],
243+
['name' => 'Aternos GmbH', 'icon' => 'https://images.opencollective.com/aternos/5436b31/logo.png'],
244+
['name' => 'Mercari Inc.', 'icon' => 'https://images.opencollective.com/mercari/454ef50/logo.png'],
245+
['name' => 'pixiv Inc.', 'icon' => 'https://images.opencollective.com/user-ecfec7e5/2f4c2c4/logo.png'],
246+
['name' => 'SPY', 'icon' => 'https://images.opencollective.com/spy/261d722/logo.png'],
247+
['name' => 'Symfony Corp', 'icon' => 'https://images.opencollective.com/symfony-sas/b1f53fd/logo.png'],
248+
['name' => 'shopware AG', 'icon' => 'https://images.opencollective.com/stefan-hamann/2865d41/logo.png'],
249+
['name' => 'OP.GG', 'icon' => 'https://images.opencollective.com/opgg/7e44af2/logo.png'],
250+
['name' => 'Passbolt', 'icon' => 'https://images.opencollective.com/passbolt/2468aab/logo.png'],
251+
['name' => 'Spryker', 'icon' => 'https://images.opencollective.com/spryker/a634346/logo.png'],
252+
['name' => 'Digital Scholar', 'icon' => 'https://images.opencollective.com/digital-scholar/logo.png'],
253+
['name' => 'Cambium Learning, Inc.', 'icon' => 'https://images.opencollective.com/cambium-learning-inc/30c5f1c/logo.png'],
254+
['name' => 'Craft CMS', 'icon' => 'https://images.opencollective.com/craftcms/1fd28bf/logo.png'],
255+
['name' => 'GoDaddy.com', 'icon' => 'https://images.opencollective.com/godaddy/c37e587/logo.png'],
256+
['name' => 'Laravel', 'icon' => 'https://images.opencollective.com/laravel/4ad04b8/logo.png'],
257+
['name' => 'Livesport s.r.o.', 'icon' => 'https://images.opencollective.com/livesport-s-r-o/be081c5/logo.png'],
258+
['name' => 'Aligent Consulting', 'icon' => 'https://images.opencollective.com/aligent-consulting/ee7abd9/logo.png'],
259+
['name' => 'Moodle', 'icon' => 'https://images.opencollective.com/moodle/141a57d/logo.png'],
260+
];
261+
239262

240263
ob_start();
241264
?>
265+
<div class="landing landing-dark">
242266
<link rel="stylesheet" href="/styles/landing.css" type="text/css">
243-
<div class="landing-section ">
244-
<div class="landing-hdr">
245-
<div style="display: flex; flex-direction: column; gap: 1em; text-align: center; justify-content: center; background: #22222277; border-radius: 1em; padding: 1em">
246-
<img class="hero__logo" src="/images/logos/php-logo-white.svg" alt="php" width="240" height="120" style="margin-left: auto; margin-right: auto;">
247-
<p class="landing-hdr-tagline">Powering Solo Developers, Teams, and Global Enterprise</p>
248-
</div>
249-
<div>
250-
<div class="landing-hdr-block">
251-
<div class="landing-hdr-title">Fast &amp; Modern</div>
252-
<div class="landing-hdr-content">PHP provides blistering fast performance and a modern developer-focused experience.</div>
253-
</div>
254267

255-
<div class="landing-hdr-block">
256-
<div class="landing-hdr-title">A Massive Ecosystem</div>
257-
<div class="landing-hdr-content">Leverage over 300,000 existing open source packages for your projects, along with powerful tooling.</div>
268+
<div class="landing-eco-full-container" style="border: 0">
269+
<div class="landing-hdr-outer landing-section ">
270+
<div class="landing-hdr">
271+
<div style="position: relative; display: flex; flex-direction: column; gap: 1em; text-align: center; justify-content: center; padding: 1em">
272+
<img class="hero__logo" src="/images/logos/php-logo-white.svg" alt="php" width="240" height="120" style="z-index: 1; margin-left: auto; margin-right: auto;">
273+
<p class="landing-hdr-tagline" style="z-index: 1">
274+
Powering Solo Developers, Teams, and Global Enterprise
275+
</p>
276+
<img style="position: absolute; object-position: center; width: 100%; height: 100%; object-fit: contain; opacity: 0.2" src="/images/landing/elephpant.png" alt="PHP Elephant logo" />
258277
</div>
278+
<div>
279+
<div class="landing-hdr-block">
280+
<div class="landing-hdr-title">Fast &amp; Modern</div>
281+
<div class="landing-hdr-content">PHP provides blistering fast performance and a modern developer-focused experience.</div>
282+
</div>
259283

260-
<div class="landing-hdr-block">
261-
<div class="landing-hdr-title">An Established Community</div>
262-
<div class="landing-hdr-content">Millions of developers and businesses already use PHP to achieve their goals every day.</div>
284+
<div class="landing-hdr-block">
285+
<div class="landing-hdr-title">A Massive Ecosystem</div>
286+
<div class="landing-hdr-content">Leverage over 300,000 existing open source packages for your projects, along with powerful tooling.</div>
287+
</div>
288+
289+
<div class="landing-hdr-block">
290+
<div class="landing-hdr-title">An Established Community</div>
291+
<div class="landing-hdr-content">Millions of developers and businesses already use PHP to achieve their goals every day.</div>
292+
</div>
263293
</div>
264294
</div>
265-
</div>
266-
</div>
267-
268-
<div style="background: #202127; position: relative" >
269-
<?php foreach ($heroCards as $heroCard) { ?>
270-
<div class="hero-cards-bg" id="<?= safe($heroCard->id . '-cover') ?>"></div>
271-
<?php } ?>
272295

273-
<div class="landing-section" style="position: relative; z-index: 1">
274-
<div role="list" class="vgrid"><?= buildNavCards($heroCards) ?></div>
296+
<div class="landing-hero-cards-container" >
297+
<div style="position: relative; z-index: 1">
298+
<div role="list" class="vgrid"><?= buildNavCards($heroCards, ['cn_card' => 'landing-cc-card landing-cc-card-alt']) ?></div>
299+
</div>
300+
</div>
275301
</div>
276302
</div>
277303

278-
<script type="text/javascript">
279-
(() => {
280-
let heroIds = <?= json_encode(array_map(fn(NavCardItem $card) => $card->id, $heroCards), flags: JSON_HEX_QUOT | JSON_HEX_QUOT) ?>;
281-
heroIds.forEach(heroId => {
282-
const cover = document.querySelector('#' + heroId + '-cover');
283-
if (!cover) console.error('Unable to find cover ' + heroId);
284-
285-
const card = document.querySelector('#' + heroId);
286-
if (!card) console.error('Unable to find card ' + heroId);
287-
288-
card.addEventListener('mouseenter', () => {
289-
cover.style.opacity = 1;
290-
});
291-
292-
card.addEventListener('mouseleave', () => {
293-
cover.style.opacity = 0;
294-
});
295-
});
296-
})();
297-
</script>
298-
299304
<div class="landing-section">
300305
<div id="releases" >
301306
<div class="landing-lrv">
302-
<svg style="position: absolute; inset: 0" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" class="hero-bg">
307+
<svg style="position: absolute; inset: 0; opacity: 0.5" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" class="hero-bg">
303308
<defs>
304309
<radialGradient id="Gradient1" cx="50%" cy="50%" fx="0.441602%" fy="50%" r=".5"><animate attributeName="fx" dur="34s" values="0%;3%;0%" repeatCount="indefinite"></animate><stop offset="0%" stop-color="rgba(210, 203, 255, 1)"></stop><stop offset="100%" stop-color="rgba(51, 63, 124, 0)"></stop></radialGradient>
305310
<radialGradient id="Gradient2" cx="50%" cy="50%" fx="2.68147%" fy="50%" r=".5"><animate attributeName="fx" dur="23.5s" values="0%;3%;0%" repeatCount="indefinite"></animate><stop offset="0%" stop-color="rgba(133, 109, 255, 1)"></stop><stop offset="100%" stop-color="rgba(51, 63, 124, 0)"></stop></radialGradient>
@@ -373,9 +378,9 @@ function drawBranchInfo(array $release): void
373378
</div>
374379
</div>
375380

376-
<div style="background: #3c4053; border-top: 5px solid #333333">
381+
<div class="landing-eco-full-container">
377382
<div class="landing-section">
378-
<div class="landing-eco-banner">
383+
<div id="php-foundation" class="landing-eco-banner">
379384
<img alt="PHP Foundation Logo" style="width: 160px; height: 160px; border-radius: 0.5em" src="/images/logos/php-foundation.svg" />
380385
<div>
381386
<div class="landing-eco-text">
@@ -392,31 +397,48 @@ function drawBranchInfo(array $release): void
392397
<a class="button-primary" target="_blank" href="https://github.com/sponsors/ThePHPF">Donate Via GitHub</a>
393398
</div>
394399
</div>
400+
<?php if (($_GET['show_sponsors'] ?? '1') === '1') { ?>
401+
<div>
402+
<div style="margin-top: 2em; margin-bottom: 0.5em; text-align: center; font-size: 90%">The PHP Foundation is grateful for our many sponsors, including:</div>
403+
<div id="foundation-sponsor-carousel" data-width="100" style="opacity: 0.7">
404+
<?php foreach ($foundationSponsors as $sponsor) { ?>
405+
<img src="<?= safe($sponsor['icon']) ?>" alt="<?= safe($sponsor['name'])?>" style="background: white; border-radius: 1em; padding: 10px; margin: 10px; width: 100px; height: 100px; filter: grayscale(60%)"/>
406+
<?php } ?>
407+
</div>
408+
409+
<script type="text/javascript" src="js/landing.js" ></script>
410+
<script type="text/javascript">
411+
initInfiniteScroll(document.querySelector('#foundation-sponsor-carousel'), 30);
412+
</script>
413+
</div>
414+
<?php } ?>
395415
</div>
396416
</div>
397417

398418

399-
<div style="background: #202127; background-image: url('/images/bg-texture-00.svg')">
419+
<div >
400420
<div id="community" class="landing-section">
401421
<div style="display: flex; gap: 1.5em; flex-direction: column">
402422
<div class="landing-section-header" role="heading">Community</div>
403423
<div>
404-
<div role="list" class="vgrid" id="community-cards"><?= buildNavCards($communityCards); ?></div>
424+
<div role="list" class="vgrid" id="community-cards"><?= buildNavCards($communityCards, ['cn_card' => 'landing-cc-card landing-cc-card-grey']); ?></div>
405425
</div>
406426
<div></div>
407427

408428
<div class="landing-section-header" role="heading">Events &amp; Conferences</div>
409429
<div>
410-
<div role="list" class="vgrid" id="conference-cards"><?= buildNavCards($eventCards) ?></div>
430+
<div role="list" class="vgrid" id="conference-cards"><?= buildNavCards($eventCards, ['cn_card' => 'landing-cc-card landing-cc-card-grey']) ?></div>
411431
</div>
412432
</div>
413433
</div>
414434
</div>
415435

416-
<div style="background: #3c4053; border-bottom: 5px solid #333333">
436+
<div class="landing-eco-full-container">
417437
<div class="landing-section">
418438
<div class="landing-eco-banner">
419-
<img alt="PHP Foundation Logo" style="width: 160px; height: 160px; border-radius: 0.5em" src="/images/logos/composer.png" />
439+
<div style="flex: 0 0 fit-content">
440+
<img alt="Composer Logo" style="background: white; object-fit: contain; padding: 0.5em; width: 100%; height: 160px; border-radius: 0.5em" src="/images/logos/composer.png" />
441+
</div>
420442
<div>
421443
<div class="landing-eco-text">
422444
PHP has one of the largest collections of open-source libraries in the world.
@@ -450,7 +472,7 @@ function drawBranchInfo(array $release): void
450472
shuffleDOMChildrenWithLimit(document.querySelector('#conference-cards'), 6);
451473
});
452474
</script>
453-
475+
</div>
454476
<?php
455477
$header = ob_get_clean();
456478

0 commit comments

Comments
 (0)