我有一个标志的SVG,当滚动时,从全名切换到只有首字母。它位于一个容器div中,有一个彩色背景,也应该相应地改变大小。到目前为止,我已经能够将额外的字符动画化,并将首字母移动到正确的空间,但我在如何更新/动画化容器div的大小方面遇到了问题。
我有它目前的工作使用GSAP,但我们切换到成帧运动。这有点难以解释,所以这里是当前的工作版本:https://pixelbakery.com/about(我希望允许链接)
注意:我们使用Tailwind作为我们的样式框架。
我现在的代码:
1.你可以忽略这一部分-这是我如何计算滚动位置。我添加它只是为了以防你想要一些 prop 的额外上下文:
const [isHamActive, setHamToggle] = useState(false)
const [windowHeight, setwindowHeight] = useState(0)
const [showNavBar, setShowNavBar] = useState(true)
const [scrollPosition, setScrollPosition] = useState(0)
function handleShowNavBar() {
if (scrollPosition + 1 >= windowHeight / 3) setShowNavBar(false)
else setShowNavBar(true)
}
// Create a window resize event listener
useEffect(() => {
setwindowHeight(window.innerHeight)
const handleWindowResize = () => {
setwindowHeight(window.innerHeight)
handleShowNavBar()
}
window.addEventListener('resize', handleWindowResize)
return () => {
window.removeEventListener('resize', handleWindowResize)
handleShowNavBar()
}
}, [])
// Create a scroll event listener, and call handleShowNavBar
useEffect(() => {
setScrollPosition(window.scrollY + 1)
handleShowNavBar()
const handleScroll = () => {
const position = window.scrollY + 1
setScrollPosition(position)
handleShowNavBar()
}
window.addEventListener('scroll', handleScroll, { passive: true })
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [scrollPosition])
1.父组件/完整导航栏
import { motion, Variants } from 'framer-motion'
import Nav_Logo from './Nav_Logo'
export default function Navbar() {
const navItem: Variants = {
offscreen: (delay) => ({
y: -300,
transition: {
ease: 'easeOut',
duration: 1,
delay: delay,
},
}),
onscreen: (delay) => ({
y: 0,
transition: {
ease: 'easeOut',
duration: 1,
delay: delay,
},
}),
}
return (
<>
<motion.div initial='offscreen' className={'z-40 '}>
<motion.div
initial={'offscreen'}
animate={'onscreen'}
variants={navItem}
custom={0.3}
className='navItem origin-top-left ml-8 mt-8 fixed top-0 left-0 z-40 '
>
<div className='bg-cream rounded-md origin-top-left hidden xl:block '>
<Link
hrefLang={'en-US'}
href={'/'}
className=' pointer-events-auto block relative min-w-full z-40 px-4 pt-3 my-0 w-full'
>
<Nav_Logo showNavBar={showNavBar} />
</Link>
</div>
</motion.div>
</motion.div>
</>
)
}
1.下面是SVG徽标组件
import { Variants, motion } from "framer-motion";
const fadeAway: Variants = {
hide: (delay) => ({
opacity: 0,
transition: {
ease: "easeOut",
duration: 1,
delay: delay,
},
}),
show: (delay) => ({
opacity: 1,
transition: {
ease: "easeOut",
duration: 1,
delay: delay,
},
}),
};
const Nav_Logo = ({ showNavBar }) => {
return (
<motion.svg
xmlns='http://www.w3.org/2000/svg'
version='1.1'
id='Logo_Wordmark'
viewBox='0 0 494 138'
width={"100%"}
preserveAspectRatio='xMaxYMin meet'
>
{/* P */}
<motion.path d='...' />
{/* IXEL */}
<motion.g
variants={fadeAway}
animate={showNavBar ? "show" : "hide"}
> ... </motion.g>
{/* B */}
<motion.path
animate={showNavBar ? {{x: 0}} : {{x: -140}}
d='...'
/>
{/* AKERY */}
<motion.g
variants={fadeAway}
animate={showNavBar ? "show" : "hide"}
>
...
</motion.g>
{/* D */}
<motion.path
animate={showNavBar ? {{scale: 1}} : {{scale: 1.4, y:-10}}
...
/>
{/* ESIGN */}
<motion.g
variants={fadeAway}
animate={showNavBar ? "show" : "hide"}
>
...
</motion.g>
{/* S */}
<motion.path
animate={showNavBar ? {{scale: 1}} : {{scale: 1.4, y:-10}}}
p='...'
/>
{/* TUDIO */}
<motion.g
variants={fadeAway}
animate={showNavBar ? "show" : "hide"}
>
...
</motion.g>
</motion.svg>
)
}
export default Nav_Logo;
改变视框大小是最好的方法吗?
1条答案
按热度按时间2uluyalo1#
我不知道这是否有用,但它很有趣。你不能对SVG的viewBox进行动画处理,但是如果你删除了它,CSS中的所有值都将引用上下文文档。这里我切换SVG上的样式
small
。