Musíte změnit nastavení vašeho prohlížeče
Podívejte se na:
Jak povolit JavaScript ve vašem prohlížeči
.
Pokud používáte software na blokování reklam, může být nutné povolit JavaScript z této stránky.
Děkujeme.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookies. Více informací
zde
.
Nastavení
Odmítnout
Souhlasím
Přejít na obsah
Zpět
do obchodu
Přihlášení k vašemu účtu
Nemůžete vyplnit toto pole
Přihlásit se
Nová registrace
Zapomenuté heslo
774344594
Hledat
Přihlášení
Nákupní košík
Prázdný košík
Menu
rok
měsíc
týden
tracker
prázdné listy
desky
komplet
Obchodní podmínky
Kontakty
Přihlášení
Více
Domů
/
desky
desky
Produkty teprve připravujeme.
Můžete se ale podívat na ostatní kategorie.
Zpět do obchodu
Dárek zdarma
Ke každé objednávce
Garance doručení
nepoškozeného zboží
Přes 3000 výdejních míst
po celé ČR
Doručení do druhého dne
na jakékoliv místo
Zpět
do obchodu
Zpět
do obchodu
Co potřebujete najít?
Hledat
Doporučujeme
Následující
Předchozí
Měsíční přehled STANDALONE | BOLD
99 Kč
Měsíční přehled FLOW | BOLD
49 Kč
Roční přehled NOTES SIDE | BOLD
15 Kč
Týdenní přehled VERTICAL FLOW | BOLD
150 Kč
Týdenní přehled VERTICAL STANDALONE | BOLD
150 Kč
Týdenní přehled TIMELINE FLOW | BOLD
150 Kč
Týdenní přehled TIMELINE STANDALONE | BOLD
150 Kč
Týdenní přehled JOURNAL FLOW | BOLD
150 Kč
Týdenní přehled JOURNAL STANDALONE | BOLD
150 Kč
'use client'; import React, { useEffect, useRef } from 'react'; interface BubbleCursorProps { wrapperElement?: HTMLElement; } class Particle { lifeSpan: number; initialLifeSpan: number; velocity: { x: number; y: number }; position: { x: number; y: number }; baseDimension: number; constructor(x: number, y: number) { this.initialLifeSpan = Math.floor(Math.random() * 60 + 60); this.lifeSpan = this.initialLifeSpan; this.velocity = { x: (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 10), y: -0.4 + Math.random() * -1, }; this.position = { x, y }; this.baseDimension = 4; } update(context: CanvasRenderingContext2D) { this.position.x += this.velocity.x; this.position.y += this.velocity.y; this.velocity.x += ((Math.random() < 0.5 ? -1 : 1) * 2) / 75; this.velocity.y -= Math.random() / 600; this.lifeSpan--; const scale = 0.2 + (this.initialLifeSpan - this.lifeSpan) / this.initialLifeSpan; context.fillStyle = '#e6f1f7'; context.strokeStyle = '#3a92c5'; context.beginPath(); context.arc( this.position.x - (this.baseDimension / 2) * scale, this.position.y - this.baseDimension / 2, this.baseDimension * scale, 0, 2 * Math.PI ); context.stroke(); context.fill(); context.closePath(); } } const BubbleCursor: React.FC
= ({ wrapperElement }) => { const canvasRef = useRef
(null); const particlesRef = useRef
([]); const cursorRef = useRef({ x: 0, y: 0 }); const animationFrameRef = useRef
(null); useEffect(() => { const prefersReducedMotion = window.matchMedia( '(prefers-reduced-motion: reduce)' ); let canvas: HTMLCanvasElement | null = null; let context: CanvasRenderingContext2D | null = null; let width = window.innerWidth; let height = window.innerHeight; const init = () => { if (prefersReducedMotion.matches) { console.log( 'This browser has prefers reduced motion turned on, so the cursor did not init' ); return false; } canvas = canvasRef.current; if (!canvas) return; context = canvas.getContext('2d'); if (!context) return; canvas.style.top = '0px'; canvas.style.left = '0px'; canvas.style.pointerEvents = 'none'; if (wrapperElement) { canvas.style.position = 'absolute'; wrapperElement.appendChild(canvas); canvas.width = wrapperElement.clientWidth; canvas.height = wrapperElement.clientHeight; } else { canvas.style.position = 'fixed'; document.body.appendChild(canvas); canvas.width = width; canvas.height = height; } bindEvents(); loop(); }; const bindEvents = () => { const element = wrapperElement || document.body; element.addEventListener('mousemove', onMouseMove); element.addEventListener('touchmove', onTouchMove, { passive: true }); element.addEventListener('touchstart', onTouchMove, { passive: true }); window.addEventListener('resize', onWindowResize); }; const onWindowResize = () => { width = window.innerWidth; height = window.innerHeight; if (!canvasRef.current) return; if (wrapperElement) { canvasRef.current.width = wrapperElement.clientWidth; canvasRef.current.height = wrapperElement.clientHeight; } else { canvasRef.current.width = width; canvasRef.current.height = height; } }; const onTouchMove = (e: TouchEvent) => { if (e.touches.length > 0) { for (let i = 0; i < e.touches.length; i++) { addParticle(e.touches[i].clientX, e.touches[i].clientY); } } }; const onMouseMove = (e: MouseEvent) => { if (wrapperElement) { const boundingRect = wrapperElement.getBoundingClientRect(); cursorRef.current.x = e.clientX - boundingRect.left; cursorRef.current.y = e.clientY - boundingRect.top; } else { cursorRef.current.x = e.clientX; cursorRef.current.y = e.clientY; } addParticle(cursorRef.current.x, cursorRef.current.y); }; const addParticle = (x: number, y: number) => { particlesRef.current.push(new Particle(x, y)); }; const updateParticles = () => { if (!canvas || !context) return; if (particlesRef.current.length === 0) { return; } context.clearRect(0, 0, canvas.width, canvas.height); // Update for (let i = 0; i < particlesRef.current.length; i++) { particlesRef.current[i].update(context); } // Remove dead particles for (let i = particlesRef.current.length - 1; i >= 0; i--) { if (particlesRef.current[i].lifeSpan < 0) { particlesRef.current.splice(i, 1); } } if (particlesRef.current.length === 0) { context.clearRect(0, 0, canvas.width, canvas.height); } }; const loop = () => { updateParticles(); animationFrameRef.current = requestAnimationFrame(loop); }; init(); return () => { if (canvas) { canvas.remove(); } if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } const element = wrapperElement || document.body; element.removeEventListener('mousemove', onMouseMove); element.removeEventListener('touchmove', onTouchMove); element.removeEventListener('touchstart', onTouchMove); window.removeEventListener('resize', onWindowResize); }; }, [wrapperElement]); return
; }; export default BubbleCursor;