|
|
(function () {
|
|
|
let initData = null;
|
|
|
let grid = null;
|
|
|
let currentComponent = null;
|
|
|
let cellHeight = 40;
|
|
|
|
|
|
// 生成唯一id
|
|
|
var generateUniqueId = function () {
|
|
|
const timestamp = Date.now().toString(36);
|
|
|
const randomNum = Math.random().toString(36).substring(2);
|
|
|
return timestamp + randomNum;
|
|
|
};
|
|
|
|
|
|
/** 初始化 */
|
|
|
var init = function () {
|
|
|
const initDataStorage = localStorage.getItem('initData');
|
|
|
if (!initDataStorage) {
|
|
|
initData = {
|
|
|
id: `grid_${generateUniqueId()}`,
|
|
|
children: [],
|
|
|
version: '1.0.0',
|
|
|
width: 1920,
|
|
|
height: 1080,
|
|
|
};
|
|
|
} else {
|
|
|
initData = JSON.parse(initDataStorage);
|
|
|
conputedInitData('init');
|
|
|
}
|
|
|
console.log(initData, 'initData');
|
|
|
|
|
|
// 让gridstack知道如何渲染,组件children中的content直接渲染html
|
|
|
GridStack.renderCB = function (el, w) {
|
|
|
el.innerHTML = w.content;
|
|
|
};
|
|
|
grid = GridStack.init({
|
|
|
// 一行高度
|
|
|
cellHeight,
|
|
|
// 间距
|
|
|
margin: 5,
|
|
|
minRow: Math.floor(($(window).height() - 80) / cellHeight),
|
|
|
acceptWidgets: true,
|
|
|
float: true,
|
|
|
removable: '#trash',
|
|
|
// subGridOpts: subOptions,
|
|
|
// subGridDynamic: true,
|
|
|
children: initData.children,
|
|
|
});
|
|
|
GridStack.setupDragIn('#components-panel .component-item', undefined, [
|
|
|
{
|
|
|
w: 2,
|
|
|
h: 4,
|
|
|
type: 'image',
|
|
|
name: '图片',
|
|
|
image: '',
|
|
|
eventsType: 'click',
|
|
|
eventsAction: '',
|
|
|
defaultFocus: false,
|
|
|
leftId: '',
|
|
|
rightId: '',
|
|
|
upId: '',
|
|
|
downId: '',
|
|
|
},
|
|
|
{
|
|
|
w: 2,
|
|
|
h: 2,
|
|
|
type: 'text',
|
|
|
childrenType: '',
|
|
|
name: '文本',
|
|
|
background: '#fff',
|
|
|
fontSize: '14px',
|
|
|
color: '#333',
|
|
|
text: '文本',
|
|
|
fontWeight: 'normal',
|
|
|
eventsType: 'click',
|
|
|
eventsAction: '',
|
|
|
defaultFocus: false,
|
|
|
leftId: '',
|
|
|
rightId: '',
|
|
|
upId: '',
|
|
|
downId: '',
|
|
|
},
|
|
|
]);
|
|
|
console.log(grid, 'grid实例');
|
|
|
|
|
|
// grid.load(initData.children);
|
|
|
|
|
|
grid.engine.nodes.forEach((item) => {
|
|
|
handleAddComponent(item);
|
|
|
});
|
|
|
|
|
|
grid.on('added', function (_event, itemArray) {
|
|
|
console.log(itemArray, '这里触发了添加了added事件');
|
|
|
itemArray.forEach((item) => {
|
|
|
handleAddComponent(item);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
grid.on('removed', function (_event, itemArray) {
|
|
|
console.log(itemArray, '这里触发了移除removed事件');
|
|
|
itemArray.forEach((item) => {
|
|
|
handleRemoveComponent(item);
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// 处理添加组件之后的操作
|
|
|
var handleAddComponent = (component) => {
|
|
|
if (!component.id) {
|
|
|
component.id = `${component.type}_${generateUniqueId()}`;
|
|
|
}
|
|
|
setComponentView(component);
|
|
|
component.el.addEventListener('click', () => {
|
|
|
console.log('点击组件', component);
|
|
|
if (currentComponent && currentComponent.id === component.id) {
|
|
|
return;
|
|
|
}
|
|
|
currentComponent = component;
|
|
|
// 右侧显示组件属性列表
|
|
|
if (!$('#props-panel').find('form').is(':visible')) {
|
|
|
$('#props-panel').find('.wait-box').hide();
|
|
|
$('#props-panel').find('form').show();
|
|
|
}
|
|
|
// 将当前选中组件的属性显示在右侧列表中
|
|
|
setCurrentComponentProps(currentComponent);
|
|
|
// 设置上下左右移动组件ID
|
|
|
setMoveComponentId(currentComponent);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// 设置上下左右移动组件ID
|
|
|
var setMoveComponentId = function (component) {
|
|
|
const allComponents = grid.save();
|
|
|
if (allComponents.length <= 1) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
setMoveComponentHtml('leftId', component, allComponents);
|
|
|
setMoveComponentHtml('rightId', component, allComponents);
|
|
|
setMoveComponentHtml('upId', component, allComponents);
|
|
|
setMoveComponentHtml('downId', component, allComponents);
|
|
|
};
|
|
|
|
|
|
var setMoveComponentHtml = function (idName, component, allComponents) {
|
|
|
let componentsHtml = [{ value: '', text: '请选择' }];
|
|
|
allComponents
|
|
|
.filter((item) => item.id !== component.id)
|
|
|
.map((item) => {
|
|
|
componentsHtml.push({ value: item.id, text: `${item.name}(${item.id})`, selected: item.id === component[idName] });
|
|
|
});
|
|
|
let el = $(`#${idName}`);
|
|
|
el.empty();
|
|
|
componentsHtml.forEach((item) => {
|
|
|
el.append(
|
|
|
$('<option>', {
|
|
|
value: item.value,
|
|
|
text: item.text,
|
|
|
selected: item.selected || false,
|
|
|
})
|
|
|
);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
var handleRemoveComponent = (component) => {
|
|
|
if (currentComponent && currentComponent.id === component.id) {
|
|
|
currentComponent = null;
|
|
|
// 右侧显示请选择组件
|
|
|
if (!$('#props-panel').find('wait-box').is(':visible')) {
|
|
|
$('#props-panel').find('.wait-box').show();
|
|
|
$('#props-panel').find('form').hide();
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
//将当前选中组件的属性显示在右侧列表中
|
|
|
var setCurrentComponentProps = function (component) {
|
|
|
const form = $('#props-panel').find('form');
|
|
|
if (component.hasOwnProperty('childrenType')) {
|
|
|
form.find('#childrenType').val(component.childrenType);
|
|
|
form.find('#childrenType').parent().show();
|
|
|
} else {
|
|
|
form.find('#childrenType').parent().hide();
|
|
|
}
|
|
|
|
|
|
form.find('#name').val(component.name);
|
|
|
|
|
|
if (component.hasOwnProperty('image')) {
|
|
|
form.find('#image').val(component.image);
|
|
|
form.find('#image').parent().show();
|
|
|
} else {
|
|
|
form.find('#image').parent().hide();
|
|
|
}
|
|
|
|
|
|
if (component.hasOwnProperty('background')) {
|
|
|
form.find('#background').val(component.background);
|
|
|
form.find('#background').parent().show();
|
|
|
} else {
|
|
|
form.find('#background').parent().hide();
|
|
|
}
|
|
|
|
|
|
if (component.type === 'text') {
|
|
|
form.find('#text').val(component.text);
|
|
|
form.find('#fontSize').val(component.fontSize);
|
|
|
form.find('#color').val(component.color);
|
|
|
form.find('#fontWeight').val(component.fontWeight);
|
|
|
form.find('#text').parent().show();
|
|
|
form.find('#fontSize').parent().show();
|
|
|
form.find('#color').parent().show();
|
|
|
form.find('#fontWeight').parent().show();
|
|
|
} else {
|
|
|
form.find('#text').parent().hide();
|
|
|
form.find('#fontSize').parent().hide();
|
|
|
form.find('#color').parent().hide();
|
|
|
form.find('#fontWeight').parent().hide();
|
|
|
}
|
|
|
|
|
|
form.find('#eventsType').val(component.eventsType);
|
|
|
form.find('#eventsAction').val(component.eventsAction);
|
|
|
form.find('#defaultFocus').val(component.defaultFocus);
|
|
|
form.find('#leftId').val(component.leftId);
|
|
|
form.find('#rightId').val(component.rightId);
|
|
|
form.find('#upId').val(component.upId);
|
|
|
form.find('#downId').val(component.downId);
|
|
|
};
|
|
|
|
|
|
// 定义组件设置配置策略
|
|
|
const componentStrategies = {
|
|
|
background: function (el, value) {
|
|
|
el.find('.grid-stack-item-content').css('background', value);
|
|
|
},
|
|
|
image: function (el, value) {
|
|
|
el.find('.grid-stack-item-content').css('background', `url(${value}) no-repeat center center`).css('background-size', 'cover');
|
|
|
},
|
|
|
fontSize: function (el, value) {
|
|
|
el.find('span').css('font-size', value + 'px');
|
|
|
},
|
|
|
color: function (el, value) {
|
|
|
el.find('span').css('color', value);
|
|
|
},
|
|
|
text: function (el, value) {
|
|
|
el.find('span').text(value);
|
|
|
},
|
|
|
fontWeight: function (el, value) {
|
|
|
el.find('span').css('font-weight', value);
|
|
|
},
|
|
|
};
|
|
|
|
|
|
// 设置当前传递组件的视图展示
|
|
|
var setComponentView = function (component, fields = null) {
|
|
|
const el = $(component.el);
|
|
|
|
|
|
// 确定要处理的属性
|
|
|
const propsToHandle = fields || Object.keys(componentStrategies);
|
|
|
|
|
|
// 遍历并执行对应的策略
|
|
|
propsToHandle.forEach((prop) => {
|
|
|
if (componentStrategies[prop] && component[prop] !== undefined) {
|
|
|
componentStrategies[prop](el, component[prop]);
|
|
|
}
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// 定义映射关系:元素ID -> 事件类型 -> 组件属性
|
|
|
const elementMappings = {
|
|
|
childrenType: { event: 'blur', property: 'childrenType' },
|
|
|
background: { event: 'blur', property: 'background' },
|
|
|
image: { event: 'change', property: 'image' },
|
|
|
fontSize: { event: 'blur', property: 'fontSize' },
|
|
|
color: { event: 'blur', property: 'color' },
|
|
|
text: { event: 'blur', property: 'text' },
|
|
|
fontWeight: { event: 'blur', property: 'fontWeight' },
|
|
|
eventsType: { event: 'blur', property: 'eventsType' },
|
|
|
eventsAction: { event: 'blur', property: 'eventsAction' },
|
|
|
defaultFocus: { event: 'blur', property: 'defaultFocus' },
|
|
|
leftId: { event: 'change', property: 'leftId' },
|
|
|
rightId: { event: 'change', property: 'rightId' },
|
|
|
upId: { event: 'change', property: 'upId' },
|
|
|
downId: { event: 'change', property: 'downId' },
|
|
|
};
|
|
|
|
|
|
// 统一绑定函数
|
|
|
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]);
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// 保存的时候计算x,y,w,h
|
|
|
var conputedInitData = function (type) {
|
|
|
if (type === 'save') {
|
|
|
let initDataCopy = JSON.parse(JSON.stringify(initData));
|
|
|
initDataCopy.children.forEach((item) => {
|
|
|
item.xCopy = item.x;
|
|
|
item.x = item.x * (1920 / 12);
|
|
|
item.yCopy = item.y;
|
|
|
item.y = item.y * cellHeight;
|
|
|
|
|
|
item.wCopy = item.w;
|
|
|
item.w = item.w * (1920 / 12);
|
|
|
if (!item.hasOwnProperty('h')) {
|
|
|
item.h = 1;
|
|
|
}
|
|
|
item.hCopy = item.h;
|
|
|
item.h = item.h * cellHeight;
|
|
|
});
|
|
|
console.log(initDataCopy);
|
|
|
return initDataCopy;
|
|
|
}
|
|
|
if (type === 'init') {
|
|
|
initData.children.forEach((item) => {
|
|
|
item.x = item.xCopy;
|
|
|
item.y = item.yCopy;
|
|
|
item.w = item.wCopy;
|
|
|
item.h = item.hCopy;
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
$('.save-container').click(function () {
|
|
|
// grid.addWidget({ w: 2, content: 'item 1' });
|
|
|
// console.log(grid.save());
|
|
|
// console.log(grid);
|
|
|
initData.children = grid.save();
|
|
|
console.log(initData);
|
|
|
localStorage.setItem('initData', JSON.stringify(conputedInitData('save')));
|
|
|
});
|
|
|
|
|
|
/** 执行方法 */
|
|
|
$(function () {
|
|
|
init();
|
|
|
// 调用绑定
|
|
|
bindComponentEvents();
|
|
|
});
|
|
|
})();
|