mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2026-01-06 19:58:10 +00:00
🆕编辑器添加一键生成H5分享海报图功能 | The editor adds a one-click build H5 share poster chart feature
This commit is contained in:
parent
c27ca0cccd
commit
c98dc26094
@ -11,9 +11,9 @@ export default defineConfig({
|
||||
devtool: 'source-map',
|
||||
antd: {},
|
||||
title: '趣谈前端-h5-dooring',
|
||||
exportStatic: {},
|
||||
// exportStatic: {},
|
||||
base: '/',
|
||||
publicPath: './',
|
||||
publicPath: '/',
|
||||
outputPath: 'dist',
|
||||
esbuild: {},
|
||||
routes: [
|
||||
|
||||
40
dist/editor/index.html
vendored
40
dist/editor/index.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
href="http://io.nainor.com/uploads/logo_1742fd359da.png"
|
||||
rel="shortcut icon"
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="H5,HTML5,javascript,react,nodejs,前端开发,github,开源"
|
||||
/>
|
||||
<meta name="author" content="徐小夕" />
|
||||
<!-- <meta name="robots" content="noindex, nofollow"> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.2.23
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
40
dist/help/index.html
vendored
40
dist/help/index.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
href="http://io.nainor.com/uploads/logo_1742fd359da.png"
|
||||
rel="shortcut icon"
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="H5,HTML5,javascript,react,nodejs,前端开发,github,开源"
|
||||
/>
|
||||
<meta name="author" content="徐小夕" />
|
||||
<!-- <meta name="robots" content="noindex, nofollow"> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.2.23
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
40
dist/ide/index.html
vendored
40
dist/ide/index.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
href="http://io.nainor.com/uploads/logo_1742fd359da.png"
|
||||
rel="shortcut icon"
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="H5,HTML5,javascript,react,nodejs,前端开发,github,开源"
|
||||
/>
|
||||
<meta name="author" content="徐小夕" />
|
||||
<!-- <meta name="robots" content="noindex, nofollow"> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.2.23
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
6
dist/index.html
vendored
6
dist/index.html
vendored
@ -8,7 +8,7 @@
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<title>H5编辑器之神-Dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
@ -24,7 +24,7 @@
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<link rel="stylesheet" href="/umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
@ -35,6 +35,6 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
<script src="/umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
40
dist/login/index.html
vendored
40
dist/login/index.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
href="http://io.nainor.com/uploads/logo_1742fd359da.png"
|
||||
rel="shortcut icon"
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="H5,HTML5,javascript,react,nodejs,前端开发,github,开源"
|
||||
/>
|
||||
<meta name="author" content="徐小夕" />
|
||||
<!-- <meta name="robots" content="noindex, nofollow"> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.2.23
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
40
dist/mobileTip/index.html
vendored
40
dist/mobileTip/index.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
href="http://io.nainor.com/uploads/logo_1742fd359da.png"
|
||||
rel="shortcut icon"
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="H5,HTML5,javascript,react,nodejs,前端开发,github,开源"
|
||||
/>
|
||||
<meta name="author" content="徐小夕" />
|
||||
<!-- <meta name="robots" content="noindex, nofollow"> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.2.23
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
2
dist/p__editor.js.map
vendored
2
dist/p__editor.js.map
vendored
File diff suppressed because one or more lines are too long
40
dist/preview/index.html
vendored
40
dist/preview/index.html
vendored
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
href="http://io.nainor.com/uploads/logo_1742fd359da.png"
|
||||
rel="shortcut icon"
|
||||
type="image/vnd.microsoft.icon"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>趣谈前端-h5-dooring</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="H5,HTML5,javascript,react,nodejs,前端开发,github,开源"
|
||||
/>
|
||||
<meta name="author" content="徐小夕" />
|
||||
<!-- <meta name="robots" content="noindex, nofollow"> -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link
|
||||
href="https://cdn.bootcdn.net/ajax/libs/spinkit/2.0.1/spinkit.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="./umi.css" />
|
||||
<script>
|
||||
window.routerBase = "/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.2.23
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script src="./umi.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
443
dist/umi.js
vendored
443
dist/umi.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/umi.js.map
vendored
2
dist/umi.js.map
vendored
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
import React, { useRef, memo, useMemo, useContext, useState, useEffect } from 'react';
|
||||
import { Button, Input, Modal, Select, Upload } from 'antd';
|
||||
import { Button, Input, Modal, Select, Upload, Tooltip, Badge } from 'antd';
|
||||
import {
|
||||
ArrowLeftOutlined,
|
||||
MobileOutlined,
|
||||
@ -12,6 +12,7 @@ import {
|
||||
CodeOutlined,
|
||||
SketchOutlined,
|
||||
UploadOutlined,
|
||||
InstagramOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { history } from 'umi';
|
||||
import QRCode from 'qrcode.react';
|
||||
@ -38,6 +39,8 @@ interface HeaderComponentProps {
|
||||
const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
const { pointData, location, clearData, undohandler, redohandler, importTpl } = props;
|
||||
const [showModalIframe, setShowModalIframe] = useState(false);
|
||||
const [showFaceModal, setShowFaceModal] = useState(false);
|
||||
const [faceUrl, setFaceUrl] = useState('');
|
||||
const iptRef = useRef<Input>(null);
|
||||
|
||||
const toPreview = () => {
|
||||
@ -205,6 +208,18 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
[],
|
||||
);
|
||||
|
||||
const generatePoster = () => {
|
||||
localStorage.setItem('pointData', JSON.stringify(pointData));
|
||||
setShowModalIframe(true);
|
||||
setTimeout(() => {
|
||||
setShowFaceModal(true);
|
||||
}, 3600);
|
||||
};
|
||||
|
||||
const handleReloadPage = () => {
|
||||
document.getElementById('previewPage').contentWindow.location.reload();
|
||||
};
|
||||
|
||||
const { setTheme } = useContext(dooringContext);
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
@ -288,6 +303,18 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
<Button type="link" style={{ marginRight: '9px' }} title="重做" onClick={redohandler}>
|
||||
<RedoOutlined />
|
||||
</Button>
|
||||
<Tooltip placement="bottom" title="一键生成海报分享图">
|
||||
<Badge dot offset={[-18, 10]}>
|
||||
<Button
|
||||
type="link"
|
||||
style={{ marginRight: '6px' }}
|
||||
onClick={generatePoster}
|
||||
disabled={!pointData.length}
|
||||
>
|
||||
<InstagramOutlined />
|
||||
</Button>
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
<Button type="link" onClick={toPreview} disabled={!pointData.length}>
|
||||
预览
|
||||
</Button>
|
||||
@ -323,19 +350,31 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
</Button>
|
||||
</div>
|
||||
<Modal
|
||||
title="正在生成封面..."
|
||||
title="生成封面中...(长时间未反应请点右侧按钮重试)"
|
||||
visible={showModalIframe}
|
||||
footer={null}
|
||||
width={420}
|
||||
closable={false}
|
||||
width={414}
|
||||
closeIcon={<RedoOutlined />}
|
||||
destroyOnClose={true}
|
||||
onCancel={handleReloadPage}
|
||||
maskClosable={false}
|
||||
>
|
||||
<iframe
|
||||
title="editor"
|
||||
src={`/h5_plus/preview?tid=${props.location.query.tid}&gf=1`}
|
||||
id="previewPage"
|
||||
src={`/preview?tid=${props.location.query.tid}&gf=1`}
|
||||
style={{ width: '100%', border: 'none', height: '600px' }}
|
||||
></iframe>
|
||||
</Modal>
|
||||
<Modal
|
||||
title="封面图(右键复制图片)"
|
||||
visible={showFaceModal}
|
||||
footer={null}
|
||||
width={414}
|
||||
destroyOnClose={true}
|
||||
onCancel={() => setShowFaceModal(false)}
|
||||
>
|
||||
<img src={faceUrl} style={{ width: '100%' }} />
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@ -6,6 +6,7 @@ import req from '@/utils/req';
|
||||
import styles from './index.less';
|
||||
import { useGetScrollBarWidth } from '@/utils/tool';
|
||||
import { LocationDescriptorObject } from 'history-with-query';
|
||||
|
||||
const isMac = navigator.platform.indexOf('Mac') === 0;
|
||||
|
||||
interface PreviewPageProps {
|
||||
@ -33,20 +34,38 @@ const PreviewPage = memo((props: PreviewPageProps) => {
|
||||
}));
|
||||
});
|
||||
|
||||
const [pageData, setPageData] = useState(() => {
|
||||
let pageConfigStr = localStorage.getItem('pageConfig');
|
||||
let pageConfig;
|
||||
|
||||
try {
|
||||
pageConfig = JSON.parse(pageConfigStr!) || {};
|
||||
} catch (err) {
|
||||
pageConfig = {};
|
||||
}
|
||||
return pageConfig;
|
||||
});
|
||||
|
||||
const vw = window.innerWidth;
|
||||
|
||||
useEffect(() => {
|
||||
const { tid, gf } = props.location.query!;
|
||||
if (!gf) {
|
||||
if (!gf && parent.window.location.pathname === '/preview') {
|
||||
req
|
||||
.get<any, PointDataItem[]>('/visible/preview/get', { params: { tid } })
|
||||
.get<any, any>('/xxx/xxx/你的自定义接口地址', { params: { tid } })
|
||||
.then(res => {
|
||||
const { pageConfig, tpl } = res || { pageConfig: {}, tpl: [] };
|
||||
// 设置标题
|
||||
document.title = pageConfig.title || 'H5-Dooring | 强大的H5编辑神器';
|
||||
// 设置数据源
|
||||
setPointData(
|
||||
res.map(item => ({
|
||||
tpl.map(item => ({
|
||||
...item,
|
||||
point: { ...item.point, isDraggable: false, isResizable: false },
|
||||
})),
|
||||
);
|
||||
|
||||
setPageData(pageConfig);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
@ -62,27 +81,31 @@ const PreviewPage = memo((props: PreviewPageProps) => {
|
||||
}, [props.location.query]);
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const refImgDom = useRef<HTMLDivElement>(null);
|
||||
const width = useGetScrollBarWidth(ref);
|
||||
const pcStyle: CSSProperties = useMemo(() => {
|
||||
return {
|
||||
width: isMac ? 395 : 375 + width + 1, //小数会有偏差
|
||||
width: isMac ? 382 : 375 + width + 1, //小数会有偏差
|
||||
margin: '55px auto',
|
||||
height: '684px',
|
||||
overflow: 'auto',
|
||||
position: 'relative',
|
||||
transform: 'scale(0.7) translateY(-80px)',
|
||||
backgroundColor: pageData.bgColor,
|
||||
};
|
||||
}, [width]);
|
||||
|
||||
const generateImg = (cb: any) => {
|
||||
domtoimage
|
||||
.toBlob(ref.current)
|
||||
.toBlob(refImgDom.current, {
|
||||
bgcolor: '#fff',
|
||||
})
|
||||
.then(function(blob: Blob) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', blob, 'tpl.jpg');
|
||||
req.post('/files/xxx', formData).then((res: any) => {
|
||||
cb && cb(res.url);
|
||||
});
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
cb && cb(e?.target?.result);
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
})
|
||||
.catch(function(error: any) {
|
||||
console.error('oops, something went wrong!', error);
|
||||
@ -91,20 +114,35 @@ const PreviewPage = memo((props: PreviewPageProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div ref={ref} style={vw > 800 ? pcStyle : {}}>
|
||||
<GridLayout
|
||||
className={styles.layout}
|
||||
cols={24}
|
||||
rowHeight={2}
|
||||
width={vw > 800 ? 375 : vw}
|
||||
margin={[0, 0]}
|
||||
>
|
||||
{pointData.map((value: PointDataItem) => (
|
||||
<div className={styles.dragItem} key={value.id} data-grid={value.point}>
|
||||
<DynamicEngine {...(value.item as any)} />
|
||||
</div>
|
||||
))}
|
||||
</GridLayout>
|
||||
<div
|
||||
ref={ref}
|
||||
style={
|
||||
vw > 800
|
||||
? pcStyle
|
||||
: { height: '100vh', overflow: 'auto', backgroundColor: pageData.bgColor }
|
||||
}
|
||||
>
|
||||
<div ref={refImgDom}>
|
||||
<GridLayout
|
||||
className={styles.layout}
|
||||
cols={24}
|
||||
rowHeight={2}
|
||||
width={vw > 800 ? 375 : vw}
|
||||
margin={[0, 0]}
|
||||
style={{
|
||||
backgroundColor: pageData.bgColor,
|
||||
backgroundImage: pageData.bgImage ? `url(${pageData.bgImage[0].url})` : 'initial',
|
||||
backgroundSize: 'contain',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}}
|
||||
>
|
||||
{pointData.map((value: PointDataItem) => (
|
||||
<div className={styles.dragItem} key={value.id} data-grid={value.point}>
|
||||
<DynamicEngine {...(value.item as any)} />
|
||||
</div>
|
||||
))}
|
||||
</GridLayout>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{vw > 800 ? (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user