diff --git a/website/src/assets/images/infographs/Architecture.svg b/website/src/assets/images/infographs/Architecture.svg index cdb0740e19077..d92cbcfec2c39 100644 --- a/website/src/assets/images/infographs/Architecture.svg +++ b/website/src/assets/images/infographs/Architecture.svg @@ -1,245 +1,151 @@ - - - - - - - - - - - Apache APISIX - - - - - - - - - Rate limit - - - - - - - - - - Auth - - - - - - - - - - Security - - - - - - - - - - Logging - - - - - - - - - - Custom plugin - - - - - - - - - - ... ... - - - - - - - - - - - Client/Service - - - - - - - - - - - - - - - - - Apache Skywalking - - - - - - - - - - Grafana... - - - - - - - - - - Prometheus - - - - - - - - - - - - - PARTNER - - + + + + + + + + + + + + Apache APISIX + + + + Rate limit + + + + Auth + + + + Security + + + + + Logging + + + + + + Custom plugin + + + + + + ... ... + + + + + + Client/Service + + + + + + + + + + Apache Skywalking - - - - - - - PRIVATE - + + + + Grafana... - - - - - - - PUBLIC - + + + + Prometheus - - - - + + + + + + + PARTNER + + + + + + PRIVATE + + + + + + PUBLIC + + + + + + + + + + + etcd - - - - - - - - - - - - - etcd - - - - - - - - - - etcd - - - - - - - - - - etcd - - + + + + etcd - - - - - - - - Control Plane (CP) - + + + + etcd - - - - - - - - - - - - - - Manager API - - - - Dashboard - + + + + + + + - + Control Plane (CP) + + + + + - - - - + + + + Manager API - - - - - - - - Data Plane (DP) - + Dashboard + + + + + + + + + + + + + + Data Plane (DP) + diff --git a/website/src/assets/images/pluginised.png b/website/src/assets/images/pluginised.png index 1aa732009b8b4..7520b9d5ec94a 100644 Binary files a/website/src/assets/images/pluginised.png and b/website/src/assets/images/pluginised.png differ diff --git a/website/src/css/customTheme.css b/website/src/css/customTheme.css index c18d864b1c890..79e8e942305f7 100644 --- a/website/src/css/customTheme.css +++ b/website/src/css/customTheme.css @@ -52,8 +52,47 @@ html[data-theme="dark"] { --color-downloads-dropdown-items: #4c4e50; } -body { - font-family: "Inter", sans-serif; +@font-face { + font-family: 'MaisonNeue-Medium'; + src: local('MaisonNeue-Medium'), url(../fonts/MaisonNeue-Medium.otf) format('opentype'); + font-display: swap; +} +@font-face { + font-family: 'MaisonNeue-Bold'; + src: local('MaisonNeue-Bold'), url(../fonts/MaisonNeue-Bold.otf) format('opentype'); + font-display: swap; +} +@font-face { + font-family: 'MaisonNeue-Light'; + src: local('MaisonNeue-Light'), url(../fonts/MaisonNeue-Light.otf) format('opentype'); + font-display: swap; +} +@font-face { + font-family: 'MaisonNeue-Demi'; + src: local('MaisonNeue-Demi'), url(../fonts/MaisonNeue-Demi.otf) format('opentype'); + font-display: swap; +} +@font-face { + font-family: 'MaisonNeue-ExtraBold'; + src: local('MaisonNeue-ExtraBold'), url(../fonts/MaisonNeue-ExtraBold.otf) format('opentype'); + font-display: swap; +} + +::-webkit-scrollbar { + width: 5px; +} +::-webkit-scrollbar-track { + background: #f1f1f1; +} +::-webkit-scrollbar-thumb { + background: #888; +} +::-webkit-scrollbar-thumb:hover { + background: #555; +} + +body, h1, h2, h3 { + font-family: MaisonNeue-Medium, sans-serif; } div.inner { @@ -100,76 +139,9 @@ header h2 { height: 30px; } -/* home splash */ -.home-splash { - margin-top: 0px; - margin-bottom: -50px; -} -@media only screen and (min-device-width: 360px) and (max-device-width: 736px) { - .home-splash { - margin-top: -20px; - margin-bottom: -50px; - } -} - -.home-splash .title { - font-size: 5rem; - font-weight: 800; - color: var(--color-title); -} -@media only screen and (min-device-width: 376px) and (max-device-width: 736px) { - .home-splash .title { - font-size: 3.52rem; - } -} - -@media only screen and (min-device-width: 320px) and (max-width: 375px) { - .home-splash .title { - font-size: 3rem; - } -} - -.home-splash .title.slogan .feature-word { - color: var(--ifm-color-primary); -} - -.home-splash .title.slogan .feature-word span { - display: inline-block; -} - -.home-splash .subtitle { - color: var(--color-subtitle); - opacity: 0.58; - font-size: 1.2rem; - width: 65%; -} -@media only screen and (min-device-width: 360px) and (max-device-width: 736px) { - .home-splash .subtitle { - color: var(--ifm-color-dark); - opacity: 0.58; - font-size: 1.2rem; - width: 100%; - margin-top: 30px; - } -} - -.home-splash .button-wrapper { - margin-top: 28px; -} - -/* showcase */ -.product-showcase-title { - color: var(--color-primary); - font-size: 60px; - font-weight: bold; -} - .showcase { padding-left: 0; padding-right: 0; - margin-left: 0; - margin-right: 0; - margin-bottom: 70px; } .showcase .container { padding-left: 0; @@ -235,171 +207,590 @@ header h2 { } } -/* events section */ -.events-section .events-container { +/* button */ +.button { + margin: 0 10px; + padding: 12px 24px; + font-size: 18px; + font-weight: 600; + border-radius: 10px; + border: none; + background: #fee2e2; + color: #ef4444; + transition: all 0.3s; +} +.button:hover { + background: #fecaca; + color: #ef4444; +} +.button.github { + background: var(--color-github-button); + color: white; + display: inline-flex; + align-items: center; + margin-bottom: 15px; +} +.button.github .github-logo { + height: 24px; + margin: 0 12px 1px 0px; +} +.button.github:hover { + background: var(--color-github-button-hover); +} +.button-wrapper { + margin: 0 -10px; +} +.button.secondary { + background: #f3f4f6; + color: #1f2937; + border: 1px solid #d1d5db; + box-sizing: border-box; + margin-bottom: 15px; +} +.button.secondary:hover { + background: #e5e7eb; +} +@media only screen and (max-width: 414px) { + .button { + margin: 0; + } + .button.secondary, + .button.github { + width: 100%; + } + .button-wrapper { + margin: 0; + } +} +a { + color: inherit; + cursor: pointer; +} +a:hover { + color: var(--color-primary); +} +.markdown a { + color: var(--color-primary); +} + +.arrow-btn { + stroke-dasharray: 1000; + stroke-dashoffset: 1002; +} + +/*Hero section*/ +.hide-title, .hide-subtitle, .hide-ctas { + opacity: 0; +} + +.hero-sec-wrap{ + display: flex; + background: #f4f4f4ad; + height: 100vh; +} + +.homeCanvas-overlay { + position: absolute; + width: 50vw; + height: 100vh; + background: #FFFFFF; + top: -1px; + right: 0px; +} + +.homeCanvas{ + width: 50vw; + height: 100vh; +} + +.hero-text { + height: 100%; display: flex; - overflow: hidden; flex-wrap: wrap; - width: 100%; - margin: 16px 0; + align-content: center; + width: 50%; + padding: 0 0 0 6vw; +} + +.hero-title { + font-family: MaisonNeue-Bold; + color: #121212; + width: 42vw; + font-size: 4.2rem; + letter-spacing: 0.2px; + margin: 0; } -.events-section .event-item { + +.hero-subtitle { + z-index: 100; + font-size: 1.1rem; + font-family: MaisonNeue-Light; + position: relative; + color: #615D5D; + line-height: 30px; + letter-spacing: 0.2px; + margin: 25px 0; + padding-right: 20px; +} + +.hero-ctas { display: flex; - flex-direction: column; - justify-content: space-between; - text-align: left; - border: 1px solid var(--color-border); - margin: 8px; - padding: 8px 18px; - border-radius: 6px; - flex: 1; - cursor: pointer; + align-items: center; +} + +.btn { + background: #030c16; + border-style: solid; + border-width: 1px; + border: none; + color: white; + padding: 5px 20px 5px 20px; + border-radius: 20px; + font-size: 1rem; + text-decoration: none; + margin: 0 10px 0px 0; transition: all 0.3s; - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03); +} +.btn:hover { + background: #9b9b9b; + color: white; text-decoration: none; - min-width: 256px; } -@media (max-width: 574px) { - .events-section .event-item .event-read-button { - display: none; - } + +.btn-docs{ + display: flex; } -.events-section .event-item .event-title { - font-weight: 500; - color: var(--color-subtitle); - opacity: 0.88; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; +.btn-docs:hover{ + text-decoration: none; + color: #9b9b9b; +} + +/*Architecture section*/ +.hldesign{ + height: 100%; + display: flex; + justify-content: center; +} + +.hldesign-graphic{ + width: 60%; + height: auto; +} + +.Architecture_svg__architecture { + font-family: MaisonNeue-Medium; +} + +.arch { + background: linear-gradient(180deg, #E2ECFF 15%, #FFF 90%); + position: relative; + z-index: 1; + padding: 50px 0; overflow: hidden; - transition: all 0.3s; } -.events-section .event-item .event-publish-time { - color: var(--color-subtitle); - opacity: 0.58; - font-size: 12px; + +.arch-card-caption{ + height: 100%; + display: flex; + justify-content: center; + color: #615D5D; } -.events-section .event-item .event-read-button { - margin-top: 16px; - font-weight: 500; - color: var(--color-subtitle); - opacity: 0.58; - font-size: 12px; - transition: all 0.3s; + +.arch-card-border { + z-index: -10; + position: absolute; + width: 66%; + height: 100%; + border-style: solid; + top: 15px; + left: 17%; + border-color: white; + background: white; + filter: drop-shadow(0px 4px 10px rgb(0,0,0,0.25)); } -.events-section .event-item .event-read-button svg { - height: 8px; - margin-left: 1px; - transition: all 0.3s; + +.arch-head, .compare-head, .testimonials-head, .docs-promo-head, .oss-promo-head { + font-size: 2.4rem; + position: relative; + left: 16.8%; + width: 83.2%; } -.events-section .event-item:hover .event-title { - color: var(--ifm-color-primary); + +.arch-subtitle, .compare-subtitle, .testimonials-subtitle, .docs-promo-subtitle, .oss-promo-subtitle { + font-size: 1.13rem; + position: relative; + left: 16.8%; + width: 70%; + color: #615D5D; + letter-spacing: 0.2px; + font-family: MaisonNeue-Light; + font-weight: 700; } -.events-section .event-item:hover .event-read-button { - opacity: 0.88; + +.arch-card-caption > p{ + letter-spacing: 0.2px; + font-family: MaisonNeue-Light; + font-weight: 700; + text-align: center; + position: relative; + bottom: -15px; + font-size: 1rem; } -.events-section .event-item:hover { - border-color: rgb(231, 231, 231); - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.06); + +.add-left-margin{ + position: relative; + left: 16.8%; } -.events-section .events-view-all-button { - margin-top: 8px; - font-size: 14px; + +/*Features section*/ +.feat-head { + font-size: 2.4rem; + width: 75%; } -/* learn how */ -.learn-how { +.feat-container-d { + display: block; width: 100%; - border-radius: 16px; - background: var(--color-secondary-bg); + height: 300vh; + display: flex; } -.learn-how .container { - margin-top: 36px; - padding-bottom: 30px; + +.feat-container-m { + display: none; +} + +.feat-head-desc{ + font-size: 1.4rem; + color: #363130; + opacity: 0.5; + position: relative; + left: 17%; + margin: 0; + line-height: 1.8; + width: fit-content; } -.learn-how .hero__title { + +.feat-desc{ + margin: 10px 0; + font-size: 1.13rem; + color: #615D5D; font-weight: 700; - color: var(--color-subtitle); - opacity: 0.84; - font-size: 2.2rem; - margin-bottom: 10px; + font-family: MaisonNeue-Light; + width: 65%; + left: 17%; } -.learn-how .hero__subtitle { - color: var(--color-secondary-text); + +.add-left-margin-feat{ + position: absolute; + left: 34%; } -/* button */ -.button { - margin: 0 10px; - padding: 12px 24px; - font-size: 18px; - font-weight: 600; +.i-text{ + font-family: MaisonNeue-Demi; + font-size: 2rem; + padding: 0 0 200px 0; +} + +.text-div{ + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.i-text-desc{ + font-size: 1.13rem; + color: #615D5D; + font-weight: 700; + font-family: MaisonNeue-Light; +} + +.i-image { + opacity: 1; + width: auto; + height: 90%; border-radius: 10px; - border: none; - background: #fee2e2; - color: #ef4444; - transition: all 0.3s; + max-width: 200%; + max-height: 100%; + filter: drop-shadow(0px 4px 10px rgba(0, 0, 0, 0.25)); } -.button:hover { - background: #fecaca; - color: #ef4444; + +.n-image{ + opacity: 0; + width: auto; + height: 90%; + border-radius: 10px; + max-height: 100%; + max-width: 200%; + filter: drop-shadow(0px 4px 10px rgb(0,0,0,0.25)); +} + +.i-image-col{ + opacity: 1; + width: 100%; + height: auto; + max-height: 100%; + max-width: 100%; + margin: 0 0 20px 0; + filter: drop-shadow(0px 4px 10px rgb(0,0,0,0.25)); +} + +.imagePosition{ + position: absolute; + bottom: 10px; + left: 30px; +} + +.i-text-col { + font-family: MaisonNeue-Demi; + font-size: 2rem; + top: 0; +} + +.i-text-desc-col { + font-size: 0.95rem; + color: #615D5D; + font-weight: 700; + font-family: MaisonNeue-Light; + width: 80%; +} + +.hiddenDiv-col{ + opacity: 0; +} + +/*benefits section*/ +.row-benefit{ + margin: 100px 5px; + display: flex; + justify-content: center; + align-items: center; + height: fit-content; +} + +.benefit{ + background: #fff8f6; + padding: 50px 0; +} + +.benefit-infograph{ + width: 50%; + display: flex; + justify-content: center; + align-items: center; +} + +/*Comparison table section*/ +.compare { + padding: 50px 0; +} + +.table tbody td:nth-child(even) { + background: rgba(14,30,37,.02); +} + +.table tbody tr:nth-child(odd) { + background: rgba(14,30,37,.02); +} + +.table thead { + font-size: 1.13rem; +} + +.table { + background: #fff; + border-radius: 8px; + box-shadow: 0 0 0 1px rgba(255,255,255,.1),0 2px 4px 0 rgba(14,30,37,.12); + color: rgba(14,30,37,.87); + font-size: 1.13rem; + margin: 1em auto; + border-collapse: collapse; + max-width: 100%; + overflow-x: auto; + table-layout: fixed; + width: 66.4%; + font-family: MaisonNeue-Light; + display: table; +} + +.table td, .table th { + font-weight: 700; + min-width: 11.089em; + padding: .85rem 1rem; + text-align: center; +} + +.table-head { + font-weight: 900; + font-family: MaisonNeue-Demi; + font-size: 1.25rem; +} + +.table tbody th { + font-weight: 700; +} + +.table td:first-child, .table th:first-child { + text-align: left; +} + +/*opensource and docs promotion*/ +.docs-promo{ + display: flex; + padding: 100px 0; + background: #fff8f6; + justify-content: center; +} + +.docs-promo-text { + display: flex; + justify-content: center; + flex-flow: column; +} + +.docs-promo-video { + display: flex; + align-items: center; + justify-content: center; + width: 50%; +} + +.docs-promo-video>iframe { + width: 500px; + height: 288px; +} + +.oss-promo { + display: flex; + padding: 50px 0; + flex-flow: row-reverse; + color: black; + background: #fff8f6; +} + +.oss-promo-text { + width: 50%; + display: flex; + justify-content: center; + flex-direction: column; + background: #121010; + color: white; +} + +.oss-promo-infograph { + background: #0a0a0a; + width: 50%; + height: 100%; +} + +.oss-promo-cta { + background: #080808; + display: flex; + width: fit-content; + font-size: 0.95rem; + border-style: solid; + border-radius: 32px; + border-width: 1.75px; + padding: 5px 12px; + transition: background 0.5s; +} +.oss-promo-cta:hover { + background: #9b9b9b; + color: #080808; + border-style: solid; } -.button.github { - background: var(--color-github-button); - color: white; - display: inline-flex; - align-items: center; +.oss-promo-cta>a:hover { + color: #080808; +} + +/*Events and newsletter*/ +.event-card-container { + display: flex; justify-content: center; - border: 1px solid #101827; - padding: 11px 23px; - margin-bottom: 1rem; + align-items: center; + width: 100%; } -.button.github .github-logo { - height: 24px; - margin: 0 12px 1px 0px; + +.event-card { + border-style: solid; + border-color: #fff; + box-shadow: 0px 4px 23px rgba(0, 0, 0, 0.10); + font-size: 0.95rem; + font-family: MaisonNeue-Light; + font-weight: 700; + padding: 20px ; + width: 230px; + height: 200px; + margin: 0 20px; + border-radius: 10px; + position: relative; } -.button.github:hover { - background: var(--color-github-button-hover); + +.event-card-title { + position: absolute; + top: 25px; } -.button-wrapper { - margin: 0 -10px; +.event-card-time { + position: absolute; + top: 50%; } -.button.secondary { - background: #f3f4f6; - color: #1f2937; - border: 1px solid #d1d5db; - padding: 11px 23px; - margin-bottom: 1rem; +.event-card-read { + position: absolute; + bottom: 25px; } -.button.secondary:hover { - background: #e5e7eb; + +.newsletter { + display: flex; + font-weight: 700; + font-family: MaisonNeue-Light; + font-size: 0.95rem; + color: #615D5D; + letter-spacing: 0.2px; + align-items: center; + justify-content: center; + flex-direction: column; + margin: 25px 0; } -@media only screen and (max-width: 414px) { - .button { - margin: 0; - } - .button.secondary, - .button.github { - width: 100%; - } - .button-wrapper { - margin: 0; - } + +.news-button { + border: none; + padding: 5px 30px; + border-style: solid; + border-radius: 20px; + background: #030c16; + color: white; + margin: 0; + text-decoration: none; + transition: all 0.3s; } -a { - color: inherit; - cursor: pointer; +.news-button:hover { + background: #9b9b9b; + color: white; + text-decoration: none; } -a:hover { - color: var(--color-primary); + +.endcta-text { + text-align: center; + font-size: 3.5rem; + font-family: MaisonNeue-ExtraBold; } -.markdown a { - color: var(--color-primary); + +.endcta-btns { + display: flex; + justify-content: center; + padding-bottom: 2rem; +} + +.rocket { + width: 6vw; + height: auto; + transform: rotate(45deg); } /* footer */ -.footer { - margin-top: 2rem; +.footer__title { + /* margin-top: 2rem; */ + font-family: MaisonNeue-Medium !important; } .footer__links .footer__title { font-weight: 700; @@ -438,42 +829,6 @@ a:hover { opacity: 0.88; } -/* - Animations -*/ - -/* feature-word-text */ -.feature-word-text-enter, -.feature-word-text-appear { - opacity: 0; - transform: translateX(-24px); -} - -.feature-word-text-enter-active, -.feature-word-text-appear-active { - opacity: 1; - transform: translateX(0); - transition: all 300ms; -} - -.feature-word-text-enter-done { - opacity: 1; -} - -.feature-word-text-exit { - transform: translateX(24px); - opacity: 1; -} - -.feature-word-text-exit-active { - opacity: 0; - transition: opacity 300ms; -} - -.feature-word-text-exit-done { - opacity: 0; -} - /* help page */ .help-page .cards { margin-top: 38px; @@ -541,75 +896,10 @@ a:hover { display: flex; } -/*contribution section*/ -.contribution { - justify-content: center; - margin-bottom: 100px; -} - -.center-elem { - display: flex; - justify-content: center; -} - -.contribution-text { - color: var(--color-primary); - text-align: center; -} - -.contribution-link { - display: flex; - align-items: center; - justify-content: center; -} - -.contribution-logo { - vertical-align: middle; - margin: 0 12px 1px 0px; - height: 24px; -} - .team-githubLogo { height: 24px; } -/*newsletter section*/ - -.center-elem { - display: flex; - justify-content: center; -} - -.news-logo { - margin-bottom: 20px; -} - -.news-button { - border: #111827; - padding: 5px 30px; - border-style: solid; - border-radius: 9px; - background: var(--color-github-button); - color: white; - margin: 4px; - text-decoration: none; - transition: all 0.3s; -} -.news-button:hover { - background: var(--color-github-button-hover); - color: white; - text-decoration: none; -} - -.news-logo-svg { - height: 42px; -} - -.news-text { - color: var(--color-primary); - text-align: center; -} - .downloads-subtitle { color: var(--color-downloads-subtitle); } @@ -659,7 +949,7 @@ a:hover { } .pic-wrapper { - width: 440px; + width: 350px; position: fixed; display: flex; right: 0; @@ -679,11 +969,13 @@ a:hover { position: absolute; z-index: 1000; top: 10px; - right: 25px; + right: 10px; + padding: 5px; font-weight: 900; color: rgb(135, 151, 172); font-size: 16px; outline: none; + border-radius: 100px; border: 1px solid transparent; } @@ -693,13 +985,13 @@ a:hover { .pic-wrapper-close svg { width: 10px; - height: 15px; + height: 10px; display: inherit; } @media only screen and (max-width: 440px) { .pic-wrapper { - width: 100%; + width: 70%; } } @@ -738,7 +1030,6 @@ a:hover { } /*Sidebar Section*/ - .sidebar-link{ color: #d0312d; } @@ -746,3 +1037,272 @@ a:hover { .sidebar-link :hover { color: #ffb3b3; } + +/* Mobile-phones and tablet styles */ +@media only screen and (min-width: 300px) and (max-width: 1100px) { + body { + overflow-x: hidden !important; + } + + .hero-sec-wrap{ + display: block; + height: fit-content; + } + + .homeCanvas-overlay { + position: absolute; + width: 100vw; + height: 50vh; + background: #EBE6DC; + top: -1px; + right: 0px; + } + + .hero-text { + height: 50%; + width: 100%; + padding: 5rem 0 0 6vw; + } + + .hero-title { + width: 100vw; + font-size: 3.4rem; + } + + .hero-subtitle { + font-size: 1.05rem; + line-height: 28px; + margin: 25px 0 24px 0; + padding-right: 20px; + } + + .add-margin { + margin: 30px 0; + } + + .homeCanvas{ + width: 100vw; + height: 50vh; + } + + .hldesign-graphic{ + width: 100%; + } + + .arch-scale-svg { + display: none; + } + + .arch-card-border { + width: 100%; + left: 0; + top: 10px; + } + + .arch-head, .compare-head, .testimonials-head, .docs-promo-head, .oss-promo-head { + left: 7%; + width: 83%; + } + + .arch-subtitle, .compare-subtitle, .testimonials-subtitle, .docs-promo-subtitle, .oss-promo-subtitle { + left: 7%; + width: 85%; + } + + .add-left-margin{ + position: relative; + left: 7%; + } + + .add-left-margin-feat{ + position: absolute; + left: 7%; + } + + .bottom-pos { + bottom: 34%; + } + + .feat-head { + font-size: 2.13rem; + width: 84%; + } + + .feat-head-desc{ + left: 7%; + } + + .feat-desc{ + width: 83%; + left: 7%; + } + + .feat-container-d { + display: none; + } + .feat-container-m { + display: block; + } + + .benefit{ + background: #fff8f6; + padding: 50px 0; + height: 100vh; + } + + .row-benefit { + margin: 0 0px; + display: flex; + justify-content: center; + align-items: center; + flex-flow: column-reverse; + position: absolute; + height: 100vh; + width: 100vw; + } + + .benefit-infograph{ + width: 100%; + padding: 0 0 60px 0; + } + + .row-reverse{ + flex-flow: column; + } + + .row-hidden{ + opacity: 0; + } + + .table { + width: 100%; + display: block; + } + + .docs-promo { + flex-flow: column-reverse; + padding: 50px 0; + } + + .docs-promo-video { + width: 100%; + } + + .docs-promo-video>video { + padding: 0 26px 35px 26px; + width: 100%; + height: auto; + } + + .oss-promo { + flex-flow: column; + background: #121010; + padding: 50px 0 0 0; + + } + + .oss-promo-text { + width: 100%; + } + + .oss-promo-infograph { + width: 100%; + margin-top: 30px; + } + + .event-card { + margin: 0 20px 20px 20px; + } + + .event-card-container { + flex-flow: column; + } + + .newsletter>p { + text-align: center; + } + + .endcta-text { + font-size: 2.4rem; + } + + .navbar { + transform: none !important; + } + + .rocket { + width: 12vw; + height: auto; + transform: rotate(45deg); + } +} + +@media only screen and (min-height: 500px) and (max-height: 670px) { + .benefit-infograph { + width: 70%; + padding: 0 0 60px 0; + } +} + +.react-toggle { + display: none; +} + +.bottom-pos { + bottom: 34%; +} + +@media only screen and (min-device-width: 768px) and (max-device-width: 1100px) { + .feat-container-d { + display: none; + } + .feat-container-m { + display: block; + } +} + +@media only screen and (min-device-width: 300px) and (max-device-width: 360px) { + .hero-title { + font-size: 2.95rem; + } + + .hero-infograph { + overflow: hidden; + } + + .endcta-text { + font-size: 2.0rem; + } + + .arch-head, .compare-head, .testimonials-head, .docs-promo-head, .oss-promo-head { + left: 7%; + width: 93%; + } + + .benefit .feat-desc { + font-size: 0.85rem; + } + + .oss-promo-infograph { + overflow: hidden; + } +} + +@media (min-width: 1600px) and (max-width: 2080px) { + .hero-title { + width: 40vw; + font-size: 5.2rem; + } + + .hero-subtitle { + width: 40vw; + } + + .bottom-pos { + bottom: 38%; + } + + .arch-scale-svg { + transform: scale(1.2); + } +} diff --git a/website/src/pages/index.js b/website/src/pages/index.js index 7f72807403b4f..ec203d20c7837 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -1,77 +1,81 @@ -const React = require("react"); -import Link from "@docusaurus/Link"; +import React, { useState, useEffect, useLayoutEffect } from "react"; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import useBaseUrl from "@docusaurus/useBaseUrl"; import Layout from "@theme/Layout"; -import GitHubLogo from "../assets/icons/github-logo.svg"; -import { useState, useEffect } from "react"; -import { CSSTransition } from "react-transition-group"; -import ChevronRight from "../assets/icons/chevron-right.svg"; +import useThemeContext from '@theme/hooks/useThemeContext'; -const HomeSplash = () => { - const [featureWordIndex, setFeatureWordIndex] = useState(0); - const featureWords = ["Dynamic", "Real-Time", "Performant"]; +import HeroSection from "./sections/heroSection"; +import Architecture from "./sections/architecture"; +import Features from "./sections/features"; +import Benefits from "./sections/benefits"; +import Comparison from "./sections/comparison"; +import OpensourcePromo from "./sections/opensourcePromo"; +import NewsSection from "./sections/newsSection"; +import EndCTA from "./sections/endcta"; +import EventPosterCard from "./sections/components/eventPosterCard"; - const [isShow, setIsShow] = useState(true); +const useWindowSize = () => { + const [size, setSize] = useState([0, 0]); + useLayoutEffect(() => { + function updateSize() { + setSize([window.innerWidth, window.innerHeight]); + } + window.addEventListener('resize', updateSize); + updateSize(); + return () => window.removeEventListener('resize', updateSize); + }, []); + return size; +} - const changeFeatureWordIndex = (index) => { - setIsShow(false); - setFeatureWordIndex(index); - setIsShow(true); - }; - - useEffect(() => { - const timer = setInterval(() => { - if (featureWordIndex >= featureWords.length - 1) { - changeFeatureWordIndex(0); - } else { - changeFeatureWordIndex(featureWordIndex + 1); - } - }, 3600); - return () => clearInterval(timer); - }, [featureWordIndex]); +const Showcase = () => { + const {isDarkTheme, setLightTheme, setDarkTheme} = useThemeContext(); + + useEffect(() => { + if(isDarkTheme) { + setLightTheme(true); + } + }, []) + + const { siteConfig } = useDocusaurusContext(); + if (!(siteConfig.customFields.showcases || []).length) { + return null; + } + const showcases = siteConfig.customFields.showcases.map((user) => ( + + {user.caption} + + )); + const middleIndex = (showcases.length / 2).toFixed(0); return ( -
+
-
-
-

- A  - - - {featureWords[featureWordIndex]} - - -  Cloud-Native API - Gateway -

-
- Provides rich traffic management features such as load balancing, - dynamic upstream, canary release, circuit breaking, - authentication, observability, and more. Based on the Nginx - library and etcd. -
+

+ A wide variety of Companies and Organizations use APISIX for Research, Production and Commercial products +
  + + Add your company + +

+
+
+ +
+ {showcases.slice(0, middleIndex)} + {showcases.slice(0, middleIndex)} +
+
-
- - - View on GitHub - - - Downloads - +
+ +
+ {showcases.slice(middleIndex, showcases.length)} + {showcases.slice(middleIndex, showcases.length)} +
+
@@ -79,140 +83,22 @@ const HomeSplash = () => { ); }; -const LearnHow = () => ( -
-
-
-
-
-

- Description -

-

- - Cloud-native microservices API gateway, delivering the ultimate - performance, security, open source and scalable platform for all - your APIs and microservices. Apache APISIX is based on Nginx and - etcd. Compared with traditional API gateways, APISIX has dynamic - routing and plug-in hot loading, which is especially suitable - for API management under micro-service system. - -

-
-
- apisix-description -
-
-
-
-
-); - -const EventsSection = () => { - const { siteConfig } = useDocusaurusContext(); - const events = (siteConfig.customFields.events || []) - .slice(0, 4) - .map((event) => { - const publishTime = event.fileName.slice(0, 10); - const splittedFileName = event.fileName.split("-"); - const url = `/blog/${splittedFileName - .slice(0, 3) - .join("/")}/${splittedFileName.slice(3).join("-")}`; - return ( - -
-
{event.title}
-
{publishTime}
-
-
- Read -
-
- ); - }); - return ( -
-
-
-

Events

-
- -
{events}
-
-
- ); -}; - -const ContributionSection = () => { - - return ( -
-
-

Make your first contribution to Apache APISIX®

-
-
-

Find a good first issue to get you started !

-
-
- - - Good First Issues - -
-
- ); -}; - -const NewsletterSection = () => { +const Index = (props) => { - return ( -
-
- - - - - - - - - - - - - - - -
-
-

Stay up to date about all Apache APISIX® News

-
-
- Subscribe -
-
- ); -}; + const [screenWidth, screenHeight] = useWindowSize(); -const Index = (props) => { return ( - - - - - + + + + + + + + + + ); }; diff --git a/website/src/pages/sections/architecture.jsx b/website/src/pages/sections/architecture.jsx new file mode 100644 index 0000000000000..abcc2f9e24dee --- /dev/null +++ b/website/src/pages/sections/architecture.jsx @@ -0,0 +1,87 @@ +import React, { useEffect } from "react"; +import gsap from "gsap"; + +import "../../css/customTheme.css"; +import HLDesign from "../../assets/images/infographs/Architecture.svg"; +import Pattern from "../../assets/images/PatternGrouped.svg"; + +const Architecture = (props) => { + const screenWidth = props.screenWidth; + + useEffect(() => { + let strokePaths = [] + for (let i=1; i<28; i++) { + strokePaths.push(".PatternGrouped_svg__p"+i); + } + + let tlStroke = gsap.timeline({ + paused: true, + defaults: { + ease: "power2.inOut", + yoyo: true, + repeat: -1, + }, + }); + + tlStroke.fromTo(strokePaths, { + strokeDashoffset: 10000 + }, { + strokeDashoffset: 0, + duration: 5, + stagger: 0.3, + ease: "power2.inOut", + stroke: "red", + }); + + let observer = new IntersectionObserver(onIntersection, { + root: null, + threshold: 0.4, + }) + + function onIntersection(entries, opts){ + entries.forEach(entry => { + if (entry.isIntersecting) { + tlStroke.paused(false); + } else { + tlStroke.paused(true); + } + } + ); + } + + observer.observe( document.querySelector('.arch')); + + return () => { + tlStroke.pause(0).kill(true); + observer.disconnect(); + } + }, []); + + return ( + <> +
+
+ +
+
+

Building for large-scale, high value systems

+
+
+

Apache APISIX lets you build Cloud-Native Microservices API gateways, delivering the ultimate performance, security, open source and scalable platform for all your APIs and microservices.

+
+
+
+ +
+
+

=768 ? "50%" : "90%"}}>Apache APISIX is based on Nginx and etcd. Compared with traditional API gateways, APISIX has dynamic routing and hot-loading plugins

+
+
+
+
+
+ + ); +} + +export default Architecture; diff --git a/website/src/pages/sections/benefits.jsx b/website/src/pages/sections/benefits.jsx new file mode 100644 index 0000000000000..ad429e4bfd869 --- /dev/null +++ b/website/src/pages/sections/benefits.jsx @@ -0,0 +1,386 @@ +import React, { useRef, useEffect, useState } from "react"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import gsap from "gsap" +import { ScrollTrigger } from "gsap/ScrollTrigger"; + +import "../../css/customTheme.css"; + +import Performance from "../../assets/images/infographs/performance.svg"; +import Security from "../../assets/images/infographs/security.svg"; +import Scale from "../../assets/images/infographs/scale.svg"; +import Dynamic from "../../assets/images/infographs/dynamic.svg"; +import Multiplatform from "../../assets/images/infographs/multiplatform.svg"; + +const Benefits = (props) => { + const triggerDiv = useRef(null); + const performance = useRef(null); + const security = useRef(null); + const scale = useRef(null); + const dynamic = useRef(null); + const multiplatform = useRef(null); + + gsap.registerPlugin(ScrollTrigger); + + const screenWidth = props.screenWidth; + + useEffect(() => { + let tweenTls = []; + let observers = []; + + for (let i=0; i<5; i++) { + tweenTls.push(gsap.timeline({ + paused: true, + yoyo: true, + yoyoEase: "power3.out", + repeat: -1, + defaults: { + yoyo: true, + ease: "power3.inOut", + yoyoEase: "power3.out" + }, + })); + } + + let circles = []; + let links = []; + const colors = ["#FE7F80", "white", "red"]; + const pathColors = ["#FE7F80", "black"]; + + for (let i=1; i<28; i++) { + circles.push(".scale_svg__cir"+i); + links.push(".scale_svg__n"+i); + } + + // Performance anim + tweenTls[0].fromTo(".performance_svg__network",{ + strokeDashoffset: 1000, + stroke: "black" + },{ + strokeDashoffset: 0, + duration: 1, + strokeWidth: 5, + stroke: "orange", + ease: "power2.in", + yoyoEase: "power2.out", + repeat: -1, + }) + .fromTo(".performance_svg__lightning",{ + fill: "orange", + }, { + fill: "red", + duration: 1, + repeat: -1, + },"-=1"); + + // Security anim + tweenTls[1].fromTo([".security_svg__malWarn-square", ".security_svg__malConn"],{ + fill: "#FA5252", + },{ + fill: "yellow", + duration: 0.5, + repeat: -1, + repeatDelay: 0.1, + }) + for (let i = 1; i < 4; i++) { + tweenTls[1].fromTo(".security_svg__conn"+i, { + strokeWidth: 4, + strokeDasharray: 25, + strokeDashoffset: 200, + }, { + strokeDashoffset: 0, + duration: 2.5, + repeat: -1, + ease: "linear", + yoyoEase: "linear", + }) + } + + // Scaling anim + for (let i = 0; i < 27; i++) { + tweenTls[2].fromTo(circles[i],{ + fill: gsap.utils.random(colors), + },{ + fill: gsap.utils.random(colors), + duration: 0.3, + repeat: -1, + repeatDelay: 0.1, + }) + tweenTls[2].fromTo(links[i],{ + stroke: gsap.utils.random(pathColors), + },{ + stroke: gsap.utils.random(pathColors), + duration: 0.3, + repeat: -1, + repeatDelay: 0.1, + }) + } + + // Dynamic anim + tweenTls[3].repeatDelay(1.5); + tweenTls[3].fromTo([".dynamic_svg__rcard"],{ + x: -400, + opacity: 0, + },{ + opacity: 1, + x: 0, + ease: "sin.inOut", + duration: 1.5, + }) + .fromTo(".dynamic_svg__arrow", { + opacity: 0, + }, { + opacity: 1, + ease: "power3.out", + duration: 0.5, + }) + .fromTo(".dynamic_svg__lightning", { + opacity: 0, + y: 10, + }, { + opacity: 1, + y: 0, + duration: 1, + ease: "power2.inOut", + }); + + // Multiplatform anim + for(let i = 1; i < 4; i++) { + tweenTls[4].fromTo(".multiplatform_svg__server-port"+i,{ + fill: "#60E0F2", + },{ + fill: "#ffdc21", + duration: 0.5, + }); + } + + let standloneObserver = new IntersectionObserver(onIntersection, { + root: null, + threshold: 0.4, + }) + + let rot = 0; + const tweenArrow = gsap.fromTo(".multiplatform_svg__arrows", + { + rotation: rot, + },{ + rotation: -360+rot, + transformOrigin:"50% 50%", + ease: "power3.inOut", + duration: 3, + repeat: -1, + paused: true, + onComplete: () => { + rot -= 360; + } + }); + const tweenFloat = gsap.fromTo(".multiplatform_svg__lightning",{ + y: -2.5, + },{ + y: 5, + duration: 1, + ease: "linear", + repeat: -1, + yoyo: true, + paused: true, + yoyoEase: "linear", + }); + + function onIntersection(entries, opts){ + entries.forEach(entry => { + if (entry.isIntersecting) { + tweenArrow.paused(false); + tweenFloat.paused(false); + } else { + tweenArrow.paused(true); + tweenFloat.paused(true); + } + }); + } + + standloneObserver.observe(multiplatform.current); + + const elems = [performance.current, security.current, scale.current, dynamic.current, multiplatform.current]; + for (let i=0; i<5; i++) { + observers.push(new IntersectionObserver((entries, opts)=>{ + entries.forEach(entry => { + if (entry.isIntersecting) { + tweenTls[i].paused(false); + } else { + tweenTls[i].paused(true); + } + } + ); + }, { + root: null, + threshold: .2 + })); + } + + observers.forEach((it, index)=>{ + it.observe(elems[index]); + }); + + return () => { + observers.forEach((it, index)=>{ + it.disconnect(); + }); + tweenTls.forEach((it, index)=>{ + it.pause(0).kill(true); + }); + } + }, []) + + useEffect(() => { + ScrollTrigger.saveStyles([ + performance.current, + security.current, + scale.current, + dynamic.current, + multiplatform.current, + ]); + + ScrollTrigger.matchMedia({ + "(max-width: 1100px)": () => { + const tl = gsap.timeline({ + defaults: { + ease: "linear" + }, + scrollTrigger: { + id: 'benefits-scrolltrigger', + trigger: triggerDiv.current, + start: "top top", + pin: triggerDiv.current, + scrub: 1, + end: "+=500%" + } + }); + tl.fromTo(performance.current,{ + opacity: 1, + },{ + opacity: 0, + }) + .fromTo(security.current,{ + opacity: 0, + },{ + opacity: 1, + }) + .to(security.current,{ + opacity: 0, + }) + .fromTo(scale.current,{ + opacity: 0, + }, { + opacity: 1 + }) + .to(scale.current,{ + opacity: 0, + }) + .fromTo(dynamic.current,{ + opacity: 0, + }, { + opacity: 1 + }) + .to(dynamic.current,{ + opacity: 0, + }) + .fromTo(multiplatform.current,{ + opacity: 0, + }, { + opacity: 1, + }); + }, + "(min-width: 1101px)": () => { + const tl = gsap.timeline(); + tl.to(performance.current,{ + opacity: 1, + }) + .to(security.current,{ + opacity: 1, + }) + .to(scale.current,{ + opacity: 1, + }) + .to(dynamic.current,{ + opacity: 1, + }) + .to(multiplatform.current,{ + opacity: 1, + }); + } + }); + },[]); + + return ( + <> +
+
+
768 ? "50%" : "100%"}}> +

Performance

+

Ultimate performance

+

+ Apache APISIX uses radixtree-route-matching and etcd under the hood to provide you the ability to create high speed synchronized systems. From routing to built-in plugins, all these are designed and implemented to be uber performant with the minimum latency possible. +

+
+
+ =768 ? "35%" : "40%"}}/> +
+
+ +
+
+ =768 ? "75%" : "100%", position: "relative", left: screenWidth >=768 ? "3%" : "0"}}/> +
+
768 ? "50%" : "100%"}}> +

Security

+

Shield against the malicious

+

+ Apache APISIX provides multiple security plugins for identity authentication and interface verification, putting stability and security first. For more information, check here. +

+
+
+ +
+
768 ? "50%" : "100%"}}> +

Scalability and availability

+

Scales with your users

+

+ Apache APISIX provides the ability to write your own custom plugins, use custom Load Balancing Algorithms during the balancer phase for scaling and custom Routing algorithms for fine control on routing. +

+
+
+ =768 ? "50%": "60%"}}/> +
+
+ +
+
+ =768 ? "50%" : "70%"}}/> +
+
768 ? "50%" : "100%"}}> +

Fully dynamic

+

Save dev-time, design what matters

+

+ Apache APISIX provides Hot updates and Hot plugins, which continuosly update configurations without restarts, saving development time and stress. Health checks, circuit breakers and many more features keep the system balanced at all times. +

+
+
+ +
+
768 ? "50%" : "100%"}}> +

Multi-platform and protocol

+

Create once, run anywhere

+

+ Platform agnostic, no vendor lock-in, Apache APISIX can run from bare-metal to kubernetes. It supports HTTP to gRPC transcoding, websockets, gRPC, Dubbo, MQTT proxy and multiple platforms including ARM64, don’t worry about the lock-in of the infra technology. +

+
+
+ =768 ? "50%" : "80%"}}/> +
+
+
+ + ); +} + +export default Benefits; diff --git a/website/src/pages/sections/comparison.jsx b/website/src/pages/sections/comparison.jsx new file mode 100644 index 0000000000000..11ef8e1945a95 --- /dev/null +++ b/website/src/pages/sections/comparison.jsx @@ -0,0 +1,79 @@ +import React from "react"; + +import "../../css/customTheme.css"; +import Cross from "../../assets/icons/cross.svg"; +import Tick from "../../assets/icons/tick.svg"; + +const Comparison = () => { + return ( + <> +
+
+

Among the best, and always improving

+
+
+

Apache APISIX is opensource and ever evolving. Here’s a general comparison of APISIX with other options in this API Gateway ecosystem.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Feature + APISIX + + Other API Gateways +
Single-core CPU, QPS (enable limit-count and prometheus plugins)18000~1700
Latency0.2 ms2 ms
Dubbo, MQTT, Tengine and REST API to gRPC transcoding
Configuration rollback
Custom Load Balancing and routing
Plug-in hot loading
Dashboard
Support any Nginx variable as routing condition
+
+
+ + ); +} + +export default Comparison; diff --git a/website/src/pages/sections/components/arrowAnim.jsx b/website/src/pages/sections/components/arrowAnim.jsx index a008e77495b3c..df7a7bc1bbb09 100644 --- a/website/src/pages/sections/components/arrowAnim.jsx +++ b/website/src/pages/sections/components/arrowAnim.jsx @@ -2,54 +2,55 @@ import React, { useRef } from "react"; import Link from "@docusaurus/Link"; import useBaseUrl from "@docusaurus/useBaseUrl"; import gsap from "gsap" + import "../../../css/customTheme.css"; -function ArrowAnim() { - const endpathRef1 = useRef(null); - const endpathRef2 = useRef(null); +const ArrowAnim = () => { + const endpathRef1 = useRef(null); + const endpathRef2 = useRef(null); - function mouseOver() { - gsap.to([endpathRef2.current],{ - strokeDashoffset: 970, - duration: 0.4 - }); - gsap.to([endpathRef1.current],{ - stroke: "#9b9b9b", - duration: 0.4 - }); - gsap.to([endpathRef2.current],{ - stroke: "#9b9b9b", - duration: 0.4 - }); - } - - function mouseOut() { - gsap.to([endpathRef2.current],{ - strokeDashoffset: 1002, - duration: 0.4 - }); - gsap.to([endpathRef1.current],{ - stroke: "black", - duration: 0.4 - }); - gsap.to([endpathRef2.current],{ - stroke: "black", - duration: 0.4 - }); - } + function mouseOver() { + gsap.to([endpathRef2.current],{ + strokeDashoffset: 970, + duration: 0.4 + }); + gsap.to([endpathRef1.current],{ + stroke: "#9b9b9b", + duration: 0.4 + }); + gsap.to([endpathRef2.current],{ + stroke: "#9b9b9b", + duration: 0.4 + }); + } - return ( - <> - - Go to docs... - - - - - - - ); + function mouseOut() { + gsap.to([endpathRef2.current],{ + strokeDashoffset: 1002, + duration: 0.4 + }); + gsap.to([endpathRef1.current],{ + stroke: "black", + duration: 0.4 + }); + gsap.to([endpathRef2.current],{ + stroke: "black", + duration: 0.4 + }); } + + return ( + <> + + Go to docs... + + + + + + + ); +} - export default ArrowAnim; +export default ArrowAnim; diff --git a/website/src/pages/sections/components/eventPosterCard.jsx b/website/src/pages/sections/components/eventPosterCard.jsx index a34a422694107..f98f63af69d80 100644 --- a/website/src/pages/sections/components/eventPosterCard.jsx +++ b/website/src/pages/sections/components/eventPosterCard.jsx @@ -1,57 +1,58 @@ import React, { useState, useRef, useEffect } from "react"; import gsap from "gsap" + import "../../../css/customTheme.css"; const EventPosterCard = () => { - const [display, setDisplay] = useState(true); - const picRef = useRef(null); + const [display, setDisplay] = useState(true); + const picRef = useRef(null); - useEffect(() => { - gsap.fromTo(picRef.current, { - x: 500, - opacity: 0 - }, { - x: 0, - opacity: 1, - delay: 3.0, - }); - }, []); + useEffect(() => { + gsap.fromTo(picRef.current, { + x: 500, + opacity: 0 + }, { + x: 0, + opacity: 1, + delay: 3.0, + }); + }, []); - useEffect(() => { - if (!localStorage.getItem('SHOW_EVENT_ENTRY')) { - setDisplay(true); - }; - }, []); - - const onClose = () => { - gsap.to(picRef.current, { - x: 500, - opacity: 0, - onComplete: ()=>{ - setDisplay(false); - } - }); - if (typeof window !== 'undefined') { - localStorage.setItem('SHOW_EVENT_ENTRY', 'true'); - } + useEffect(() => { + if (!localStorage.getItem('SHOW_EVENT_ENTRY')) { + setDisplay(true); }; + }, []); - if (!display) { - return null; + const onClose = () => { + gsap.to(picRef.current, { + x: 500, + opacity: 0, + onComplete: ()=>{ + setDisplay(false); + } + }); + if (typeof window !== 'undefined') { + localStorage.setItem('SHOW_EVENT_ENTRY', 'true'); } + }; - return ( -
- - - - -
- ) + if (!display) { + return null; } - export default EventPosterCard; + return ( +
+ + + + +
+ ); +} + +export default EventPosterCard; diff --git a/website/src/pages/sections/components/heroCanvas.jsx b/website/src/pages/sections/components/heroCanvas.jsx index 15e1fc69bbea0..6c47ae2bac154 100644 --- a/website/src/pages/sections/components/heroCanvas.jsx +++ b/website/src/pages/sections/components/heroCanvas.jsx @@ -1,227 +1,236 @@ import React, { useRef, useEffect } from "react"; import * as THREE from "three"; import gsap from "gsap" + import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"; + import "../../../css/customTheme.css"; import vertex from '!!raw-loader!../../../shaders/vertex.vert'; import fragment from '!!raw-loader!../../../shaders/fragment.frag'; -function HeroCanvas() { - const canvasRef = useRef(0); - const overlayRef = useRef(0); +const HeroCanvas = () => { + const canvasRef = useRef(0); + const overlayRef = useRef(0); - let canvasHeight, canvasWidth, screenWidth, screenHeight, controls; - let isLoaded = false, isRendering = false, animationFrame; + let canvasHeight, canvasWidth, screenWidth, screenHeight, controls; + let isLoaded = false, isRendering = false, animationFrame; - useEffect(() => { - - screenWidth = window.innerWidth; - screenHeight = window.innerHeight; + useEffect(() => { + screenWidth = window.innerWidth; + screenHeight = window.innerHeight; - let mouse = {x: 0.5, y: 0.5}; - let fragMouse = {x: 0.5, y: 0.5}; + let mouse = {x: 0.5, y: 0.5}; + let fragMouse = {x: 0.5, y: 0.5}; - let camera, mesh, scene, renderer, material, geometry; + let camera, mesh, scene, renderer, material, geometry; - window.addEventListener('resize', onWindowResize, false); - - if (screenWidth > 800) { - canvasHeight = screenHeight; - canvasWidth = screenWidth / 2; - } else { - canvasHeight = screenHeight / 2; - canvasWidth = screenWidth; - } - - canvasRef.current.width = canvasWidth; - canvasRef.current.height = canvasHeight; - - canvasRef.current.addEventListener("mousemove", function (event) { - - let ctx = { - x: (event.clientX), - y: (event.clientY) - }; - - const canvasOffset = { - left: canvasRef.current.getBoundingClientRect().x, - top: canvasRef.current.getBoundingClientRect().y - }; - - ctx.x = ((ctx.x - canvasOffset.left) / canvasWidth); - ctx.y = ((ctx.y - canvasOffset.top) / canvasHeight); - - gsap.to(mouse, 2, { - x: ctx.x * (canvasWidth / canvasHeight) - (canvasWidth / canvasHeight) / 2, - y: (1.0 - ctx.y) - 0.5, - onUpdate: ()=>{ - material.uniforms.u_mouse.value.x = mouse.x; - material.uniforms.u_mouse.value.y = mouse.y; - } - }); - - gsap.to(fragMouse, 2, { - x: ctx.x, - y: (1.0 - ctx.y), - onUpdate: ()=>{ - material.uniforms.u_fragMouse.value.x = fragMouse.x; - material.uniforms.u_fragMouse.value.y = fragMouse.y; - } - }); - }); + window.addEventListener('resize', onWindowResize, false); - function getRandom(a, b) { - return a + (b - a) * Math.random(); + if (screenWidth > 1100) { + canvasHeight = screenHeight; + canvasWidth = screenWidth / 2; + } else { + canvasHeight = screenHeight / 2; + canvasWidth = screenWidth; + } + + canvasRef.current.width = canvasWidth; + canvasRef.current.height = canvasHeight; + + canvasRef.current.addEventListener("mousemove", function (event) { + + let ctx = { + x: (event.clientX), + y: (event.clientY) + }; + + const canvasOffset = { + left: canvasRef.current.getBoundingClientRect().x, + top: canvasRef.current.getBoundingClientRect().y + }; + + ctx.x = ((ctx.x - canvasOffset.left) / canvasWidth); + ctx.y = ((ctx.y - canvasOffset.top) / canvasHeight); + + gsap.to(mouse, 2, { + x: ctx.x * (canvasWidth / canvasHeight) - (canvasWidth / canvasHeight) / 2, + y: (1.0 - ctx.y) - 0.5, + onUpdate: ()=>{ + material.uniforms.u_mouse.value.x = mouse.x; + material.uniforms.u_mouse.value.y = mouse.y; } + }); - let canvasObserver = new IntersectionObserver(onCanvasIntersection, { - root: null, - threshold: 0.01, - }); + gsap.to(fragMouse, 2, { + x: ctx.x, + y: (1.0 - ctx.y), + onUpdate: ()=>{ + material.uniforms.u_fragMouse.value.x = fragMouse.x; + material.uniforms.u_fragMouse.value.y = fragMouse.y; + } + }); + }); + + function getRandom(a, b) { + return a + (b - a) * Math.random(); + } + + let canvasObserver = new IntersectionObserver(onCanvasIntersection, { + root: null, + threshold: 0.01, + }); - init(canvasWidth, canvasHeight); + init(canvasWidth, canvasHeight); - function onCanvasIntersection(entries, opts){ - entries.forEach( entry => { - if (entry.isIntersecting && isLoaded) { - if (isLoaded && !isRendering) { - animate(); - } else { - console.log("Loading") - } - } else { - if (animationFrame) { - cancelAnimationFrame(animationFrame); - isRendering = false; - } - } + function onCanvasIntersection(entries, opts){ + entries.forEach( entry => { + if (entry.isIntersecting && isLoaded) { + if (isLoaded && !isRendering) { + animate(); + } else { + console.log("Loading") } - ); - } + } else { + if (animationFrame) { + cancelAnimationFrame(animationFrame); + isRendering = false; + } + } + } + ); + } - canvasObserver.observe(canvasRef.current); + canvasObserver.observe(canvasRef.current); - function init(width, height) { - const ctx = canvasRef.current; - - renderer = new THREE.WebGLRenderer({canvas: ctx}); - renderer.autoClearColor = false; + function init(width, height) { + const ctx = canvasRef.current; + + renderer = new THREE.WebGLRenderer({canvas: ctx}); + renderer.autoClearColor = false; - camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100); - controls = new OrbitControls( camera, renderer.domElement ); - - controls.enableZoom = false; - controls.enablePan = false; - controls.enabled = false; + camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100); + controls = new OrbitControls( camera, renderer.domElement ); + + controls.enableZoom = false; + controls.enablePan = false; + controls.enabled = false; - geometry = new THREE.PlaneBufferGeometry(width / height, 1, 200, 200); + geometry = new THREE.PlaneBufferGeometry(width / height, 1, 250, 250); - let count = geometry.attributes.position.count; - let arrSize = new THREE.BufferAttribute(new Float32Array(count), 1); + let count = geometry.attributes.position.count; + let arrSize = new THREE.BufferAttribute(new Float32Array(count), 1); - for (let i = 0; i < arrSize.count; i++) { - arrSize.array[i] = getRandom(0, 1) - } - geometry.setAttribute("aSize", arrSize, 1); + for (let i = 0; i < arrSize.count; i++) { + arrSize.array[i] = getRandom(0, 1) + } + geometry.setAttribute("aSize", arrSize, 1); - geometry.scale(2.0, 1.0, 1.0); + geometry.scale(2.0, 1.0, 1.0); - scene = new THREE.Scene(); - renderer.setSize(canvasWidth, canvasHeight); - - let uniforms = { - u_time: { - type: "f", - value: 1.0 - }, - u_resolution: { - type: "v2", - value: new THREE.Vector2() - }, - u_mouse: { - type: "v2", - value: new THREE.Vector2(0.5, 0.5) - }, - u_fragMouse: { - type: "v2", - value: new THREE.Vector2(0.5, 0.5) - }, - }; + scene = new THREE.Scene(); + renderer.setSize(canvasWidth, canvasHeight); - scene.background = new THREE.Color('red'); + let uniforms = { + u_time: { + type: "f", + value: 1.0 + }, + u_resolution: { + type: "v2", + value: new THREE.Vector2() + }, + u_mouse: { + type: "v2", + value: new THREE.Vector2(0.5, 0.5) + }, + u_fragMouse: { + type: "v2", + value: new THREE.Vector2(0.5, 0.5) + }, + }; - camera.position.z = 5; - controls.update(); - - material = new THREE.ShaderMaterial({ - uniforms: uniforms, - vertexShader: vertex, - fragmentShader: fragment, - wireframe: true, - side: THREE.DoubleSide - }); - - mesh = new THREE.Points(geometry, material); - - let backGeometry = new THREE.PlaneBufferGeometry(width / height, 1, 200, 200); - let bgMaterial = new THREE.MeshBasicMaterial({color: 0x121212, wireframe: false}); - let background = new THREE.Mesh(backGeometry, bgMaterial); - - backGeometry.scale(50,50,1); - background.position.set(10,10,-10); - background.rotation.set(Math.PI/2,0,0); - - scene.add(mesh); - scene.add(background); - - camera.position.set( 0.16430412417444037, -1.5202138879420155, 0.20892968987792318); // Tested and checked - controls.update(); - - renderer.setPixelRatio(window.devicePixelRatio); - onWindowResize(); - - isLoaded = true; - } + scene.background = new THREE.Color('red'); - function onWindowResize(event) { - screenHeight = window.innerHeight; - screenWidth = window.innerWidth; + camera.position.z = 5; + controls.update(); + + material = new THREE.ShaderMaterial({ + uniforms: uniforms, + vertexShader: vertex, + fragmentShader: fragment, + wireframe: true, + side: THREE.DoubleSide + }); + + mesh = new THREE.Points(geometry, material); + + let backGeometry = new THREE.PlaneBufferGeometry(width / height, 1, 200, 200); + let bgMaterial = new THREE.MeshBasicMaterial({color: 0x121212, wireframe: false}); + let background = new THREE.Mesh(backGeometry, bgMaterial); + + backGeometry.scale(50,50,1); + background.position.set(10,10,-10); + background.rotation.set(Math.PI/2,0,0); - renderer.setSize(canvasWidth, canvasHeight); - material.uniforms.u_resolution.value.x = renderer.domElement.width; - material.uniforms.u_resolution.value.y = renderer.domElement.height; - } + scene.add(mesh); + scene.add(background); + + camera.position.set( 0.16430412417444037, -1.5202138879420155, 0.20892968987792318); // Tested and checked + controls.update(); + + renderer.setPixelRatio(window.devicePixelRatio); + onWindowResize(); + + isLoaded = true; + } - function animate() { - animationFrame = requestAnimationFrame(animate); - material.uniforms.u_time.value += 0.05; - controls.update(); - renderer.render(scene, camera); - isRendering = true; - } + function onWindowResize(event) { + screenHeight = window.innerHeight; + screenWidth = window.innerWidth; - return ()=>{ - renderer.dispose(); - canvasObserver.disconnect(); + if (screenWidth > 1100) { + canvasHeight = screenHeight; + canvasWidth = screenWidth / 2; + } else { + canvasHeight = screenHeight / 2; + canvasWidth = screenWidth; } - }, []); - - - useEffect(() => { - gsap.to(overlayRef.current,{ - height: 0, - delay: window.innerWidth >= 768 ? 0 : 0.3, - duration: 2.1, - ease: "Expo.easeInOut" - }); - }, []) + + renderer.setSize(canvasWidth, canvasHeight); + material.uniforms.u_resolution.value.x = renderer.domElement.width; + material.uniforms.u_resolution.value.y = renderer.domElement.height; + } + + function animate() { + animationFrame = requestAnimationFrame(animate); + material.uniforms.u_time.value += 0.05; + controls.update(); + renderer.render(scene, camera); + isRendering = true; + } + + return ()=>{ + scene.remove.apply(scene, scene.children); + canvasObserver.disconnect(); + } + }, []); - return ( -
- -
-
- ); + + useEffect(() => { + gsap.to(overlayRef.current,{ + height: 0, + delay: window.innerWidth >= 768 ? 0 : 0.3, + duration: 2.1, + ease: "Expo.easeInOut" + }); + }, []) + + return ( +
+ +
+
+ ); } export default HeroCanvas; diff --git a/website/src/pages/sections/components/ossCanvas.jsx b/website/src/pages/sections/components/ossCanvas.jsx index 8d2aca6a6792b..237594460c7a0 100644 --- a/website/src/pages/sections/components/ossCanvas.jsx +++ b/website/src/pages/sections/components/ossCanvas.jsx @@ -1,129 +1,138 @@ import React, { useRef, useEffect, useState } from "react"; import * as THREE from "three"; import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"; + import "../../../css/customTheme.css"; -function OssCanvas() { - const [screenWidth, setScreenWidth] = useState(typeof window !== 'undefined' && window.innerWidth); - const [screenHeight, setScreenHeight] = useState(typeof window !== 'undefined' && window.innerWidth); +const OssCanvas = () => { + let screenWidth, screenHeight; - const canvasRef = useRef(null); + const canvasRef = useRef(null); - let canvasHeight, canvasWidth; + let canvasHeight, canvasWidth; + + useEffect(() => { + let camera, scene, renderer, material, mesh; - useEffect(() => { - - let camera, scene, renderer, material, mesh; - - window.addEventListener('resize', onWindowResize, false); - - let controls; - let isLoaded = false, isRendering = false, animationFrame; - - if (screenWidth > 800) { - canvasHeight = 500; - canvasWidth = screenWidth/2; - } else { - canvasHeight = 500 - canvasWidth = screenWidth; - } + screenWidth = window.innerWidth; + screenHeight = window.innerHeight; + window.addEventListener('resize', onWindowResize, false); + + let controls; + let isLoaded = false, isRendering = false, animationFrame; + + if (screenWidth > 1100) { + canvasHeight = 500; + canvasWidth = screenWidth/2; + } else { + canvasHeight = 500 + canvasWidth = screenWidth; + } + + function onWindowResize(event) { + screenHeight = window.innerHeight; + screenWidth = window.innerWidth; + + if (screenWidth > 1100) { + canvasHeight = 500; + canvasWidth = screenWidth/2; + } else { + canvasHeight = 500 + canvasWidth = screenWidth; + } + + renderer.setSize(canvasWidth, canvasHeight); + } + + let ossCanvasObserver = new IntersectionObserver(onOssCanvasIntersection, { + root: null, + threshold: 0.01, + }); - function onWindowResize(event) { - setScreenHeight(window.innerHeight); - setScreenWidth(window.innerWidth); - renderer.setSize(canvasWidth, canvasHeight); - } + function init(width, height) { + const ctx = canvasRef.current; + renderer = new THREE.WebGLRenderer({canvas: ctx}); + + camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100); - let ossCanvasObserver = new IntersectionObserver(onOssCanvasIntersection, { - root: null, - threshold: 0.01, - }); - - function init(width, height) { - - const ctx = canvasRef.current; - renderer = new THREE.WebGLRenderer({canvas: ctx}); - - camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100); - - controls = new OrbitControls( camera, renderer.domElement ); - controls.enableZoom = false; - - const radius = window.innerWidth > 768 ? 5 : 4.5; - const detail = 8; - - const geometry = new THREE.IcosahedronGeometry(radius, detail); - - camera.position.z = 2; - camera.position.x = 3; - - controls.update(); - - scene = new THREE.Scene(); - renderer.setSize(canvasWidth, canvasHeight); - - scene.background = new THREE.Color(0x000000); - - material = new THREE.MeshNormalMaterial({wireframe: false, flatShading: true}); - - mesh = new THREE.Mesh(geometry, material); - - scene.add(mesh); - mesh.position.set(3, 0, -9.5); - - controls.target.copy(mesh.position) - - controls.update(); - renderer.setPixelRatio(window.devicePixelRatio); - - onWindowResize(); - - isLoaded = true; - } + controls = new OrbitControls( camera, renderer.domElement ); + controls.enableZoom = false; + + const radius = window.innerWidth > 768 ? 5 : 4.5; + const detail = 8; + + const geometry = new THREE.IcosahedronGeometry(radius, detail); + + camera.position.z = 2; + camera.position.x = 3; - function animate() { - animationFrame = requestAnimationFrame(animate); + controls.update(); + + scene = new THREE.Scene(); + renderer.setSize(canvasWidth, canvasHeight); + + scene.background = new THREE.Color(0x000000); - mesh.rotation.x += 0.005; - mesh.rotation.y += 0.005; + material = new THREE.MeshNormalMaterial({wireframe: false, flatShading: true}); - controls.update(); - - renderer.render(scene, camera); - isRendering = true; - } + mesh = new THREE.Mesh(geometry, material); - init(canvasWidth, canvasHeight); - - function onOssCanvasIntersection(entries, opts){ - entries.forEach(entry => { - if (entry.isIntersecting && isLoaded) { - if (isLoaded && !isRendering) { - animate(); - } else { - console.log("Loading") - } - } else { - if (animationFrame) { - cancelAnimationFrame(animationFrame); - isRendering = false; - } - } - } - ); - } + scene.add(mesh); + mesh.position.set(3, 0, -9.5); + + controls.target.copy(mesh.position) + + controls.update(); + renderer.setPixelRatio(window.devicePixelRatio); + + onWindowResize(); + + isLoaded = true; + } - ossCanvasObserver.observe(canvasRef.current); + function animate() { + animationFrame = requestAnimationFrame(animate); - return () => { - renderer.dispose(); - ossCanvasObserver.disconnect(); - } - }, []); + mesh.rotation.x += 0.005; + mesh.rotation.y += 0.005; - return ( - - ); + controls.update(); + + renderer.render(scene, camera); + isRendering = true; + } + + init(canvasWidth, canvasHeight); + + function onOssCanvasIntersection(entries, opts){ + entries.forEach(entry => { + if (entry.isIntersecting && isLoaded) { + if (isLoaded && !isRendering) { + animate(); + } else { + console.log("Loading") + } + } else { + if (animationFrame) { + cancelAnimationFrame(animationFrame); + isRendering = false; + } + } + } + ); + } + + ossCanvasObserver.observe(canvasRef.current); + + return () => { + scene.remove.apply(scene, scene.children); + ossCanvasObserver.disconnect(); + } + }, []); + + return ( + + ); } export default OssCanvas; diff --git a/website/src/pages/sections/endcta.jsx b/website/src/pages/sections/endcta.jsx new file mode 100644 index 0000000000000..a856472786727 --- /dev/null +++ b/website/src/pages/sections/endcta.jsx @@ -0,0 +1,31 @@ +import React from "react"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; + +import "../../css/customTheme.css"; +import ArrowAnim from "./components/arrowAnim"; +import Rocket from "../../assets/images/rocket.gif"; + +const EndCTA = () => { + return ( + <> +
+
+

Try APISIX today Rocket

+
+
+
+ + Downloads + + +
+
+
+ + ); +} + +export default EndCTA; diff --git a/website/src/pages/sections/features.jsx b/website/src/pages/sections/features.jsx new file mode 100644 index 0000000000000..d2e9c4308f5b7 --- /dev/null +++ b/website/src/pages/sections/features.jsx @@ -0,0 +1,210 @@ +import React, { useState, useRef, useEffect } from "react"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import gsap from "gsap" +import { ScrollTrigger } from "gsap/ScrollTrigger"; + +import "../../css/customTheme.css"; +import Dashboard from "../../assets/images/apisix-dashboard.png"; +import Snippet from "../../assets/images/code-sample.png"; +import Plugin from "../../assets/images/pluginised.png"; +import ArrowAnim from "./components/arrowAnim"; + +const Features = () => { + const dashboardDiv = useRef(null); + const userfDiv = useRef(null); + const pluginDiv = useRef(null); + const triggerDiv = useRef(null); + const triggerDivCol = useRef(null); + const pinDiv = useRef(null); + const img1 = useRef(null); + const img1col = useRef(null); + const img2 = useRef(null); + const img2col = useRef(null); + const img3 = useRef(null); + const img3col = useRef(null); + const featPin = useRef(null); + + gsap.registerPlugin(ScrollTrigger); + + const [screenWidth, setScreenWidth] = useState(typeof window !== 'undefined' && window.innerWidth); + const [screenHeight, setScreenHeight] = useState(typeof window !== 'undefined' && window.innerWidth); + + useEffect(()=>{ + setScreenHeight(window.innerHeight); + setScreenWidth(window.innerWidth); + window.addEventListener('resize', resizeEvent, false); + + function resizeEvent(event) { + setScreenHeight(window.innerHeight); + setScreenWidth(window.innerWidth); + } + + return () => { + window.removeEventListener('resize', resizeEvent); + } + }, []) + + useEffect(() => { + const value = window.innerHeight*2; + + let tl; + let observers = []; + + if(screenWidth > 1100) { + tl = gsap.timeline({ + defaults: { + ease: "linear" + }, + scrollTrigger: { + id: "feat", + trigger: triggerDiv.current, + start: "top top", + pin: pinDiv.current, + scrub: 1.5, + end: value+"px" + } + }); + + tl.to(img1.current,{ + opacity: 0, + }) + .to(img2.current,{ + opacity: 1, + }) + .to(img2.current,{ + opacity: 0, + }) + .to(img3.current,{ + opacity: 1, + }); + } else { + // Mobile + + const elems = [img1col.current, img2col.current, img3col.current] + for (let i=1; i<4; i++) { + observers.push(new IntersectionObserver((entries, opts)=>{ + entries.forEach(entry => { + if (entry.isIntersecting) { + observers[i-1].disconnect(); + gsap.fromTo(elems[i-1],{ + opacity: 0, + y: 90, + }, { + opacity: 1, + y: 0, + duration: 0.5, + ease: "power3.out", + yoyo: true, + yoyoEase: "power3.inOut", + }); + } + } + ); + }, { + root: null, + threshold: .2 + })); + } + + observers.forEach((it, index)=>{ + it.observe(elems[index]); + }); + } + }); + + return ( + <> +
+

Why APISIX ?

+

Reduce time fighting bugs, focus on designing world-class systems

+

+ Apache APISIX is the first Open source API gateway, with a built-in low-code Dashboard offering a powerful and flexible interface for developers to use +

+
+
+ {/* Desktop */} +
+
+
+

Easy-to-use dashboard

+

+ The Apache APISIX Dashboard is designed to make it as easy as possible for users to operate Apache APISIX through a frontend interface. It’s opensource and ever evolving, feel free to contribute. +

+
+ + Downloads + + +
+
+
+ +
+
+

User flexible

+

+ The Apache APISIX dashboard is flexible to User demand, providing option to create custom modules through code matching your requirements, alongside the existing no-code toolchain. +

+
+
+ +
+
+

Pluginised workflow

+

+ No need to reinvent the wheel again and again. Use inbuilt plugins to create high performance systems in tight deadlines. For something custom, there is option of building custom plugins. +

+
+
+
+ +
+ apisix-dashboard + code-snippet + plugin-workflow +
+
+
+ {/* Mobile */} +
+
+

Easy-to-use dashboard

+ +

+ The Apache APISIX Dashboard is designed to make it as easy as possible for users to operate Apache APISIX through a frontend interface. It’s opensource and ever evolving, feel free to contribute. +

+
+ + Downloads + + +
+
+
+ +
+

User flexible

+ +

+ The Apache APISIX dashboard is flexible to User demand, providing option to create custom modules through code matching your requirements, alongside the existing no-code toolchain. +

+
+ +
+

Pluginised workflow

+ +

+ No need to reinvent the wheel again and again. Use inbuilt plugins to create high performance systems in tight deadlines. For something custom, there is option of building custom plugins. +

+
+
+ + ); +} + +export default Features; diff --git a/website/src/pages/sections/heroSection.jsx b/website/src/pages/sections/heroSection.jsx new file mode 100644 index 0000000000000..ae4b96d83f1a5 --- /dev/null +++ b/website/src/pages/sections/heroSection.jsx @@ -0,0 +1,63 @@ +import React, { useRef, useEffect } from "react"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import gsap from "gsap" + +import "../../css/customTheme.css"; +import HeroCanvas from "./components/heroCanvas" +import ArrowAnim from "./components/arrowAnim"; + +const HeroSection = (props) => { + const titleRef = useRef(0) + const subtitleRef = useRef(0) + const ctaRef = useRef(0) + const canRef = useRef(0) + + useEffect(() => { + let tl = gsap.timeline({ + defaults: { + delay: window.innerWidth >= 768 ? 1.5 : 0.01, + duration: 0.5, + ease: "Expo.easeInOut" + }, + }); + + tl.fromTo([titleRef.current, subtitleRef.current, ctaRef.current],{ + opacity: 0, + y: 10 + },{ + opacity: 1, + y: 0, + stagger: 0.3 + }); + + return () => { + tl.pause(0).kill(true); + } + }, []) + + return ( + <> +
+
+

Effortless and smooth API Traffic management.

+

Apache APISIX provides rich traffic management features like Load Balancing, Dynamic Upstream, Canary Release, Circuit Breaking, Authentication, Observability, and more...

+
+ + Downloads + + +
+
+
+ +
+
+ + ); +} + +export default HeroSection; + \ No newline at end of file diff --git a/website/src/pages/sections/newsSection.jsx b/website/src/pages/sections/newsSection.jsx new file mode 100644 index 0000000000000..0ef8c5bfb6648 --- /dev/null +++ b/website/src/pages/sections/newsSection.jsx @@ -0,0 +1,47 @@ +import React from "react"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; + +import "../../css/customTheme.css"; +import ChevronRight from "../../assets/icons/chevron-right.svg"; + +const NewsSection = () => { + const { siteConfig } = useDocusaurusContext(); + const events = (siteConfig.customFields.events || []) + .slice(0, 4) + .map((event) => { + const publishTime = event.fileName.slice(0, 10); + const splittedFileName = event.fileName.split("-"); + const url = `/events/${splittedFileName + .slice(0, 3) + .join("/")}/${splittedFileName.slice(3).join("-")}`; + return ( + + ); + }); + + return ( + <> +
+
+

Stay updated about APISIX

+

Some Recent events

+
{events}
+
+
+

Stay up to date about all Apache APISIX™ News, subscribe to our newsletter.

+ Subscribe +
+
+ + ); +} + +export default NewsSection; diff --git a/website/src/pages/sections/opensourcePromo.jsx b/website/src/pages/sections/opensourcePromo.jsx new file mode 100644 index 0000000000000..1e81fe447901a --- /dev/null +++ b/website/src/pages/sections/opensourcePromo.jsx @@ -0,0 +1,48 @@ +import React from "react"; +import Link from "@docusaurus/Link"; +import useBaseUrl from "@docusaurus/useBaseUrl"; + +import OssCanvas from "./components/ossCanvas" + +import "../../css/customTheme.css"; +import GitHub from "../../assets/icons/github-logo.svg"; +import YtPromo from "../../assets/videos/apisix.mp4"; + +const OpensourcePromo = (props) => { + return ( + <> +
+
+
+

Learn from developers

+
+

Want to learn Apache APISIX usage, but don’t know where to start. Check out our docs.

+

Like visual information, check out our Youtube channel for detailed tutorials. Subscribe for more.

+
+
+
+ +
+
+ +
+
+

Be a part of building APISIX

+
+

Apache APISIX is opensource and ever-growing. Contributors are always welcome. Reach out to us on GitHub

+
+ + Check us out +
+
+
+
+ +
+
+
+ + ); +} + +export default OpensourcePromo; diff --git a/website/src/pages/showcase/styles.scss b/website/src/pages/showcase/styles.scss index c61b24ffcc5a6..dd66811bc2683 100644 --- a/website/src/pages/showcase/styles.scss +++ b/website/src/pages/showcase/styles.scss @@ -1,41 +1,41 @@ .showcase { - .header { - padding-top: 0; + .header { + padding-top: 0; - .title { - color: var(--color-primary); - font-size: 50px; - font-weight: bold; - } - - .tips { - font-size: 18px; - } + .title { + color: var(--color-primary); + font-size: 50px; + font-weight: bold; } - .content { - width: 100%; - padding: 50px 200px; - display: flex; - flex-wrap: wrap; + .tips { + font-size: 18px; } + } - .user-card { - padding: 30px 10px; + .content { + width: 100%; + padding: 50px 200px; + display: flex; + flex-wrap: wrap; + } - .logo { - max-width: 100px; - max-height: 40px; - } - } + .user-card { + padding: 30px 10px; - .row { - margin: 0; + .logo { + max-width: 100px; + max-height: 40px; } + } - @media (max-width: 1200px) { - .content { - padding: 50px 50px; - } + .row { + margin: 0; + } + + @media (max-width: 1200px) { + .content { + padding: 50px 50px; } + } } diff --git a/website/src/theme/DocPage/index.tsx b/website/src/theme/DocPage/index.tsx index ea7082355656c..f5eacadce2433 100644 --- a/website/src/theme/DocPage/index.tsx +++ b/website/src/theme/DocPage/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ReactNode, useState, useCallback} from 'react'; +import React, {ReactNode, useState, useCallback, useEffect} from 'react'; import {MDXProvider} from '@mdx-js/react'; import renderRoutes from '@docusaurus/renderRoutes'; @@ -46,6 +46,41 @@ function DocPageContent({ const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false); const [hiddenSidebar, setHiddenSidebar] = useState(false); + + useEffect(() => { + document.querySelector(".react-toggle").style.display = "block"; + const currentPage = currentDocRoute.path.split("/")[2] || ""; + switch (currentPage) { + case "general": + document.querySelectorAll(".navbar__link")[0].innerText = "General"; + break; + case "apisix": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX®"; + break; + case "dashboard": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX® Dashboard"; + break; + case "ingress-controller": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX® Ingress Controller"; + break; + case "helm-chart": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX® Helm Chart"; + break; + case "docker": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX® Docker"; + break; + case "java-plugin-runner": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX® Java Plugin Runner"; + break; + case "go-plugin-runner": + document.querySelectorAll(".navbar__link")[0].innerText = "Apache APISIX® Go Plugin Runner"; + break; + } + return () => { + document.querySelector(".react-toggle").style.display = "none"; + } + }, []); + const toggleSidebar = useCallback(() => { if (hiddenSidebar) { setHiddenSidebar(false); diff --git a/website/src/theme/DocSidebar/styles.module.css b/website/src/theme/DocSidebar/styles.module.css index 190eeb36a6168..a4988258985de 100644 --- a/website/src/theme/DocSidebar/styles.module.css +++ b/website/src/theme/DocSidebar/styles.module.css @@ -59,6 +59,8 @@ .collapseSidebarButton { display: block !important; + width: 100%; + margin: 0; background-color: var(--ifm-button-background-color); height: 40px; position: sticky;