Compare commits
3 Commits
7c9d012f7e
...
e1fce839b3
| Author | SHA1 | Date |
|---|---|---|
|
|
e1fce839b3 | 4 weeks ago |
|
|
0669154d0a | 4 weeks ago |
|
|
ab4de42fdc | 4 weeks ago |
@ -0,0 +1 @@
|
|||||||
|
.grid-stack{position:relative}.grid-stack-rtl{direction:ltr}.grid-stack-rtl>.grid-stack-item{direction:rtl}.grid-stack-placeholder>.placeholder-content{background-color:rgba(0,0,0,.1);margin:0;position:absolute;width:auto;z-index:0!important}.grid-stack>.grid-stack-item{position:absolute;padding:0;top:0;left:0;width:var(--gs-column-width);height:var(--gs-cell-height)}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;width:auto;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item.size-to-content:not(.size-to-content-max)>.grid-stack-item-content{overflow-y:hidden}.grid-stack>.grid-stack-item>.grid-stack-item-content,.grid-stack>.grid-stack-placeholder>.placeholder-content{top:var(--gs-item-margin-top);right:var(--gs-item-margin-right);bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack-item>.ui-resizable-ne,.grid-stack-item>.ui-resizable-nw,.grid-stack-item>.ui-resizable-se,.grid-stack-item>.ui-resizable-sw{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="%23666" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 20 20"><path d="m10 3 2 2H8l2-2v14l-2-2h4l-2 2"/></svg>');background-repeat:no-repeat;background-position:center}.grid-stack-item>.ui-resizable-ne{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-sw{transform:rotate(45deg)}.grid-stack-item>.ui-resizable-nw{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-se{transform:rotate(-45deg)}.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;top:var(--gs-item-margin-top);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:var(--gs-item-margin-top);left:25px;right:25px}.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;top:var(--gs-item-margin-top);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;top:15px;bottom:15px;right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-se{cursor:se-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);right:var(--gs-item-margin-right)}.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:var(--gs-item-margin-bottom);right:25px}.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;bottom:var(--gs-item-margin-bottom);left:var(--gs-item-margin-left)}.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;top:15px;bottom:15px;left:var(--gs-item-margin-left)}.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack-item.ui-draggable-dragging{will-change:left,top}.grid-stack-item.ui-resizable-resizing{will-change:width,height}.ui-draggable-dragging,.ui-resizable-resizing{z-index:10000}.ui-draggable-dragging>.grid-stack-item-content,.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px rgba(0,0,0,.2);opacity:.8}.grid-stack-animate,.grid-stack-animate .grid-stack-item{transition:left .3s,top .3s,height .3s,width .3s}.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack-animate .grid-stack-item.ui-resizable-resizing{transition:left 0s,top 0s,height 0s,width 0s}.grid-stack>.grid-stack-item[gs-y="0"]{top:0}.grid-stack>.grid-stack-item[gs-x="0"]{left:0}
|
||||||
@ -0,0 +1,203 @@
|
|||||||
|
/* Global styles */
|
||||||
|
body,
|
||||||
|
html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f0f2f5;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Components panel */
|
||||||
|
#components-panel {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-content: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
border-right: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.component-item {
|
||||||
|
width: calc(50% - 5px);
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.component-item .grid-stack-item-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas-panel .grid-stack-item-content {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#components-panel .grid-stack-item {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.component-item i {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.component-item span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Canvas panel */
|
||||||
|
#canvas-panel {
|
||||||
|
flex: 4;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.grid-stack-item-content {
|
||||||
|
cursor: pointer;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.global-save-button-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.global-save-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #28a745;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.global-save-button:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Props panel */
|
||||||
|
#props-panel {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow-y: auto;
|
||||||
|
border-left: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item input,
|
||||||
|
.form-item textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item input:focus,
|
||||||
|
.form-item textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions button {
|
||||||
|
padding: 10px 15px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-button {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
background-color: #dc3545;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button:hover {
|
||||||
|
background-color: #c82333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar styles */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive layout */
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
#components-panel {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0"
|
||||||
|
/>
|
||||||
|
<title>Page Builder</title>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="css/index.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="./css/gridstack.min.css"
|
||||||
|
/>
|
||||||
|
<script src="./js/gridstack-all.js"></script>
|
||||||
|
<script src="./js/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<!-- 组件列表 -->
|
||||||
|
<div id="components-panel">
|
||||||
|
<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 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">
|
||||||
|
<form>
|
||||||
|
<div class="form-item">
|
||||||
|
<label for="name">名称</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-item">
|
||||||
|
<label for="image">图片</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-item">
|
||||||
|
<label for="description">描述</label>
|
||||||
|
<textarea id="description"></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>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<script src="./js/index.js"></script>
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,70 @@
|
|||||||
|
(function () {
|
||||||
|
var grid = null;
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
var init = function () {
|
||||||
|
grid = GridStack.init({
|
||||||
|
// 一行高度
|
||||||
|
cellHeight: 80,
|
||||||
|
// 间距
|
||||||
|
margin: 5,
|
||||||
|
minRow: 8,
|
||||||
|
acceptWidgets: true,
|
||||||
|
float: true,
|
||||||
|
});
|
||||||
|
GridStack.setupDragIn('#components-panel > .component-item', undefined, [
|
||||||
|
{ w: 12, h: 2 },
|
||||||
|
{ w: 2, h: 1 },
|
||||||
|
]);
|
||||||
|
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.engine.nodes.forEach((item) => {
|
||||||
|
item.el.addEventListener('click', () => {
|
||||||
|
console.log(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
grid.on('added', function (_event, itemArray) {
|
||||||
|
console.log(itemArray, '这里触发了添加了added事件');
|
||||||
|
itemArray.forEach((item) => {
|
||||||
|
item.el.addEventListener('click', () => {
|
||||||
|
console.log(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$('.global-save-button').click(function () {
|
||||||
|
grid.addWidget({ w: 2, content: 'item 1' });
|
||||||
|
console.log(grid.save());
|
||||||
|
console.log(grid);
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 执行方法 */
|
||||||
|
$(function () {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
})();
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue