本项目的第一篇博客,近些年来做的博客系统还不少
目录
旅途开始
- 新建仓库
使用astro-paper主题
# npm 6.x
npm create astro@latest --template satnaing/astro-paper
# npm 7+, extra double-dash is needed:
npm create astro@latest -- --template satnaing/astro-paper
# yarn
yarn create astro --template satnaing/astro-paper
p5js
text
framer-motion useScroll
import "./styles.css";
import { motion, useScroll } from "framer-motion";
export default function App() {
const { scrollYProgress } = useScroll();
return (
<>
<motion.div
className="progress-bar"
style={{ scaleX: scrollYProgress }}
/>
</>
);
}
css-doodle
basic
noise
todo:这个组件会使滑动卡卡的,分析原因
import Noise from "@components/react/doodle/noise.tsx";
<Noise client:load />;
import "css-doodle";
import {
useEffect,
useState,
type ReactNode,
type ReactElement,
useRef,
} from "react";
interface Props {
children: ReactNode;
download?: Boolean;
}
const Doodle: React.FunctionComponent<Props> = ({ children, download }) => {
let value = (children as ReactElement).props.value;
let doodle = useRef<any>(null);
let [show, setShow] = useState(false);
const click = () => {
setShow(show => !show);
};
useEffect(() => {
setShow(true);
});
const downloadClick = () => {
doodle.current &&
doodle.current.export({
scale: 8,
download: true,
});
};
return (
<div>
{show && (
<css-doodle ref={doodle} onClick={click}>
{value}
</css-doodle>
)}
{download && <button onClick={downloadClick}>下载</button>}
</div>
);
};
export default Doodle;
@grid: 50x1 / 50vmin; @place: center; @size: calc(75% / @I * @i); transform: rotate(calc(@i * 5deg)); border-radius: 30%; border: 1px solid hsla( calc(10 + 4 * @i), 70%, 68%, @r.8 );
@grid: 14 / 50vmin; @random { border-left: 1px solid #5d81bc } @random { border-top: 1px solid #5d81bc; } @random(.25) { background: linear-gradient( @p(#fff, tan, #5d81bc), @lp ) 50% / @r(60%) @lr no-repeat; } @random { filter: drop-shadow(0 0 10px #fff); }
在 mdx 中使用 dooble 组件,inner children 中的’{‘需要替换成’{‘
import Common from "@components/react/doodle/common.tsx";
<Common client:load>
@grid: 14 / 50vmin;
@random \{
border-left: 1px solid #5d81bc
}
@random \{
border-top: 1px solid #5d81bc;
}
@random(.25) \{
background: linear-gradient(
@p(#fff, tan, #5d81bc), @lp
)
50% / @r(60%) @lr
no-repeat;
}
@random \{
filter: drop-shadow(0 0 10px #fff);
}
</Common>
惯性滚动
pnpm i @studio-freight/lenis
const lenis = new Lenis();
lenis.on("scroll", e => {
console.log(e);
});
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
实现原理
Lenis 是一个轻量级的 JavaScript 库,旨在实现平滑的惯性滚动效果,模拟原生滚动行为,并提供丰富的自定义选项。其核心原理是通过监听用户的滚动操作,计算目标滚动位置,并使用 requestAnimationFrame
API 来实现平滑的动画过渡。以下是具体的实现步骤:
-
监听滚动事件: Lenis 会监听用户的鼠标滚轮事件或触摸屏滑动事件,以捕捉用户的滚动操作。
-
计算目标位置: 根据用户的滚动操作和 Lenis 的配置参数(如惯性强度、滚动方向等),计算出目标滚动位置。这一过程涉及到对用户输入的处理和目标位置的动态计算。
-
启动动画循环: 使用
requestAnimationFrame
API 启动一个动画循环,这样可以确保动画在浏览器的每一帧中平滑执行。 -
更新滚动位置: 在每一帧动画中,根据当前位置和目标位置之间的差值,计算出一个新的滚动位置,并使用
scrollTo
方法更新页面的滚动位置。 -
平滑过渡: Lenis 使用 easing 函数来控制动画的过渡效果,使得滚动体验更加平滑自然。通过调整 easing 函数,开发者可以自定义滚动的感觉。
-
停止动画循环: 当滚动位置到达目标位置或用户进行新的滚动操作时,停止动画循环。这可以通过检测用户的输入来实现。
以下是一个核心代码示例,展示了如何初始化 Lenis 并启动动画循环:
// 初始化 Lenis 实例
const lenis = new Lenis({
duration: 1.2, // 滚动动画持续时间
easing: t => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // 自定义 easing 函数
});
// 监听滚动事件
lenis.on("scroll", () => {
// 获取当前滚动位置
const scroll = lenis.scroll;
// 执行其他操作,例如更新页面元素的位置
});
// 启动动画循环
function raf(time) {
lenis.raf(time); // 更新 Lenis 实例
requestAnimationFrame(raf); // 请求下一帧
}
requestAnimationFrame(raf); // 启动动画循环
通过以上步骤和代码示例,Lenis 实现了流畅的惯性滚动效果,提升了用户在网页上的滚动体验。
Remark 和 Rehype
Remark 和 Rehype 都是用于将 Markdown 转换为 HTML 的工具.
Remark 是一个基于 Node.js 的 Markdown 解析器,它将 Markdown 文本解析为 HTML.它支持插件系统,允许用户自定义解析过程.Remark 通常用于生成静态站点,例如博客或文档.
Rehype 是一个基于 Remark 的工具,它提供了额外的功能,例如代码高亮、表格和引用.Rehype 支持多种语言,包括 JavaScript、Python、CSS 和 HTML.Rehype 通常与 Remark 一起使用,以便在解析 Markdown 时应用额外的功能.
例如rehype-autolink-headings is a rehype plugin to add links from headings back to themselves.
下学
人可用功的功夫称之为下学,此功夫在可见,可闻,可言,可思处
update astro to 4.12
允许你结合高性能静态HTML和动态服务器生成组件,可以为不同类型的内容选择不同的缓存策略,并提高页面加载速度