Commit deae8d5b authored by 张晨辰's avatar 张晨辰

feat: 节点属性继承

parent 058d0999
......@@ -34,6 +34,8 @@ export default new Vuex.Store({
'addDataMapping',
'deleteDataMapping',
'modifyDataMapping',
'modifyComponent',
'modifyProperties'
]
})
]
......
......@@ -224,19 +224,29 @@ export const projectStore = {
* 扁平化所有节点
*/
componentList: state => {
// debugger;
const flatten = arr => {
return arr.reduce((flat, toFlat) => {
return flat.concat(toFlat.children ? flatten(toFlat.children).concat([toFlat]) : [toFlat]);
if (toFlat.children) {
let _children = toFlat.children.map(c => {
c.parent = toFlat.uuid;
return c;
});
return flat.concat([toFlat].concat(flatten(_children)));
} else {
return flat.concat([toFlat]);
}
// return flat.concat(toFlat.children ? flatten(toFlat.children).concat([toFlat]) : [toFlat]);
}, []);
};
// 如果有选中的节点,则展示对应的视图组
// 否则展示第一个视图组
let _view = state.data.views.length ? [].concat(state.data.views[0]) : [];
if (state.activeViews) {
_view = state.data.views.filter(v => v.uuid === state.activeViews)
}
// debugger;
let result = flatten(_view);
// let result = state.data.views.flatMap(v => [v, v.children || []])
let result = flatten(_.cloneDeep(_view));
console.log('componentList', result);
return result;
}
......
......@@ -15,6 +15,17 @@ export const componentsMap = [{
value: 'rect'
}];
// 属性的计算方法
const propsComputeRules = {
left: 'add',
top: 'add',
rotate: 'add',
scaleX: 'multi',
scaleY: 'multi',
alpha: 'multi',
visible: 'visible'
}
const isClient = typeof window !== 'undefined';
function changeCamle(s) {
......@@ -49,9 +60,71 @@ const attrUnitMapper = {
minHeight: 'px'
};
// function getAssetByUUID(asset, uuid){
// return
// }
/**
* 根据uuid,从list中找到所有父组件
* @param {*} uuid
* @param {*} list
*/
function getParentCmps(uuid, list) {
let _self = list.find(c => c.uuid === uuid);
let parentLoop = (uuid, list) => {
let _item = list.find(c => c.uuid === uuid);
return _item.parent ? [_item].concat(parentLoop(_item.parent, list)) : [_item];
}
return _self.parent ? parentLoop(_self.parent, list) : [];
}
export { getParentCmps, buildCompleteProps };
/**
* 移除组件从父级继承的属性
* @param {*} cmp
* @param {*} list
*/
export const removeParentProps = function(cmp, list) {
}
/**
* 根据propsComputeRules的计算规则,继承父级的属性
* @param {*} props
* @param {*} parent
*/
function inheritProps(props, parent) {
_.forIn(parent, (value, key) => {
let rule = propsComputeRules[key];
// 加法
if (rule === 'add') {
props[key] += parent[key];
}
// 乘法
if (rule === 'multi') {
props[key] *= parent[key];
}
// 可见,特殊处理
if (rule === 'visible') {
props[key] = !props[key] || !parent[key] ? false : true;
}
});
}
function buildCompleteProps(component) {
// 根据组件类型,获取默认属性
let defaultProps = getCmpProps(component.type);
// omit从defaultProps中过滤出组件properties中没有的属性,格式参考properties.js
defaultProps = _.omit(defaultProps, _.keys(component.properties));
// 再把这些属性格式转换成key: value
defaultProps = _.mapValues(defaultProps, o => (o.value));
// 将组件properties中的属性和默认属性拼装成组件自身的属性
return {
...component.properties,
...defaultProps
}
}
export const styles = {
getStyles(value, key) {
......@@ -99,27 +172,32 @@ export const styles = {
}
});
return resultObj;
},
/**
* 根据组件数据,生成完整的style
* @param {*} component
*/
getComponentStyle(component, project) {
getComponentStyle(component, project, componentList) {
// debugger;
let result = '';
let cmpSelfProps = buildCompleteProps(component);
// 根据uuid获取节点的所有父节点
let propsMatrix = getParentCmps(component.uuid, componentList);
propsMatrix = propsMatrix.map(buildCompleteProps);
console.log('propsMatrix', propsMatrix);
console.log('cmpSelfProps', cmpSelfProps);
if (propsMatrix.length) {
propsMatrix.forEach(prop => {
inheritProps(cmpSelfProps, prop);
});
}
// 根据组件类型,获取默认属性
let defaultProps = getCmpProps(component.type);
defaultProps = _.omit(defaultProps, _.keys(component.properties));
defaultProps = _.mapValues(defaultProps, o => (o.value));
console.log('cmpSelfProps after inherit ', cmpSelfProps);
let _cmpProps = styles.getStylesFromObj(component.properties, project);
let _defaultProps = styles.getStylesFromObj(defaultProps, project);
cmpSelfProps = styles.getStylesFromObj(cmpSelfProps, project);
_.forIn({
..._defaultProps,
..._cmpProps
}, (value, key) => {
_.forIn(cmpSelfProps, (value, key) => {
result += `${key}: ${value.join(' ')};`
});
result += `background-position: center;background-size: contain;`
......
......@@ -2,8 +2,7 @@
<vue-draggable-resizable
:minw="1"
:minh="1"
:z="1"
:otherstatus="true"
:z="2"
:style="styleObject"
:class="[active ? 'choosed-cmp' : 'unchoosed-cmp', isTyping && 'isTyping']"
v-bind="position"
......@@ -27,7 +26,7 @@
<script>
import { mapState, mapGetters } from 'vuex';
import { getComposedComponents } from '../../../utils/getComposedComponents';
import { styles } from '../../../utils/common';
import { styles, getParentCmps } from '../../../utils/common';
import properties from '../../../utils/properties';
const composedComponents = getComposedComponents();
......@@ -101,6 +100,12 @@ export default {
},
handleDragging(left, top) {
if (!this.active) {
return false;
}
console.log('handleDragging', left, top);
// console.log('getParentCmps', getParentCmps);
// 文本编辑状态 与 位置锁定状态无法拖动
// if (
// this.isTyping ||
......@@ -140,7 +145,7 @@ export default {
},
computed: {
...mapState(['project']),
...mapGetters(['activeComponentId']),
...mapGetters(['activeComponentId', 'componentList']),
active() {
return this.activeComponentId === (this.componentData || {}).uuid;
},
......@@ -154,18 +159,47 @@ export default {
styleObject() {
console.log('wrapper styleObject');
return styles.getComponentStyle(this.componentData, this.project);
return styles.getComponentStyle(this.componentData, this.project, this.componentList);
},
position() {
const componentData = this.componentData;
componentData.properties = componentData.properties || {};
// const componentData = this.componentData;
let _props = this.componentData.properties;
// componentData.properties = componentData.properties || {};
const _node = properties.node;
console.log('*******left', _props.left, _node.left.value);
console.log('*******top', _props.top, _node.top.value);
let _left = _props.left || _node.left.value;
let _top = _props.top || _node.top.value;
if (_props.left) {
return {
x: componentData.properties.left || _node.left.value,
y: componentData.properties.top || _node.top.value,
w: componentData.properties.width || _node.width.value,
h: componentData.properties.height || _node.height.value
x: 50,
y: _props.top,
w: _props.width || _node.width.value,
h: _props.height || _node.height.value
};
} else {
return {
x: 50,
y: 50,
w: 100,
h: 100
};
}
// return {
// x: 50,
// y: 50,
// w: _props.width || _node.width.value,
// h: _props.height || _node.height.value
// };
// return {
// x: _props.left || _node.left.value,
// y: _props.top || _node.top.value,
// w: _props.width || _node.width.value,
// h: _props.height || _node.height.value
// };
}
},
watch: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment