Compare commits

..

2 Commits

@ -16,7 +16,37 @@ html {
#app {
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
}
#main {
display: flex;
flex: 1;
height: calc(100vh - 60px);
}
#header {
flex-shrink: 0;
width: 100%;
height: 60px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
}
#header > h1 {
font-size: 20px;
}
.panel-title {
width: 90%;
margin: 0 5%;
padding: 10px 0;
border-bottom: 2px solid #667eea;
}
/* Components panel */
@ -50,7 +80,8 @@ html {
justify-content: center;
overflow: hidden;
}
.component-item .grid-stack-item-content {
.component-item .grid-stack-item-content,
.grid-stack-item .grid-stack-item-content {
width: 100%;
height: 100%;
display: flex;
@ -68,13 +99,15 @@ html {
border: 1px solid #e0e0e0;
}
.component-item i {
.component-item i,
.grid-stack-item i {
font-size: 18px;
margin-bottom: 5px;
color: #007bff;
}
.component-item span {
.component-item span,
.grid-stack-item span {
font-size: 14px;
}
.action-btn {
@ -101,7 +134,7 @@ html {
cursor: pointer;
}
.save-container {
background: rgb(0, 123, 255, 1) !important;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
}
.action-btn .trash-container > span,
.action-btn .save-container > span {
@ -112,11 +145,15 @@ html {
#canvas-panel {
flex: 4;
height: 100%;
background-color: #f9fafb;
background-color: #fff;
position: relative;
overflow-y: auto;
padding: 10px;
}
.grid-stack {
background-color: #f9fafb;
border-radius: 8px;
}
.grid-stack-item-content {
cursor: pointer;
background: #fff;
@ -151,12 +188,20 @@ html {
/* Props panel */
#props-panel {
flex: 1;
padding: 10px;
background-color: #fff;
overflow-y: auto;
border-left: 1px solid #e0e0e0;
display: flex;
flex-direction: column;
}
form {
padding: 10px;
display: flex;
flex-direction: column;
flex: 1;
overflow-y: auto;
}
.form-item {
margin-bottom: 20px;
}

@ -24,114 +24,128 @@
</head>
<body>
<div id="app">
<!-- 组件列表 -->
<div id="components-panel">
<div class="components-list">
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-images"></i><span>轮播图</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-search"></i><span>搜索</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-tv"></i><span>热门频道</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-video"></i><span>直播</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-thumbs-up"></i><span>推荐内容</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-link"></i><span>快捷入口</span></div>
</div>
</div>
<div
class="action-btn"
id="trash"
>
<div class="trash-container">
<i class="fas fa-trash"></i>
<span>拖动删除</span>
</div>
<div class="save-container">
<i class="fas fa-trash"></i>
<span>保存布局</span>
</div>
<div id="header">
<h1>可视化布局编辑器</h1>
<div class="header-actions">
<span>拖拽组件到画布区域</span>
</div>
</div>
<!-- 画布容器 -->
<div id="canvas-panel">
<!-- <div class="global-save-button-container">
<button class="global-save-button">保存布局</button>
</div> -->
<div class="grid-stack"></div>
</div>
<!-- 当前选中组件属性 -->
<div id="props-panel">
<div class="wait-box">请选择组件</div>
<form class="hidden">
<div class="form-item">
<label for="name">名称</label>
<input
type="text"
id="name"
/>
</div>
<div class="form-item">
<label for="background">背景颜色</label>
<input
type="text"
id="background"
/>
</div>
<div class="form-item">
<label for="fontSize">文字大小</label>
<input
type="text"
id="fontSize"
/>
</div>
<div class="form-item">
<label for="color">文字颜色</label>
<input
type="text"
id="color"
/>
</div>
<div class="form-item">
<label for="icon">图标名称</label>
<input
type="text"
id="icon"
/>
<div id="main">
<!-- 组件列表 -->
<div id="components-panel">
<div class="panel-title">
<span>组件列表</span>
</div>
<div class="form-item">
<label for="detail">描述</label>
<textarea id="detail"></textarea>
<div class="components-list">
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-images"></i><span>轮播图</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-search"></i><span>搜索</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-tv"></i><span>热门频道</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-video"></i><span>直播</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-thumbs-up"></i><span>推荐内容</span></div>
</div>
<div class="component-item grid-stack-item">
<div class="grid-stack-item-content"><i class="fas fa-link"></i><span>快捷入口</span></div>
</div>
</div>
<div class="form-item">
<label for="link">跳转链接</label>
<input
type="text"
id="link"
/>
<div
class="action-btn"
id="trash"
>
<div class="trash-container">
<i class="fas fa-trash"></i>
<span>拖动删除</span>
</div>
<div class="save-container">
<i class="fas fa-trash"></i>
<span>保存布局</span>
</div>
</div>
<!-- <div class="form-actions">
<button
type="button"
class="save-button"
>
保存组件
</button>
<button
type="button"
class="delete-button"
>
删除组件
</button>
</div>
<!-- 画布容器 -->
<div id="canvas-panel">
<!-- <div class="global-save-button-container">
<button class="global-save-button">保存布局</button>
</div> -->
</form>
<div class="grid-stack"></div>
</div>
<!-- 当前选中组件属性 -->
<div id="props-panel">
<div class="panel-title">
<span>组件属性</span>
</div>
<div class="wait-box">请选择组件</div>
<form class="hidden">
<div class="form-item">
<label for="name">名称</label>
<input
type="text"
id="name"
/>
</div>
<div class="form-item">
<label for="background">背景颜色</label>
<input
type="text"
id="background"
/>
</div>
<div class="form-item">
<label for="fontSize">文字大小</label>
<input
type="text"
id="fontSize"
/>
</div>
<div class="form-item">
<label for="color">文字颜色</label>
<input
type="text"
id="color"
/>
</div>
<div class="form-item">
<label for="icon">图标名称</label>
<input
type="text"
id="icon"
/>
</div>
<div class="form-item">
<label for="detail">描述</label>
<textarea id="detail"></textarea>
</div>
<div class="form-item">
<label for="link">跳转链接</label>
<input
type="text"
id="link"
/>
</div>
<!-- <div class="form-actions">
<button
type="button"
class="save-button"
>
保存组件
</button>
<button
type="button"
class="delete-button"
>
删除组件
</button>
</div> -->
</form>
</div>
</div>
</div>
</body>

@ -1,4 +1,5 @@
(function () {
let initData = null;
let grid = null;
let currentComponent = null;
@ -11,15 +12,31 @@
/** 初始化 */
var init = function () {
const initDataStorage = localStorage.getItem('initData');
if (!initDataStorage) {
initData = {
id: `grid_${generateUniqueId()}`,
children: [],
};
} else {
initData = JSON.parse(initDataStorage);
}
console.log(initData, 'initData');
// 让gridstack知道如何渲染组件children中的content直接渲染html
GridStack.renderCB = function (el, w) {
el.innerHTML = w.content;
};
grid = GridStack.init({
// 一行高度
cellHeight: 80,
cellHeight: 60,
// 间距
margin: 5,
minRow: 8,
acceptWidgets: true,
float: true,
removable: '#trash',
children: initData.children,
});
GridStack.setupDragIn('#components-panel .component-item', undefined, [
{
@ -38,28 +55,7 @@
]);
console.log(grid, 'grid实例');
var initData = [
// {
// x: 0,
// y: 0,
// w: 2,
// h: 2,
// content: 'item 1',
// data: {
// name: 'item 1',
// },
// },
// {
// x: 2,
// y: 3,
// w: 3,
// content: 'item 2',
// data: {
// name: 'item 2',
// },
// },
];
// grid.load(initData);
// grid.load(initData.children);
grid.engine.nodes.forEach((item) => {
handleAddComponent(item);
@ -82,7 +78,9 @@
// 处理添加组件之后的操作
var handleAddComponent = (component) => {
component.id = `${component.type}_${generateUniqueId()}`;
if (!component.id) {
component.id = `${component.type}_${generateUniqueId()}`;
}
setComponentView(component);
component.el.addEventListener('click', () => {
console.log('点击组件', component);
@ -192,6 +190,8 @@
// grid.addWidget({ w: 2, content: 'item 1' });
console.log(grid.save());
console.log(grid);
initData.children = grid.save();
localStorage.setItem('initData', JSON.stringify(initData));
});
/** 执行方法 */

Loading…
Cancel
Save