Fix iframe interactivity

This commit is contained in:
Ruslan Bakiev
2026-02-10 15:56:17 +07:00
parent 86886a62cb
commit 7909b7bf1c

View File

@@ -1,6 +1,6 @@
<template> <template>
<div data-theme="silk" class="min-h-screen bg-mesh text-neutral"> <div data-theme="silk" class="min-h-screen bg-mesh text-neutral">
<canvas id="gradient-canvas" class="gradient-canvas" aria-hidden="true"></canvas> <canvas id="canvas-basic" class="gradient-canvas" aria-hidden="true"></canvas>
<div class="relative z-10"> <div class="relative z-10">
<div <div
class="pointer-events-none absolute -top-24 left-1/2 h-72 w-[1100px] -translate-x-1/2 rounded-full bg-[radial-gradient(circle_at_center,rgba(67,56,118,0.25),transparent_70%)] blur-3xl" class="pointer-events-none absolute -top-24 left-1/2 h-72 w-[1100px] -translate-x-1/2 rounded-full bg-[radial-gradient(circle_at_center,rgba(67,56,118,0.25),transparent_70%)] blur-3xl"
@@ -9,7 +9,7 @@
<main class="relative px-6 pb-16 pt-10 md:px-12 lg:px-20"> <main class="relative px-6 pb-16 pt-10 md:px-12 lg:px-20">
<div class="grid gap-8 lg:grid-cols-[220px_1fr]"> <div class="grid gap-8 lg:grid-cols-[220px_1fr]">
<aside class="hidden lg:block"> <aside class="hidden lg:block">
<div class="sticky top-10 rounded-3xl border border-base-300 bg-base-100/90 p-5 shadow-soft"> <div class="glass-panel sticky top-10 rounded-3xl border border-base-300 bg-base-100/90 p-5 shadow-soft">
<div class="text-xs uppercase tracking-[0.2em] text-neutral/50">Навигация</div> <div class="text-xs uppercase tracking-[0.2em] text-neutral/50">Навигация</div>
<nav class="mt-4 space-y-2 text-sm"> <nav class="mt-4 space-y-2 text-sm">
<a class="nav-link block rounded-2xl px-3 py-2 text-neutral/70 border border-transparent" href="#context">Контекст</a> <a class="nav-link block rounded-2xl px-3 py-2 text-neutral/70 border border-transparent" href="#context">Контекст</a>
@@ -90,7 +90,7 @@
</p> </p>
</div> </div>
<div class="slide-main"> <div class="slide-main">
<div class="glass-card rounded-3xl border border-base-300 bg-base-100/90 p-6"> <div class="glass-panel rounded-3xl border border-base-300 bg-base-100/90 p-6">
<div class="text-xs font-semibold text-neutral/60">Пример регламентной приемки</div> <div class="text-xs font-semibold text-neutral/60">Пример регламентной приемки</div>
<div class="mt-4 grid grid-cols-[1.1fr_1.3fr_0.9fr_1fr] gap-3 text-sm"> <div class="mt-4 grid grid-cols-[1.1fr_1.3fr_0.9fr_1fr] gap-3 text-sm">
<div class="rounded-2xl bg-base-200 px-4 py-3 font-semibold text-neutral/70">Работа</div> <div class="rounded-2xl bg-base-200 px-4 py-3 font-semibold text-neutral/70">Работа</div>
@@ -204,7 +204,7 @@
class="iphone-iframe" class="iphone-iframe"
title="Прототип пользовательского пути" title="Прототип пользовательского пути"
:srcdoc="prototypeSrcdoc" :srcdoc="prototypeSrcdoc"
sandbox="allow-scripts" sandbox="allow-scripts allow-same-origin"
></iframe> ></iframe>
</div> </div>
</div> </div>
@@ -222,7 +222,7 @@
</p> </p>
</div> </div>
<div class="slide-main"> <div class="slide-main">
<div class="glass-card relative overflow-hidden rounded-3xl border border-base-300 bg-base-100/90 p-8"> <div class="glass-panel relative overflow-hidden rounded-3xl border border-base-300 bg-base-100/90 p-8">
<div class="pointer-events-none absolute -left-16 top-10 h-36 w-36 rounded-full bg-primary/15 blur-3xl"></div> <div class="pointer-events-none absolute -left-16 top-10 h-36 w-36 rounded-full bg-primary/15 blur-3xl"></div>
<div class="pointer-events-none absolute -right-10 bottom-0 h-40 w-40 rounded-full bg-secondary/20 blur-3xl"></div> <div class="pointer-events-none absolute -right-10 bottom-0 h-40 w-40 rounded-full bg-secondary/20 blur-3xl"></div>
<div class="relative grid gap-6 md:grid-cols-3"> <div class="relative grid gap-6 md:grid-cols-3">
@@ -305,7 +305,7 @@
</p> </p>
</div> </div>
<div class="slide-main"> <div class="slide-main">
<div class="glass-card rounded-3xl border border-base-300 bg-base-100/90 p-6"> <div class="glass-panel rounded-3xl border border-base-300 bg-base-100/90 p-6">
<div class="grid gap-4 text-sm"> <div class="grid gap-4 text-sm">
<div class="grid grid-cols-6 gap-2 text-xs text-neutral/50"> <div class="grid grid-cols-6 gap-2 text-xs text-neutral/50">
<div>М1</div> <div>М1</div>
@@ -913,62 +913,21 @@ let granimInstance
onMounted(() => { onMounted(() => {
granimInstance = new Granim({ granimInstance = new Granim({
element: '#gradient-canvas', element: '#canvas-basic',
direction: 'diagonal', direction: 'radial',
isPausedWhenNotInView: true, isPausedWhenNotInView: true,
states: { states: {
'default-state': { 'default-state': {
gradients: [ gradients: [
['#6E4BCF', '#F0C16F', '#78C5B7'], ['#ff9966', '#ff5e62'],
['#5A3C9D', '#F5B4D1', '#8FCBFF'], ['#00F260', '#0575E6'],
['#9A6CFF', '#F2D08A', '#6EE7C5'], ['#e1eec3', '#f05053']
['#4E72D7', '#F1A17E', '#A6E3A1'] ]
],
transitionSpeed: 4200
} }
} }
}) })
const root = document.documentElement
let currentX = 0
let currentY = 0
let targetX = 0
let targetY = 0
let rafId = 0
const setVars = (x, y) => {
root.style.setProperty('--gx', `${x}`)
root.style.setProperty('--gy', `${y}`)
root.style.setProperty('--grot', `${x * 8}deg`)
}
const handleMove = (event) => {
targetX = (event.clientX / window.innerWidth - 0.5) * 2
targetY = (event.clientY / window.innerHeight - 0.5) * 2
}
const handleTouch = (event) => {
if (!event.touches.length) return
const touch = event.touches[0]
targetX = (touch.clientX / window.innerWidth - 0.5) * 2
targetY = (touch.clientY / window.innerHeight - 0.5) * 2
}
const animate = () => {
currentX += (targetX - currentX) * 0.03
currentY += (targetY - currentY) * 0.03
setVars(currentX, currentY)
rafId = requestAnimationFrame(animate)
}
window.addEventListener('mousemove', handleMove)
window.addEventListener('touchmove', handleTouch, { passive: true })
rafId = requestAnimationFrame(animate)
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('mousemove', handleMove)
window.removeEventListener('touchmove', handleTouch)
cancelAnimationFrame(rafId)
if (granimInstance && granimInstance.pause) granimInstance.pause() if (granimInstance && granimInstance.pause) granimInstance.pause()
}) })
}) })
@@ -979,11 +938,6 @@ onMounted(() => {
:root { :root {
color-scheme: light; color-scheme: light;
--mx: 50%;
--my: 35%;
--dx: 0;
--dy: 0;
--rot: 0deg;
} }
body { body {
@@ -998,41 +952,26 @@ html {
font-family: 'Space Grotesk', system-ui, sans-serif; font-family: 'Space Grotesk', system-ui, sans-serif;
} }
.bg-motion { .gradient-canvas {
position: fixed; position: fixed;
inset: 0; inset: 0;
width: 100%;
height: 100%;
z-index: 0; z-index: 0;
pointer-events: none; pointer-events: none;
overflow: hidden; filter: saturate(1.1);
} }
.bg-motion::before, .nav-link {
.bg-motion::after { transition: all 0.2s ease;
content: '';
position: absolute;
inset: -10%;
background-repeat: no-repeat;
filter: blur(20px);
opacity: 0.85;
transform: translate(calc(var(--dx) * 40px), calc(var(--dy) * 40px)) rotate(var(--rot));
transition: transform 0.15s ease-out;
} }
.bg-motion::before { .nav-link:hover {
background-image: background: rgba(255, 255, 255, 0.5);
radial-gradient(600px 420px at calc(var(--mx) - 10%) calc(var(--my) + 5%), rgba(108, 78, 190, 0.35), transparent 65%), border-color: rgba(255, 255, 255, 0.6);
radial-gradient(700px 480px at calc(var(--mx) + 20%) calc(var(--my) - 10%), rgba(246, 203, 120, 0.3), transparent 70%), backdrop-filter: blur(14px) saturate(1.1);
radial-gradient(520px 380px at calc(var(--mx) + 5%) calc(var(--my) + 30%), rgba(92, 189, 165, 0.28), transparent 70%), -webkit-backdrop-filter: blur(14px) saturate(1.1);
conic-gradient(from 120deg at calc(var(--mx) + 15%) calc(var(--my) + 10%), rgba(108, 78, 190, 0.18), rgba(246, 203, 120, 0.16), rgba(92, 189, 165, 0.18), transparent 55%); color: rgba(20, 20, 20, 0.85);
}
.bg-motion::after {
background-image:
radial-gradient(820px 520px at calc(100% - var(--mx)) calc(100% - var(--my)), rgba(230, 120, 170, 0.2), transparent 70%),
radial-gradient(500px 360px at calc(var(--mx) + 35%) calc(var(--my) - 30%), rgba(120, 160, 240, 0.22), transparent 70%),
conic-gradient(from 220deg at calc(var(--mx) - 20%) calc(var(--my) + 25%), rgba(230, 120, 170, 0.18), rgba(120, 160, 240, 0.16), rgba(246, 203, 120, 0.14), transparent 60%);
mix-blend-mode: multiply;
opacity: 0.7;
} }
.slide { .slide {
@@ -1121,6 +1060,9 @@ html {
height: 100%; height: 100%;
border: 0; border: 0;
display: block; display: block;
position: relative;
z-index: 1;
pointer-events: auto;
} }
.iphone-notch { .iphone-notch {