(function () { let main = { grid: null, initData: null, }; let welcome = { grid: null, initData: null, }; let currentComponent = null; let cellHeight = 60; let locale = 'en'; var initGridStack = () => { // 让gridstack知道如何渲染,组件children中的content直接渲染html GridStack.renderCB = function (el, w) { el.innerHTML = w.content; }; GridStack.setupDragIn('#components-panel .component-item', undefined, [ { w: 2, h: 2, type: 'image', name: userLangConfig[locale].user.image_default_name, background: '#fff', image: '', eventsType: 'click', eventsAction: '', defaultFocus: false, leftId: '', rightId: '', upId: '', downId: '', focusedStyle_background: '', focusedStyle_border_width: 0, focusedStyle_border_color: '', focusedStyle_scale: 1, }, { w: 2, h: 1, type: 'text', childrenType: '', name: userLangConfig[locale].user.text_default_name, background: '#fff', fontSize: 14, color: '#333', text: userLangConfig[locale].user.text_default_content, fontWeight: 'normal', eventsType: 'click', eventsAction: '', defaultFocus: false, leftId: '', rightId: '', upId: '', downId: '', focusedStyle_background: '', focusedStyle_border_width: 0, focusedStyle_border_color: '', focusedStyle_scale: 1, }, ]); }; // 生成唯一id var generateUniqueId = function () { const timestamp = Date.now().toString(36); const randomNum = Math.random().toString(36).substring(2); return timestamp + randomNum; }; // 判断是画布还是组件 var isScreen = function (type) { return type === 'screen'; }; /** 初始化 */ var init = function (type, self) { const initDataStorage = self['initData']; if (!initDataStorage) { self['initData'] = { type: 'screen', id: `grid_${generateUniqueId()}`, children: [], version: '1.0.0', width: 1920, height: 1080, background: '#e2e2e2', image: '', // 为画布添加image属性 }; } else { conputedInitData('init', self); } self['initData'].el = document.getElementById(`${type}-screen`); console.log(self['initData'], `${type}Data`); // 初始化时应用画布背景 const canvasId = `${type}-screen`; if (self.initData.image) { $('#' + canvasId) .css('background-image', `url(${self.initData.image})`) .css('background-size', 'cover'); } else if (self.initData.background) { $('#' + canvasId).css('background-color', self.initData.background); } self['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: self['initData'].children, }, `#${type}-screen` ); // console.log(self['grid'], `${type}.grid实例`); // grid.load(initData.children); self['grid'].engine.nodes.forEach((item) => { handleAddComponent(item, self); }); self['grid'].on('added', function (_event, itemArray) { console.log(itemArray, '这里触发了添加了added事件'); itemArray.forEach((item) => { handleAddComponent(item, self); }); }); self['grid'].on('removed', function (_event, itemArray) { console.log(itemArray, '这里触发了移除removed事件'); itemArray.forEach((item) => { handleRemoveComponent(item); }); }); }; // 处理添加组件之后的操作 var handleAddComponent = (component, self) => { if (!component.id) { component.id = `${component.type}_${generateUniqueId()}`; } // 组件首次加载或被添加到画布时,调用 setComponentView,且没有传递 `fields` 参数。这意味着对组件进行一次完整渲染。它会读取组件对象上所有的初始属性,并一股脑地应用到DOM元素上,确保组件从一开始就显示正确的样式。 setComponentView(component); component.el.addEventListener('click', (e) => { e.stopPropagation(); console.log(isScreen(component.type) ? `点击画布` : `点击组件`, component); if (currentComponent && currentComponent.id === component.id) { return; } // 清除之前选中组件的获取焦点后的样式 clearOldFocusStyle(); currentComponent = component; // 右侧显示组件属性列表 if (!$('#props-panel').find('form').is(':visible')) { $('#props-panel').find('.wait-box').hide(); $('#props-panel').find('form').show(); } // 将当前选中组件的属性显示在右侧列表中 setCurrentComponentProps(currentComponent); // 非画布时设置 if (!isScreen(component.type)) { // 设置当前选中组件的获取焦点后的样式 setCurrentFocusStyle(); // 设置上下左右移动组件ID setMoveComponentId(currentComponent, self); } }); }; var clearOldFocusStyle = function () { if (currentComponent && !isScreen(currentComponent.type)) { let el = $(currentComponent.el).find('.grid-stack-item-content'); el.css('background', 'none'); if (currentComponent.image) { el.find('img').attr('src', currentComponent.image); } if (currentComponent.background) { el.css('background', currentComponent.background); } el.css('border-color', ''); el.css('border-width', ''); el.css('transform', ''); } }; var setCurrentFocusStyle = function () { if (currentComponent && !isScreen(currentComponent.type)) { let el = $(currentComponent.el).find('.grid-stack-item-content'); if (currentComponent.focusedStyle_background) { el.css('background', currentComponent.focusedStyle_background); } el.css('border-color', currentComponent.focusedStyle_border_color); el.css('border-width', currentComponent.focusedStyle_border_width + 'px'); el.css('transform', `scale(${currentComponent.focusedStyle_scale})`); } }; // 设置上下左右移动组件ID var setMoveComponentId = function (component, self) { const allComponents = self['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 el = $(`#${idName}`); let componentsHtml = [{ value: '', text: el.find('option').eq(0).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] }); }); el.empty(); componentsHtml.forEach((item) => { el.append( $('