Giter VIP home page Giter VIP logo

hello.kexie.space's Introduction

一个不像是README的文档

它更像是踩坑日记。

已经遇到过的问题

使用vercel部署,react-router跳转的页面会404

stack overflow上有相关的解决方案:Why does react-router not works at vercel?

只需要将vercel.json对应的配置文件改成这样。通过正则,让所有的路径资源的请求都到/,使路由生效。

{
    "routes": [
        {
            "src": "/[^.]+",
            "dest": "/",
            "status": 200
        }
    ]
}

小球刷新率设置

不同的显示器有不同的刷新率,使用setInterval(callback, ms),60FPS的参数是16.7ms,而144FPS的参数是7ms。在实际渲染的过程中还会出现丢帧的情况。[深入理解 requestAnimationFrame]

为了更好的适应不同显示器的帧数,使用window.requestAnimationFrame(callback)。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次。

Markdown文档解析

基础的文本用markdown-it,代码块的渲染用higtlight.js

代码在:/src/utils/markdown.ts。组件在/src/pages/Article下,样式写得非常的丑,以后有空再改。

主页评论

这个是用本仓库的issues。知道了组织名、项目名和issue编号,通过GitHub的API来获取也不难。

WebScoket

原本页面上的小球是可以在页面上发送消息的,因为没有将用户的登陆进行身份校验,也没有将用户发送的消息储存下来,所以直接砍掉了。

image

/src/hooks/useClient这个hook采用了消息订阅的方法,负责将消息转发给的不同回调。如果服务端传来的消息没有被订阅,那么这个消息将会被忽略。(这个消息订阅实现的时,只允许一个消息对应一个订阅者)

useEffect(() => {
    // 连接上服务器,服务器会主动回传。
    setDeliverier({ "hello": handleHelloAction }); 

    // 当有人连接上服务器,服务器会向其它用户发送这个消息。
    setDeliverier({ "enter": handleEnterAction }); 

    // 当有人发送消息至服务器,服务器会向所有用户广播这个的消息。
    setDeliverier({ "talk": handleTalkAction });

    // 当有人移动的行为发送至服务器,服务器会向其他用户广播这个消息。
    setDeliverier({ "move": handleMoveAction });

    // 客户端可以向服务器请求当前在线用户的信息。
    setDeliverier({ "stand up": handleStandUpAction });

    // 用户下线,服务器会向其他用户广播这个消息。
    setDeliverier({ "leave": handleLeaveAction });
}, []);

函数式组件里的回调函数里无法获取最新的state

/src/component/BallRoom里以各种handle开头的函数都有这个问题。这些回调被执行时,都获取不到最新的userList。这个问题产生的原因是闭包。

那么可以将获取的userList的方法放在ref里,这样每次这个方法都是最新的,获取到的userList也是最新的了。

function BallRoom(){
    ......
    const userListRef = useRef();
    userListRef.current = () => userList;
    ......
    // 获取的方式
    const data = userListRef.current();
}

小球的移动(父组件调用子组件内部的方法)

Ball组件是一个函数式组件,只能用hook的方法。useImperativeHandle与forwardRef

关于音乐播放器

没空,暂时搁置,所以/src/App.tsx中的组合 store 也暂时没用。而且现在的 reducer 设计非常有问题。

渐显和渐隐

用简单的话来说:

  1. 将需要增加这个特效的组件想方设法加入到 redux 里,可以使用useScrollAnimationRefs (一个自定义的hook)的第一个参数,用法与 ref 一样。如果该组件无法 ref ,那只能手动添加。/src/pages/Welcome/ContestList.tsx里只能这样。
  2. 选择一个容器组件,使用useScrollHandler(一个自定义的hook)作为监视器。

嵌入等比缩放的视频

参考博客:使用iframe嵌入等比缩放的哔哩哔哩视频

在父类中,宽度被设为100%,高度被设为0padding-bottom属性(外部下边距)被设为75%。因为当padding-bottom的值为百分比时,百分比计算的基准为父元素的宽。

这样,父类的实际宽高比(包含边距的宽高比)就变为了四比三。

于是子类宽高都100%position:relative在里边撑开就可以了。

antd design修改主题色

这个项目是从 create-react-app 迁移至 vite 的。修改主题色是用新的主题色去替换旧的主题色。(less 全局变量替换)在vue3-vite中配置less的全局变量

需要配置这两个文件。/vite.config.ts/src/theme.lessantd design配置主题

可能想问的问题

如何更换头像?

修改 local storage 中的 useravatar 字段,用其它图片的链接替代。

image

一些过程

小球相关

移动

其实单独抽离了一个 Float 组件出来,这个组件里所有子元素都能像小球一样移动。

Float是用类组件的形式写的,写得非常的丑,有空可以重构一下。

可以注意到,小球不随着滚动条的滚动二变化位置,是因为它 position:absolute;。位置的移动本质上就是 lefttop 的变化。

浏览器自带有 mousedown mousemove mouseup 这三个事件(触摸事件同理),抽象流程图如下。

image

消息显示

当有新消息到来,直接显示消息框。在5s后消息框会消失,若5s内又收到新消息,则推迟5s后再消失(防抖)。

export function debounce<T extends (...args: any[]) => void>(func: T, dalay: number) {
    let timer: any = null
    return (...args: Parameters<T>): void => {
        if (!!timer) clearTimeout(timer)
        timer = setTimeout(() => {
            func(...args)
        }, dalay)
    }
}
const delaySetContent = debounce(setContent, 5000);

位置信息的发送

如果是显示器刷新一次就向服务器发送一次的话也太夸张了,这个发送位置信息的函数在16ms内只会被执行一次(节流)。

16ms如果人少的话应该是不会卡的......卡了再往上调

export function throttle<T extends (...arg: any[]) => void>(func: T, interval: number) {
    let _args: any = null;
    let _timer: any = null;
    return (...args: Parameters<T>) => {
        _args = args;
        if (!_timer) {
            _timer = setTimeout(() => {
                func(..._args);
                _timer = null;
            }, interval);
        }
    }
}
/**
 * 拖动自己的小球,将位置信息发送至服务器
 */
const onMoving = throttle((position: Position) => {
    if (!unique) return;
    const res = { type: "move", data: position, userName: user.name };
    client.send(res);
}, 16);

挂载列表的ref

/src/component/BallRoom 有用到类似的。

const floatRefs = useRef(new Map());
function floatRef(user: AtomUser) {
    return (el) => {
        floatRefs.current.set(user.name, el);
    }
}

使用的时候,通过 current 取 Map 即可得到对应元素。

floatRefs.current.get(user.name);

跳转页面后,返回保留之前的滚动条高度

在学习方向的介绍这,点击跳转页面回来仍然是现在的高度。

image

没有把saveScrollTop写在useEffect销毁的回调中,为了更方便的自定义。

export function usePageJumpSaveScrollTop() {
    useEffect(() => {
        const scrollTop = localStorage.getItem("scrollTop");
        if (scrollTop) {
            localStorage.removeItem("scrollTop");
            document.body.scrollTop = ~~scrollTop;
        }
    }, []);

    function saveScrollTop() {
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
        localStorage.setItem("scrollTop", JSON.stringify(scrollTop));
    }

    return saveScrollTop;
}

hello.kexie.space's People

Contributors

dependabot[bot] avatar lideming avatar mirrorchilde avatar msqtt avatar onlytonight avatar taskmanagerol avatar therainisme avatar visualdust avatar wilinz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hello.kexie.space's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.