You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
12 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

(function () {
let initData = null;
let grid = null;
let currentComponent = null;
let cellHeight = 60;
// 生成唯一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: 0,
minRow: Math.floor(1080 / 2 / cellHeight),
maxRow: Math.floor(1080 / 2 / cellHeight),
acceptWidgets: true,
float: true,
removable: '#trash',
// subGridOpts: subOptions,
// subGridDynamic: true,
children: initData.children,
});
GridStack.setupDragIn('#components-panel .component-item', undefined, [
{
w: 2,
h: 2,
type: 'image',
name: '图片',
image: '',
eventsType: 'click',
eventsAction: '',
defaultFocus: false,
leftId: '',
rightId: '',
upId: '',
downId: '',
},
{
w: 2,
h: 1,
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 * 2;
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 * 2;
});
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();
});
})();