init game theme

This commit is contained in:
tangly1024.com
2024-03-18 18:57:49 +08:00
parent fc3e60e94c
commit ff77d30cae
41 changed files with 2366 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
/* eslint-disable @next/next/no-img-element */
import { AdSlot } from '@/components/GoogleAdsense'
import { deepClone } from '@/lib/utils'
import { useState } from 'react'
/**
* 游戏列表
* @returns
*/
export const GameListIndexCombine = ({ games }) => {
const gamesClone = deepClone(games)
gamesClone?.sort((a, b) => {
const orderA = a.order || 999
const orderB = b.order || 999
return orderA - orderB
})
// 构造一个List<Component>
const components = []
// 根据序号随机大小;或根据game.recommend 决定
const recommend = true
let index = 0
// 无限循环
if (recommend) {
// 4合一卡组
let groupItems = []
while (gamesClone?.length > 0) {
index++
// 广告位
if (index % 9 === 0) {
components.push(<GameAd key={index} />)
continue
}
// 试图将4合一卡组塞满
while (gamesClone?.length > 0 && groupItems.length < 4) {
const item = gamesClone.shift()
if (item.recommend) {
components.push(<GameItem key={index} item={item} isLargeCard={true} />)
break
} else {
groupItems.push(item)
}
}
if (groupItems.length === 4 || (gamesClone.length === 0 && groupItems.length > 4)) {
components.push(<GameItemGroup key={index} items={groupItems} />)
groupItems = []
} else {
while (groupItems.length > 0) {
const item = groupItems.shift()
components.push(<GameItem key={index++} item={item} isLargeCard={true} />)
}
}
}
} else {
while (gamesClone?.length > 0) {
index++
if (index % 6 === 0) {
components.push(<GameAd key={index} />)
} else if (index % 2 === 0 && gamesClone?.length >= 4) {
// 如果是偶数则从游戏列表中退出4个组成大卡牌
const groupItems = []
for (let i = 1; i <= 4; i++) {
groupItems.push(gamesClone.shift())
}
components.push(<GameItemGroup key={index} items={groupItems} />)
} else {
const item = gamesClone.shift()
components.push(<GameItem key={index} item={item} isLargeCard={true} />)
}
}
}
return (
<div className='game-list-wrapper flex justify-center w-full px-2'>
<div className='game-grid mx-auto w-full h-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2'>
{components?.map((ItemComponent, index) => {
return ItemComponent
})}
</div>
</div>
)
}
/**
* 一个广告游戏大卡
* @returns
*/
const GameAd = () => {
return (
<div className='card-group border border-gray-600 rounded game-ad h-[20rem] w-full overflow-hidden'>
<AdSlot type='flow' />
</div>
)
}
/**
* 4卡组成一个大卡
* @param {*} param0
* @returns
*/
const GameItemGroup = ({ items }) => {
return (
<div className='card-group h-[20rem] w-full grid grid-cols-2 grid-rows-2 gap-2'>
{items.map((item, index) => (
<GameItem key={index} item={item} />
))}
</div>
)
}
/**
* 游戏=单卡
* @param {*} param0
* @returns
*/
const GameItem = ({ item, isLargeCard }) => {
const { id, title, img, video } = item
const [showType, setShowType] = useState('img') // img or video
return (
<a
href={`/game/${id}`}
onMouseOver={() => {
setShowType('video')
}}
onMouseOut={() => {
setShowType('img')
}}
title={title}
className={`card-single ${
isLargeCard ? 'h-[20rem]' : 'h-full'
} w-full relative shadow rounded-md overflow-hidden flex justify-center items-center
group hover:border-purple-400`}>
<div className='text-center absolute bottom-0 invisible group-hover:bottom-2 group-hover:visible transition-all duration-200 text-white z-30'>
{title}
</div>
<div className='h-1/2 w-full absolute left-0 bottom-0 z-20 opacity-0 group-hover:opacity-75 transition-all duration-200'>
<div className='h-full w-full absolute bg-gradient-to-b from-transparent to-black'></div>
</div>
{showType === 'video' && (
<video
className={`z-10 object-cover w-full ${isLargeCard ? 'h-[20rem]' : 'h-full'} absolute overflow-hidden`}
loop='true'
autoPlay
preload='none'>
<source src={video} type='video/mp4' />
</video>
)}
<img
className='w-full h-full absolute object-cover group-hover:scale-105 duration-100 transition-all'
src={img}
alt={title}
/>
</a>
)
}