Compare commits

...

2 Commits

@ -5,7 +5,7 @@ html {
padding: 0; padding: 0;
height: 100%; height: 100%;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f0f2f5; background-color: #e5e7eb;
color: #333; color: #333;
} }
* { * {
@ -21,16 +21,23 @@ html {
/* Components panel */ /* Components panel */
#components-panel { #components-panel {
position: relative;
flex: 1; flex: 1;
padding: 10px;
background-color: #fff; background-color: #fff;
border-right: 1px solid #e0e0e0;
display: flex;
flex-direction: column;
}
.components-list {
flex: 1;
padding: 10px;
overflow-y: auto; overflow-y: auto;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
align-content: flex-start; align-content: flex-start;
gap: 10px; gap: 10px;
border-right: 1px solid #e0e0e0;
} }
.component-item { .component-item {
@ -41,6 +48,7 @@ html {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
overflow: hidden;
} }
.component-item .grid-stack-item-content { .component-item .grid-stack-item-content {
width: 100%; width: 100%;
@ -69,12 +77,42 @@ html {
.component-item span { .component-item span {
font-size: 14px; font-size: 14px;
} }
.action-btn {
position: relative;
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
}
.action-btn .trash-container,
.action-btn .save-container {
width: 46%;
height: 40px;
margin: 0 2%;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
background: rgb(0, 123, 255, 0.6);
color: #fff;
font-size: 14px;
cursor: pointer;
}
.save-container {
background: rgb(0, 123, 255, 1) !important;
}
.action-btn .trash-container > span,
.action-btn .save-container > span {
margin-left: 5px;
}
/* Canvas panel */ /* Canvas panel */
#canvas-panel { #canvas-panel {
flex: 4; flex: 4;
height: 100%; height: 100%;
background-color: #f9f9f9; background-color: #f9fafb;
position: relative; position: relative;
overflow-y: auto; overflow-y: auto;
padding: 10px; padding: 10px;
@ -83,6 +121,10 @@ html {
cursor: pointer; cursor: pointer;
background: #fff; background: #fff;
} }
#canvas-panel .grid-stack-item-content {
border-radius: 8px;
border: 1px solid #e0e0e0;
}
.global-save-button-container { .global-save-button-container {
position: absolute; position: absolute;

@ -6,7 +6,7 @@
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0" content="width=device-width, initial-scale=1.0"
/> />
<title>Page Builder</title> <title>网页布局生成</title>
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
@ -26,30 +26,45 @@
<div id="app"> <div id="app">
<!-- 组件列表 --> <!-- 组件列表 -->
<div id="components-panel"> <div id="components-panel">
<div class="component-item grid-stack-item"> <div class="components-list">
<div class="grid-stack-item-content"><i class="fas fa-images"></i><span>轮播图</span></div> <div class="component-item grid-stack-item">
</div> <div class="grid-stack-item-content"><i class="fas fa-images"></i><span>轮播图</span></div>
<div class="component-item grid-stack-item"> </div>
<div class="grid-stack-item-content"><i class="fas fa-search"></i><span>搜索</span></div> <div class="component-item grid-stack-item">
</div> <div class="grid-stack-item-content"><i class="fas fa-search"></i><span>搜索</span></div>
<div class="component-item grid-stack-item"> </div>
<div class="grid-stack-item-content"><i class="fas fa-tv"></i><span>热门频道</span></div> <div class="component-item grid-stack-item">
</div> <div class="grid-stack-item-content"><i class="fas fa-tv"></i><span>热门频道</span></div>
<div class="component-item grid-stack-item"> </div>
<div class="grid-stack-item-content"><i class="fas fa-video"></i><span>直播</span></div> <div class="component-item grid-stack-item">
</div> <div class="grid-stack-item-content"><i class="fas fa-video"></i><span>直播</span></div>
<div class="component-item grid-stack-item"> </div>
<div class="grid-stack-item-content"><i class="fas fa-thumbs-up"></i><span>推荐内容</span></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>
<div class="component-item grid-stack-item"> <div
<div class="grid-stack-item-content"><i class="fas fa-link"></i><span>快捷入口</span></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>
</div> </div>
<!-- 画布容器 --> <!-- 画布容器 -->
<div id="canvas-panel"> <div id="canvas-panel">
<div class="global-save-button-container"> <!-- <div class="global-save-button-container">
<button class="global-save-button">保存布局</button> <button class="global-save-button">保存布局</button>
</div> </div> -->
<div class="grid-stack"></div> <div class="grid-stack"></div>
</div> </div>
<!-- 当前选中组件属性 --> <!-- 当前选中组件属性 -->
@ -102,7 +117,7 @@
id="link" id="link"
/> />
</div> </div>
<div class="form-actions"> <!-- <div class="form-actions">
<button <button
type="button" type="button"
class="save-button" class="save-button"
@ -115,7 +130,7 @@
> >
删除组件 删除组件
</button> </button>
</div> </div> -->
</form> </form>
</div> </div>
</div> </div>

@ -19,18 +19,19 @@
minRow: 8, minRow: 8,
acceptWidgets: true, acceptWidgets: true,
float: true, float: true,
removable: '#trash',
}); });
GridStack.setupDragIn('#components-panel > .component-item', undefined, [ GridStack.setupDragIn('#components-panel .component-item', undefined, [
{ {
w: 12, w: 12,
h: 2, h: 2,
type: 'banner', type: 'banner',
name: '我是轮播图', name: '我是轮播图',
fontSize: 14, fontSize: 14,
color: '#fff', color: '#333',
background: 'red', background: '#fff',
detail: '', detail: '',
icon: 'fa-link', icon: 'fa-image',
link: '', link: '',
}, },
{ w: 2, h: 1 }, { w: 2, h: 1 },
@ -70,6 +71,13 @@
handleAddComponent(item); handleAddComponent(item);
}); });
}); });
grid.on('removed', function (_event, itemArray) {
console.log(itemArray, '这里触发了移除removed事件');
itemArray.forEach((item) => {
handleRemoveComponent(item);
});
});
}; };
// 处理添加组件之后的操作 // 处理添加组件之后的操作
@ -83,15 +91,27 @@
} }
currentComponent = component; currentComponent = component;
// 右侧显示组件属性列表 // 右侧显示组件属性列表
if (!$('#props-panel').find('form').hasClass('show')) { if (!$('#props-panel').find('form').is(':visible')) {
$('#props-panel').find('.wait-box').addClass('hidden'); $('#props-panel').find('.wait-box').hide();
$('#props-panel').find('form').attr('class', 'show'); $('#props-panel').find('form').show();
} }
// 将当前选中组件的属性显示在右侧列表中 // 将当前选中组件的属性显示在右侧列表中
setCurrentComponentProps(currentComponent); setCurrentComponentProps(currentComponent);
}); });
}; };
var handleRemoveComponent = (component) => {
if (currentComponent && currentComponent.id === component.id) {
currentComponent = null;
// 右侧显示请选择组件
if (!$('#props-panel').find('wait-box').is(':visible')) {
console.log('111');
$('#props-panel').find('.wait-box').show();
$('#props-panel').find('form').hide();
}
}
};
//将当前选中组件的属性显示在右侧列表中 //将当前选中组件的属性显示在右侧列表中
var setCurrentComponentProps = function (component) { var setCurrentComponentProps = function (component) {
const form = $('#props-panel').find('form'); const form = $('#props-panel').find('form');
@ -104,32 +124,72 @@
form.find('#link').val(component.link); form.find('#link').val(component.link);
}; };
// 定义组件设置配置策略
const componentStrategies = {
name: function (el, value) {
el.find('span').text(value);
},
background: function (el, value) {
el.find('.grid-stack-item-content').css('background', value);
},
fontSize: function (el, value) {
el.find('span').css('font-size', value + 'px');
},
color: function (el, value) {
el.find('span').css('color', value);
},
icon: function (el, value) {
el.find('i').attr('class', `fas ${value}`);
},
// detail, link不需要反显页面所有不需要修改dom
};
// 设置当前传递组件的视图展示 // 设置当前传递组件的视图展示
var setComponentView = function (component) { var setComponentView = function (component, fields = null) {
const el = $(component.el); const el = $(component.el);
// 设置名称
if (component.name) { // 确定要处理的属性
el.find('span').text(component.name); const propsToHandle = fields || Object.keys(componentStrategies);
}
// 设置背景颜色 // 遍历并执行对应的策略
if (component.background) { propsToHandle.forEach((prop) => {
el.find('.grid-stack-item-content').css('background', component.background); if (componentStrategies[prop] && component[prop] !== undefined) {
} componentStrategies[prop](el, component[prop]);
// 设置文字大小和颜色 }
if (component.fontSize) { });
el.find('span').css('font-size', component.fontSize + 'px'); };
}
if (component.color) { // 定义映射关系元素ID -> 事件类型 -> 组件属性
el.find('span').css('color', component.color); const elementMappings = {
} name: { event: 'blur', property: 'name' },
// 设置图标 background: { event: 'blur', property: 'background' },
if (component.icon) { fontSize: { event: 'blur', property: 'fontSize' },
el.find('i').attr('class', `fas ${component.icon}`); color: { event: 'blur', property: 'color' },
} icon: { event: 'blur', property: 'icon' },
detail: { event: 'blur', property: 'detail' },
link: { event: 'blur', property: 'link' },
// icon: { event: 'change', property: 'icon' }, // select使用change
};
// 统一绑定函数
var bindComponentEvents = function () {
Object.keys(elementMappings).forEach((elementId) => {
const mapping = elementMappings[elementId];
const $element = $('#' + elementId);
if ($element.length) {
// 组件名称添加失去焦点事件或者change事件
$element.off(mapping.event).on(mapping.event, function () {
const value = $(this).val();
currentComponent[mapping.property] = value;
setComponentView(currentComponent, [mapping.property]);
});
}
});
}; };
$('.global-save-button').click(function () { $('.save-container').click(function () {
grid.addWidget({ w: 2, content: 'item 1' }); // grid.addWidget({ w: 2, content: 'item 1' });
console.log(grid.save()); console.log(grid.save());
console.log(grid); console.log(grid);
}); });
@ -137,5 +197,7 @@
/** 执行方法 */ /** 执行方法 */
$(function () { $(function () {
init(); init();
// 调用绑定
bindComponentEvents();
}); });
})(); })();

Loading…
Cancel
Save