button with image

This commit is contained in:
2025-06-26 17:54:51 +02:00
parent 8bab93274b
commit 96dbc38c3a
8 changed files with 141 additions and 69 deletions

View File

@ -11,10 +11,12 @@
"@pinia/nuxt": "^0.11.0",
"@tailwindcss/vite": "^4.1.8",
"@vueuse/core": "^13.3.0",
"gsap": "^3.13.0",
"nuxt": "^3.17.4",
"tailwindcss": "^4.1.7",
"vue": "^3.5.14",
"vue-router": "^4.5.1",
"vue3-toastify": "^0.2.8",
},
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.14.0",
@ -1290,6 +1292,8 @@
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
"gsap": ["gsap@3.13.0", "", {}, "sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw=="],
"gzip-size": ["gzip-size@7.0.0", "", { "dependencies": { "duplexer": "^0.1.2" } }, "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA=="],
"h3": ["h3@1.15.3", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.4", "defu": "^6.1.4", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.0", "radix3": "^1.1.2", "ufo": "^1.6.1", "uncrypto": "^0.1.3" } }, "sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ=="],
@ -2360,6 +2364,8 @@
"vue-router": ["vue-router@4.5.1", "", { "dependencies": { "@vue/devtools-api": "^6.6.4" }, "peerDependencies": { "vue": "^3.2.0" } }, "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw=="],
"vue3-toastify": ["vue3-toastify@0.2.8", "", { "peerDependencies": { "vue": ">=3.2.0" }, "optionalPeers": ["vue"] }, "sha512-8jDOqsJaBZEbGpCbhWDETJc11D1lZefvgFPq/IPdM+U7+qyXoVPDvK6uq/FIgyV7qV0NcNzvGBMEzjsLQqGROw=="],
"web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],

View File

@ -17,22 +17,12 @@
<p>{{ item.description }}</p>
<h4 class="h4-uppercase-bold-inter">{{ item.sub_title }}</h4>
</div>
<div
class="h-[235px] sm:h-[350px] w-full rounded-[20px] bg-cover bg-center transition-transform duration-300 group-hover:scale-105 xl:block relative"
:style="{
backgroundImage: `url('/api/public/file/${component.img[index]}_l.webp')`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}">
<div
class="hidden sm:block absolute bottom-0 right-0 pt-2 pl-2 bg-bg-light dark:bg-bg-dark rounded-tl-2xl">
<UiImgWrapper :src="`/api/public/file/${component.img[index]}_l.webp`">
<template #button>
<UiButtonArrow :arrow="true">{{ item.title }}</UiButtonArrow>
</div>
</div>
<UiButtonArrow :arrow="true" class="sm:hidden mx-auto">{{
item.title
}}</UiButtonArrow>
</template>
</UiImgWrapper>
</div>
<!-- Map block with same layout rules -->

View File

@ -10,18 +10,15 @@
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}"
/>
<div
class="flex flex-col items-center space-y-[30px] sm:flex-row sm:items-start md:space-y-0 xl:items-center"
>
}" />
<div class="flex flex-col items-center space-y-[30px] sm:flex-row sm:items-start md:space-y-0 xl:items-center">
<h3 class="h4-uppercase-bold-inter sm:min-w-[45%]">
{{ component.front_section_lang[0].data.title_second }}
</h3>
<div class="flex w-full items-start justify-center sm:justify-end">
<UiButtonArrow :arrow="true" type="fill">{{
component.front_section_lang[0].data.button
}}</UiButtonArrow>
}}</UiButtonArrow>
</div>
</div>
</div>
@ -29,22 +26,25 @@
</template>
<script lang="ts" setup>
defineProps<{ component: {
id: number
name: string
img: string[]
component_name: string
is_no_lang: boolean
page_name: string
front_section_lang: {
data: {
title: string
button: string
title_second: string
}
id_front_section: number
id_lang: number
}[]
} }>();
defineProps<{
component: {
id: number
name: string
img: string[]
component_name: string
is_no_lang: boolean
page_name: string
front_section_lang: {
data: {
title: string
button: string
title_second: string
}
id_front_section: number
id_lang: number
}[]
}
}>();
</script>

View File

@ -1,41 +1,26 @@
<template>
<div
class="group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap"
>
<button
:class="[
'h-[40px] cursor-pointer rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: type === 'border'
<div class="group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap">
<button :class="[
'h-[40px] cursor-pointer min-w-40 rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: type === 'border'
? 'border-button text-button group-hover:border-button-hover group-hover:text-button-hover border'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
full && 'w-full'
]"
>
full && 'w-full'
]">
<slot />
</button>
<div
v-if="arrow"
:class="[
'flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
]"
>
<svg
class=""
width="26"
height="26"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<div v-if="arrow" :class="[
'flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px]',
type === 'fill'
? 'bg-button text-text-dark group-hover:bg-button-hover'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
]">
<svg class="" width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z"
fill="currentColor"
/>
fill="currentColor" />
</svg>
</div>
</div>

View File

@ -0,0 +1,29 @@
<template>
<div class="hidden md:block">
<svg width="100%" height="100%" viewBox="0 0 870 350" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="customClip">
<path
d="M20 0.5H847.666C858.366 0.5 867.067 9.12193 867.165 19.8213L869.315 254.821C869.415 265.66 860.656 274.5 849.816 274.5H653C641.678 274.5 632.5 283.678 632.5 295V330C632.5 340.77 623.77 349.5 613 349.5H20C9.23045 349.5 0.5 340.77 0.5 330V20C0.5 9.23045 9.23045 0.5 20 0.5Z" />
</clipPath>
</defs>
<image :href="src" clip-path="url(#customClip)" preserveAspectRatio="xMidYMid slice" width="100%"
height="100%" />
<foreignObject x="640" y="280" width="calc(100% - 640px - 1px)" height="calc(100% - 280px)">
<slot name="button"></slot>
</foreignObject>
</svg>
</div>
<div class="block md:hidden">
<img :src="src" width="100%" height="100%" class="object-contain rounded-2xl my-4" />
<div class="flex justify-center">
<slot name="button"></slot>
</div>
</div>
</template>
<script lang="ts" setup>
defineProps<{ src: string }>()
</script>

View File

@ -53,6 +53,7 @@ export default defineNuxtConfig({
ignored: ["**/backend/pb_data/**"],
},
hmr: {
host: "127.0.0.1",
clientPort: 3000, // useful if proxying
},
},

View File

@ -17,6 +17,7 @@
"@pinia/nuxt": "^0.11.0",
"@tailwindcss/vite": "^4.1.8",
"@vueuse/core": "^13.3.0",
"gsap": "^3.13.0",
"nuxt": "^3.17.4",
"tailwindcss": "^4.1.7",
"vue": "^3.5.14",

View File

@ -6,6 +6,66 @@
</template>
<script setup>
import { gsap } from 'gsap'
import ScrollTrigger from 'gsap/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger)
watch(useColorMode(), (color) => {
console.log(color);
})
onMounted(() => {
const anim = gsap.fromTo(
'h1',
{
opacity: 0,
zoom: 0.95
},
{
opacity: 1,
duration: 1,
zoom: 1,
ease: 'power2.out',
}
)
ScrollTrigger.create({
trigger: 'h1',
start: 'top 80%',
onEnter: () => anim.restart(), // play when scrolling down
onEnterBack: () => anim.restart(), // play again when scrolling up
})
const animh2 = gsap.fromTo(
'h2',
{
opacity: 0,
color: 'var(--color-accent-green-light)',
},
{
opacity: 1,
duration: 1,
ease: 'power2.out',
}
)
ScrollTrigger.create({
trigger: 'h2',
start: 'top 80%',
onEnter: () => animh2.restart(), // play when scrolling down
onEnterBack: () => animh2.restart(), // play again when scrolling up
})
})
const route = useRoute();
const store = useStore();
const menuStore = useMenuStore();