Add decorative artist pattern background to desktop advertisements
Integrates an `ArtistPatternBg` component to wrap ad containers (`ArticleCardAd`, home page wide-picked ad section) with a decorative artist name pattern, enhancing visual appeal on desktop while leaving mobile unchanged. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 7e26d45f-76ee-4e0c-8b18-8bffeb9e004b Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/jdAEdU5 Replit-Helium-Checkpoint-Created: true
This commit is contained in:
parent
43bce5f4e9
commit
f2eb995d7d
@ -1,4 +1,5 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import ArtistPatternBg from "./artist-pattern-bg";
|
||||
|
||||
type AdFormat = "auto" | "fluid" | "rectangle" | "horizontal" | "vertical" | "autorelaxed";
|
||||
|
||||
@ -77,16 +78,19 @@ export default function AdSense({
|
||||
);
|
||||
}
|
||||
|
||||
let adSeedCounter = 1;
|
||||
|
||||
export function ArticleCardAd() {
|
||||
const seed = useMemo(() => adSeedCounter++, []);
|
||||
return (
|
||||
<div className="bg-card rounded-md border border-card-border overflow-hidden h-full">
|
||||
<ArtistPatternBg className="rounded-md border border-card-border h-full bg-card" seed={seed}>
|
||||
<AdSense
|
||||
slot="3854634730"
|
||||
format="fluid"
|
||||
layoutKey="-6r+cy-10+8a-3"
|
||||
style={{ display: "block" }}
|
||||
/>
|
||||
</div>
|
||||
</ArtistPatternBg>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
73
client/src/components/artist-pattern-bg.tsx
Normal file
73
client/src/components/artist-pattern-bg.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
const ARTISTS = [
|
||||
"Kastelruther Spatzen", "Melanie Payer", "Linda Feller", "Die Edlseer",
|
||||
"Hansi Berger", "Sašo Avsenik", "Die Grubertaler", "Pagger Buam",
|
||||
"John Prisco", "Igor und seine Oberkrainer", "Die Kaiser", "Marlena Martinelli",
|
||||
"Spitzbua Markus", "Julia Raich", "Meissnitzer Band", "Tauern Echo",
|
||||
"Brennholz", "Charly Kaiser", "Franz Nolf", "Franz Steiner",
|
||||
"Die 3 Z'widern", "Mark Ed", "Natascha", "Meli Stein",
|
||||
"SUSAL", "Pfundskerle", "Da Wadltreiber", "Sanny",
|
||||
"Alex Reichinger", "Sigrid & Marina", "Folx Stadl", "Gipfelstammtisch",
|
||||
];
|
||||
|
||||
function seededRandom(seed: number) {
|
||||
let s = seed;
|
||||
return () => {
|
||||
s = (s * 16807 + 0) % 2147483647;
|
||||
return s / 2147483647;
|
||||
};
|
||||
}
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
seed?: number;
|
||||
}
|
||||
|
||||
export default function ArtistPatternBg({ children, className = "", seed = 42 }: Props) {
|
||||
const items = useMemo(() => {
|
||||
const rng = seededRandom(seed);
|
||||
const result: { name: string; x: number; y: number; size: number; opacity: number; rotation: number; italic: boolean }[] = [];
|
||||
const count = 40;
|
||||
for (let i = 0; i < count; i++) {
|
||||
result.push({
|
||||
name: ARTISTS[Math.floor(rng() * ARTISTS.length)],
|
||||
x: rng() * 100,
|
||||
y: (i / count) * 100 + (rng() - 0.5) * 8,
|
||||
size: 9 + rng() * 9,
|
||||
opacity: 0.03 + rng() * 0.05,
|
||||
rotation: -12 + rng() * 24,
|
||||
italic: rng() > 0.6,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}, [seed]);
|
||||
|
||||
return (
|
||||
<div className={`relative overflow-hidden ${className}`}>
|
||||
<div className="absolute inset-0 pointer-events-none select-none hidden lg:block" aria-hidden="true">
|
||||
{items.map((item, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className="absolute whitespace-nowrap text-primary"
|
||||
style={{
|
||||
left: `${item.x}%`,
|
||||
top: `${item.y}%`,
|
||||
fontSize: `${item.size}px`,
|
||||
opacity: item.opacity,
|
||||
transform: `rotate(${item.rotation}deg)`,
|
||||
fontStyle: item.italic ? "italic" : "normal",
|
||||
fontWeight: item.italic ? 300 : 400,
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="relative z-[1]">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -8,6 +8,7 @@ import { Skeleton } from "@/components/ui/skeleton";
|
||||
import Header from "@/components/header";
|
||||
import Footer from "@/components/footer";
|
||||
import AdSense, { ArticleCardAd, MultiplexAd, SidebarAd } from "@/components/adsense";
|
||||
import ArtistPatternBg from "@/components/artist-pattern-bg";
|
||||
import { PhotoGalleryWidget } from "@/components/photo-gallery";
|
||||
import { HoroscopeWidget } from "@/components/horoscope-widget";
|
||||
import { RecipeWidget } from "@/components/recipe-widget";
|
||||
@ -631,7 +632,7 @@ export default function Home() {
|
||||
|
||||
{widePickedArticles.length > 0 && (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-4">
|
||||
<div className="hidden lg:block rounded-lg overflow-hidden bg-card border border-card-border">
|
||||
<ArtistPatternBg className="hidden lg:block rounded-lg overflow-hidden bg-card border border-card-border" seed={99}>
|
||||
<AdSense
|
||||
slot="3854634730"
|
||||
format="fluid"
|
||||
@ -639,7 +640,7 @@ export default function Home() {
|
||||
style={{ display: "block" }}
|
||||
className="w-full h-full min-h-[250px]"
|
||||
/>
|
||||
</div>
|
||||
</ArtistPatternBg>
|
||||
<div className="lg:col-span-3">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
{widePickedArticles.map((a) => (
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"access_token": "sl.u.AGVuqbSOwM_IaEQkqETN8XBMNt5yaozQHrwswboVTqkE2GeJpVRaGEjJYk_AEO1_PoylTdNl0pMwGO4_SS-REKTIm1Fls8sFKlJMN77GiJQJuGbB1qdrpwR22LpZDznp3rmkmoEhxiiDQiRUl5SBxBZTy19DWpx5nyV3Lc3eXvaOU9mKvXrOzvRqtDhFUxHlEKNCLO4s7buoYak9A9eqK27comnMEJMCKJ1Kqiho-ZKk9WNFkMSbdyQIAbM0Uwy0AUD4W69aSqmj41aVOT1Y_M_EepY1WnZjGX5t71iXFjTKqtbMIG_sCV9mkBITNXYfcYQwW6ZGuFW5mMBnQ1WJdjqPS_iVuL8tKfLTe2TBNq4-A3CPZwtOgIrara4-3pP6ifphxmkgeNLTD2Tw5q2Cl0KRF_ZBhoTO0PxgRaiBYhEnFWDdfp0Wsn0jk8BGk5OY4nsSDgJactpKmWT4itE1CE-R5QM1Dsd98BXkXoROf5CSc9d2UVcknM5fKp5RRNHhq_bdDl5-U2wt7SE_G_xf2pMVAZPO3m8YZWpeI21IyTJGrRe9NLSa7tkZpOTdEp3Bg_lHnh0IP2PP79-hlSsTtBQ4oclQ6iomGv-tRhcwt_hHdy71lhx2LUj4QwzyptYK_YSYCtgsMofpo7f5slJfWSP4-p0s_hU2hP2SC_Z9SLuPKn91bvaQLOu2PINxF0yNDo10Y1wUveZboN2S0KeK3tIyfNplQ2g6KEmBDGQgXlMabrkBZfSFqofhCYCX3sdqzQCJKK4IjXGmrFYozv4wjWHD0CwetaCBURmAqwdw6o7Be89HS2AbB5-iWxRDctSQALNS1VkE24lH9nelT31b_grTEZLkLZJqnbd4TjeY1b_AlPQ4p7d2dud0MekbzsDvFC7KAUdOTRDlsF_0YKYx2AohOu79Jz7jAWTaBFBQLsrr1IoemfAHDkLNhpxgQjWZZ4Wj3CMj-01IVSeRrX6BW_Gt7V_E5FgSnUTNZANYqMmNN7ggzmCwZltAI3uNLK_qi_XBN66uUDBMHoJD8MuHxXvWFa4r-rOEQh04YM6FpSltHq8I6fL0OYQe4zrrBOYMsu5Xg5NDg8e2n9iCq4s7CSYrbJrkvzJTPAjgy74hblV5mV6kryZ4YMtizfsMmY3PEH6thCby1tADA4gQSGouXwZVGm11Dc3SikM4wLPKnWwI2gU985QoB89vJmDLnv5FRvR_ryARI5_1TLuaWswfAYcZajGNvjS-7emRNTnVsuMl1E5uIcIKCXHrUIIkPGPTfe74NGrhMRi7fdGTtwMZgA0TEqiYFjEgabbqgazkz8F3tg",
|
||||
"access_token": "sl.u.AGUQq1dMOSrEC_xUCcjdbFyPUzqtq04u2Ya543b_-ykVOkXeSHLtcM_d24Sslmr0M6mrqYCQ7oYeh9l4XQEZWTGYWR_rDE5R_qn48gdf5DXpKM2_pzyeQaVteA0d2It52ETJRbVN4kGsJZixcwfLXGw4LK0r6FQ7Q4FYtQaYvyZKK1hO1p3SC8jL9mC_8ZUk-M-yrNtYfKnYbm6ZrMXX1WJEtqfM3fe1xVl2r0wlpq4PkSwXn_oU_EbGy6ITeJHx5PNI7_XME_tYdNDCdm9ESI-kV15r7SDtfBQfUoVx1zGGa_wsQq_chjd-v0nCoRhIWvBtxEo_cf9FyHzyqQ9iLKid1hzPZnam5rdW87B4DQQocWk8JjcAwqU4MGQWrViT-LXb6lGiyIQo_LCJlexgdlHMl8iN05-Za5rexP_K2g7GiU7bC1wf8TMFoI8xYS0Kq7pHz-Kx2AEUzip39x0dmAbb4Y07NvGWI3Cfi0fwe_7GQeKJ9KxLBMZIbAXnIfIzqK8H49npJddDPWlXJSMH6i2f4nLH05nnlf9HmqsO05TOESzxMwTAOsEStFDW0eBXrUB-UeBT8S5sfeuvubNYUNqAVw4IXisjZ4nnpfaIytuuBgPZOzQdaQkdgpxZaJFQz6uXU0ZzPMz4OnDhStSGoj15NRJDJWbNynaNWxTWv0Gncg09AP6IEuH_KdQdckUMVdmCBrTd4vsVGd__MZfsqt_SWsgEPA-xnUXSIRvhbmXCDTJsI0VHFywVfqHXtupw6ljkauw_BMiJv0p8KZhj9NB3aWJPamsPLV4UYRn_Cy2wYY6leqiAiyUI4lmcFkGtrVzeeLDG3Ga3pfm_7WlMU6ZJNuwVprxZpjf9yKR6U6u4Bc5_WoRvr7PTTu5oNOjGD2KCdSOBPDVuSL0lyMPazz1WpJ4SNAcC47c61Bp9ywO2TtDMGkcmKr6ElWxiPn21B3Cu2nh6_sCgIDLocMGPslME1VJb-msrDu8PLGX_fEnsOJd_2pHhr_cp3E3Kt8CB4mQfEtaPDhYkEQ9FvhvmtZ2sj9gYFYs0-6wE0bBaLLQBLgkBMgV5VZycNZ_A0tiB-uymKuFHdDZXVoejIrxBuRB1EiB30ba68BcM_erBItG3riwX5PfSNqJNhx0SEMNCiKjBKUuGRz6UQj64aZXOh6yvImw0SxXw922ktqTkqOk_hpZtkeGx21JC_NXohbqZnFlAMHfLFbsZUW8iaSbIzeydUvB3Llz-92Vx0hQAj3mOnMCteHivD2ra2izz_UwzfOhQ_6nLVJeWlWp6LpwycPya32VDQCb118S3zkfyrJZHNg",
|
||||
"refresh_token": "8-fiK0Io8Z8AAAAAAAAAAXn1QIGTwFTVWKF47COXY2bjqYlWyd4aRnFtQJ7usZ0y",
|
||||
"expires_at": 1772628298578,
|
||||
"expires_at": 1772647027085,
|
||||
"app_key": "sjwprgka82p8tpv",
|
||||
"app_secret": "g3vuczqo0rx3crz"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user