-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #885 from RainBondsongyg/rainstore
feat: rainstore product page
- Loading branch information
Showing
45 changed files
with
1,213 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Copyright (c) Goodrain, Inc. | ||
* | ||
* This source code is licensed under the LGPL-3.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React, { useEffect, useState } from "react"; | ||
import { animated, useTrail } from "react-spring"; | ||
import styles from "./styles.module.css"; | ||
import clsx from 'clsx'; | ||
import { useLocation } from '@docusaurus/router'; | ||
export default function AppType() { | ||
|
||
const LocalUrlEn = useLocation().pathname.includes('/en'); | ||
const animatedTexts = useTrail(5, { | ||
from: { opacity: 0, transform: 'translateY(3em)' }, | ||
to: { opacity: 1, transform: 'translateY(0)' }, | ||
config: { | ||
mass: 3, | ||
friction: 45, | ||
tension: 460, | ||
}, | ||
}) | ||
|
||
const handleOnClickLink = () => { | ||
window.open('https://rainbond.feishu.cn/share/base/shrcnv2iqnRsNJM6Y3hN5VhTJvg') | ||
} | ||
|
||
return ( | ||
<div className={styles.card}> | ||
<animated.div style={animatedTexts[0]} className={styles.card_body}> | ||
<div className={styles.apptype_img}> | ||
<img src="/img/rainstore/img/apptype.jpg" alt="" /> | ||
</div> | ||
<div className={styles.apptype_text}> | ||
<h2>支持常见应用包</h2> | ||
<p>支持四种类型的软件包,包括 Docker 镜像、Helm Chart、Rainbond App Model (RAM) 和其他软件包等,满足不同行业和业务的需求。</p> | ||
</div> | ||
</animated.div> | ||
<animated.div style={animatedTexts[0]} className={styles.card_body}> | ||
<div className={styles.apptype_text}> | ||
<h2>多样化应用交付形式</h2> | ||
<p>通过一键安装、离线包导出、私有化部署和后台一键交付等多种方式,灵活满足企业的多样化应用交付需求。</p> | ||
</div> | ||
<div className={styles.apptype_img}> | ||
<img src="/img/rainstore/img/delivery.jpg" alt="" /> | ||
</div> | ||
</animated.div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* Copyright (c) Goodrain, Inc. | ||
* | ||
* This source code is licensed under the LGPL-3.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
**/ | ||
|
||
|
||
@media screen and (max-width: 996px) { | ||
.card { | ||
width: 100% !important; | ||
} | ||
} | ||
|
||
.card { | ||
width: 1200px; | ||
margin: 0 auto; | ||
} | ||
|
||
.card_body { | ||
display: flex; | ||
justify-content: space-between; | ||
margin-top: 100px; | ||
} | ||
.apptype_img { | ||
width: 60%; | ||
height: 340px; | ||
} | ||
.apptype_img img { | ||
width: 100%; | ||
height: auto; | ||
border-radius: 5px; | ||
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); | ||
} | ||
.apptype_text{ | ||
width: 40%; | ||
padding: 20px; | ||
text-align: left; | ||
} | ||
.apptype_text h2{ | ||
font-size: 36px; | ||
font-weight: 600; | ||
margin-bottom: 20px; | ||
} | ||
.apptype_text p{ | ||
font-size: 18px; | ||
font-weight: 400; | ||
color: #637792; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
.carousel-container { | ||
position: relative; | ||
width: 100%; | ||
margin: 0 auto; /* 居中对齐 */ | ||
overflow: visible; /* 确保左右图片展示出来 */ | ||
} | ||
|
||
.carousel-wrapper { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
position: relative; | ||
height: 400px; /* 根据你的需要调整 */ | ||
} | ||
|
||
.carousel-card { | ||
position: absolute; | ||
transition: all 0.5s ease; | ||
opacity: 0; | ||
transform: scale(0.8); /* 缩小展示半张图 */ | ||
z-index: 0; | ||
} | ||
|
||
.carousel-card.active { | ||
opacity: 1; | ||
transform: scale(1) translateX(0); /* 中间图片放大并居中 */ | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
z-index: 2; | ||
} | ||
|
||
.carousel-card.prev { | ||
opacity: 0.5; | ||
transform: scale(0.85) translateX(-30%); /* 左侧展示半张图 */ | ||
z-index: 1; | ||
} | ||
|
||
.carousel-card.next { | ||
opacity: 0.5; | ||
transform: scale(0.85) translateX(30%); /* 右侧展示半张图 */ | ||
z-index: 1; | ||
} | ||
|
||
.carousel-card img { | ||
width: 100%; | ||
height: 400px; | ||
margin: 0 auto; | ||
border-radius: 10px; | ||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); | ||
} | ||
|
||
/* 指示器样式 */ | ||
.carousel-indicators { | ||
display: flex; | ||
justify-content: center; | ||
margin-top: 10px; | ||
} | ||
|
||
.indicator { | ||
width: 48px; | ||
height: 4px; | ||
background-color: #ddd; | ||
margin: 20px 5px; | ||
cursor: pointer; | ||
transition: background-color 0.3s; | ||
} | ||
|
||
.carousel-button { | ||
position: absolute; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
background: rgba(0, 0, 0, 0.5); | ||
color: white; | ||
border: none; | ||
padding: 10px; | ||
cursor: pointer; | ||
z-index: 3; | ||
display: none; | ||
} | ||
|
||
|
||
.carousel-description { | ||
text-align: center; | ||
margin-top: 28px; | ||
font-size: 18px; | ||
color: #333; | ||
} | ||
|
||
.carousel-button.prev { | ||
left: 20px; | ||
} | ||
|
||
.carousel-button.next { | ||
right: 20px; | ||
} | ||
|
||
.carousel-button:hover { | ||
background: rgba(0, 0, 0, 0.7); | ||
} | ||
|
||
.indicator.active { | ||
background-color: #007bff; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
import { PhotoProvider, PhotoView } from 'react-photo-view'; | ||
import './index.css'; | ||
|
||
interface CarouselProps { | ||
images: { src: string; description: string }[]; | ||
interval?: number; | ||
} | ||
|
||
const Carousel: React.FC<CarouselProps> = ({ images, interval = 3000 }) => { | ||
const [currentIndex, setCurrentIndex] = useState(0); | ||
|
||
useEffect(() => { | ||
const timer = setInterval(() => { | ||
setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length); | ||
}, interval); | ||
|
||
return () => clearInterval(timer); | ||
}, [images.length, interval]); | ||
|
||
const handlePrev = () => { | ||
setCurrentIndex(currentIndex === 0 ? images.length - 1 : currentIndex - 1); | ||
}; | ||
|
||
const handleNext = () => { | ||
setCurrentIndex((currentIndex + 1) % images.length); | ||
}; | ||
|
||
const handleClick = (index: number) => { | ||
setCurrentIndex(index); // 更新为点击的图片索引 | ||
}; | ||
|
||
return ( | ||
<div className="carousel-container"> | ||
<div className="carousel-wrapper"> | ||
{images.map((image, index) => { | ||
const isActive = index === currentIndex; | ||
const isPrev = index === (currentIndex - 1 + images.length) % images.length; | ||
const isNext = index === (currentIndex + 1) % images.length; | ||
|
||
return ( | ||
<div | ||
key={index} | ||
className={`carousel-card ${isActive ? 'active' : ''} ${isPrev ? 'prev' : ''} ${ | ||
isNext ? 'next' : '' | ||
}`} | ||
onClick={() => handleClick(index)} // 点击图片时切换 | ||
> | ||
<PhotoProvider> | ||
<PhotoView src={image.src} > | ||
<img src={image.src} alt={`carousel-${index}`} /> | ||
</PhotoView> | ||
</PhotoProvider> | ||
|
||
</div> | ||
); | ||
})} | ||
</div> | ||
<div className="carousel-indicators"> | ||
{images.map((_, index) => ( | ||
<span | ||
key={index} | ||
className={`indicator ${index === currentIndex ? 'active' : ''}`} | ||
onClick={() => handleClick(index)} // 点击指示器按钮时切换图片 | ||
></span> | ||
))} | ||
</div> | ||
<div className="carousel-description"> | ||
{images[currentIndex].description} | ||
</div> | ||
<button className="carousel-button prev" onClick={handlePrev}> | ||
‹ | ||
</button> | ||
<button className="carousel-button next" onClick={handleNext}> | ||
› | ||
</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Carousel; |
Oops, something went wrong.