问题描述
我正在用 Craft.js 构建一个 FrontPage 构建器。您可以将组件滑动到 Frame 组件中以将它们添加到您的页面中,如下所示。
<Editor onRender={SettingsBarHover}><Frame>{useComponents}</Frame></Editor>
编辑器有一个 onRender 属性,它提供了使用附加组件渲染框架内的每个 useComponent 的可能性。
我想使用 SettingsBarHover 渲染它,当组件被选中或 onHover 时,它在 useComponent 顶部可见。类似于下面的示例图像:
一切正常,直到我滚动页面。怎么弄?有一个例子,但它是使用 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
这是我的代码:
- 我的编辑器和框架组件在哪里
- 我的渲染节点
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 (将#修改为@)