微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 div 渲染元素位置绝对,顶部,右侧,底部,左侧,获取 de screenPositions 以知道在哪里渲染如何听滚动?

如何解决使用 div 渲染元素位置绝对,顶部,右侧,底部,左侧,获取 de screenPositions 以知道在哪里渲染如何听滚动?

我正在用 Craft.js 构建一个 FrontPage 构建器。您可以将组件滑动到 Frame 组件中以将它们添加到您的页面中,如下所示。

<Editor onRender={SettingsBarHover}><Frame>{useComponents}</Frame></Editor>

编辑器有一个 onRender 属性,它提供了使用附加组件渲染框架内的每个 useComponent 的可能性。

我想使用 SettingsBarHover 渲染它,当组件被选中或 onHover 时,它在 useComponent 顶部可见。类似于下面的示例图像:

enter image description here

一切正常,直到我滚动页面。怎么弄?有一个例子,但它是使用 TypeScript 的,当我看到所有代码并寻找一个简单的解释时,我感到困惑:

整个应用程序: https://github.com/prevwong/craft.js/tree/master/packages/examples/landing

and 组件在哪里: https://github.com/prevwong/craft.js/blob/master/packages/examples/landing/pages/index.tsx

RenderNode 组件在哪里: https://github.com/prevwong/craft.js/blob/master/packages/examples/landing/pages/index.tsx

这是我的代码

  1. 我的编辑器和框架组件在哪里
  2. 我的渲染节点

import React from "react";
import { Typography,Paper } from "@material-ui/core";
import { TopbarBuild } from "./EditorComponents/TopbarBuild";
import ContainerBuild from "./UserComponents/ContainerBuild";
import { CardBuild,CardTopBuild,CardBottomBuild } from "./UserComponents/CardBuild";
import { ButtonBuild } from "./UserComponents/ButtonBuild";
import { TextBuild } from "./UserComponents/TextBuild";
import { ToolBoxBuild } from "./EditorComponents/ToolBoxBuild";
import Card from "../Card/Card";
import CardBody from "../Card/CardBody";
import { Editor,Frame,Element } from "@craftjs/core";
import withStyles from "@material-ui/core/styles/withStyles";
import BuilderAppStyles from "../../assets/jss/material-dashboard-pro-react/components/BuilderAppStyles";
import SettingsBarHover from "./EditorComponents/SettingsBarHover";
import { PanelBuild } from "./EditorComponents/Panels/PanelBuild";
import { ButtonAfhalenBuild } from "./UserComponents/ButtonAfhalenBuild";
import { ImageBuild } from "./UserComponents/ImageBuild";

function BuilderApp({ classes }) {
  return (
    <Card>
      <CardBody>
        <div style={{ margin: "0 auto",width: "100%",height: "800px" }}>
          <Typography variant="h5" align="center">
            A super simple page editor
          </Typography>
          <TopbarBuild />
          <Editor
            resolver={{
              CardBuild,CardBottomBuild,ButtonBuild,ButtonAfhalenBuild,TextBuild,ImageBuild,ContainerBuild,}}
            onRender={SettingsBarHover}
            enabled={true}
          >
            <div style={{ display: "flex",direction: "row" }}>
              <div style={{ display: "inline",width: "5%" }}>
                <Paper square>
                  <ToolBoxBuild />
                </Paper>
              </div>
              <div className={"craftjs-renderer"} style={{ display: "inline",width: "75%" }}>
                <Paper square>
                  <Frame>
                    <Element
                      canvas
                      is={ContainerBuild}
                      name={"Page"}
                      height={"600px"}
                      flexDirection={"row"}
                      backgroundImage={"true"}
                      imageSource={"https://www.leza.nl/wp-content/uploads/2019/10/Jamezz-mobiel.jpg"}
                    />
                  </Frame>
                </Paper>
              </div>
              <div style={{ display: "inline",width: "20%" }}>
                <PanelBuild />
              </div>
            </div>
          </Editor>
        </div>
      </CardBody>
    </Card>
  );
}

export default withStyles(BuilderAppStyles)(BuilderApp);

import React,{ useCallback,useEffect,useRef } from "react";
import BuilderAppStyles from "../../../assets/jss/material-dashboard-pro-react/components/BuilderAppStyles";
import withStyles from "@material-ui/core/styles/withStyles";
import Grid from "@material-ui/core/Grid";
import { Tooltip } from "@material-ui/core";
import EditIcon from "@material-ui/icons/Edit";
import LayersIcon from "@material-ui/icons/Layers";
import DeleteForeverIcon from "@material-ui/icons/DeleteForever";
import Divider from "@material-ui/core/Divider";
import DragIndicatorIcon from "@material-ui/icons/DragIndicator";
import { useEditor,useNode } from "@craftjs/core";

const SettingsBarHover = ({ render }) => {
  const { actions,selected } = useEditor((state,query) => {
    const currentNodeId = state.events.selected;
    let selected;
    if (currentNodeId) {
      selected = {
        id: currentNodeId,name: state.nodes[currentNodeId].data.props.name,settings: state.nodes[currentNodeId].related && state.nodes[currentNodeId].related.settings,isDeletable: query.node(currentNodeId).isDeletable(),descendants: query.node(currentNodeId).descendants(),};
    }
    return {
      selected,};
  });
  const { id,isActive,isHover,dom } = useNode((node) => ({
    isActive: node.events.selected,isHover: node.events.hovered,dom: node.dom,}));

  // const currentRef = React.createRef(HTMLdivelement);

  const getPos = useCallback((dom) => {
    const { top,left,bottom } = dom ? dom.getBoundingClientRect() : { top: 0,left: 0,bottom: 0 };
    return {
      top: `${top > 0 ? top : bottom}px`,left: `${left}px`,};
  },[]);

  const scroll = useCallback(() => {
    // const { current: currentDOM } = currentRef;
    // if (!currentDOM) return;
    // const { top,left } = getPos(dom);
    // currentDOM.style.top = top;
    // currentDOM.style.left = left;
  },[dom]);

  useEffect(() => {
    window.addEventListener("scroll",scroll);

    return () => {
      window.removeEventListener("scroll",scroll);
    };
  },[scroll]);

  return (
    <>
      {isActive && (
        <div style={{ position: "absolute",...getPos(dom) }}>
          <Grid container>
            <Grid item>{selected.name}</Grid>
            <Grid item>
              <Tooltip title={"Edit"}>
                <EditIcon style={{ margin: "3px" }} onClick={() => setShowEditPanel((prevstate) => !prevstate)} />
              </Tooltip>
            </Grid>
            <Grid item>
              <LayersIcon style={{ margin: "3px" }} onClick={() => setShowLayersPanel((prevstate) => !prevstate)} />
            </Grid>
            {selected.isDeletable && (
              <Grid item>
                <DeleteForeverIcon
                  style={{ margin: "5px" }}
                  onClick={() => {
                    console.log("onCLick");
                  }}
                />
              </Grid>
            )}
            <Divider orientation={"vertical"} flexItem />
            <Grid item>
              <Tooltip title={"Drag panel"}>
                <DragIndicatorIcon style={{ margin: "3px" }} />
              </Tooltip>
            </Grid>
          </Grid>
        </div>
      )}
      {render}
    </>
  );
};

export default withStyles(BuilderAppStyles)(SettingsBarHover);

我相信我需要使用 RefHook、listenerEvents 和 className 来标识绝对定位的 div 应该相对于的 div..?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。