Commit 0fcc4e27 authored by 张晨辰's avatar 张晨辰

feat: 调整编辑区拖拽组件

parent acd1cda3
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
"cookie": "^0.4.0", "cookie": "^0.4.0",
"copy-to-clipboard": "^3.2.0", "copy-to-clipboard": "^3.2.0",
"core-js": "^2.6.5", "core-js": "^2.6.5",
"duiba-draggable-resizable": "^1.0.9",
"element-ui": "^2.4.5", "element-ui": "^2.4.5",
"jszip": "^3.2.2", "jszip": "^3.2.2",
"moment": "^2.24.0", "moment": "^2.24.0",
...@@ -34,6 +33,7 @@ ...@@ -34,6 +33,7 @@
"sass-loader": "^7.2.0", "sass-loader": "^7.2.0",
"vue-cli-plugin-element": "^1.0.1", "vue-cli-plugin-element": "^1.0.1",
"vue-cli-plugin-i18n": "^0.6.0", "vue-cli-plugin-i18n": "^0.6.0",
"vue-draggable-resizable": "^2.0.1",
"vue-template-compiler": "^2.6.10" "vue-template-compiler": "^2.6.10"
}, },
"appVersion": "0.1.0" "appVersion": "0.1.0"
......
<template> <template>
<div class="zero-custom-cmp zero-custom-node" v-html="selfText"></div> <div :style="customStyle" class="zero-custom-cmp zero-custom-node" v-html="selfText"></div>
</template> </template>
<style> <style>
.zero-custom-cmp{
position: absolute;
box-sizing: border-box;
}
</style> </style>
<script> <script>
export default { export default {
name: 'customNode', name: 'customNode',
props: { props: {
customStyle: {
type: String,
default: ''
},
properties: { properties: {
type: Object, type: Object,
default: () => {} default: () => {}
......
...@@ -10,9 +10,6 @@ import './assets/style.css' ...@@ -10,9 +10,6 @@ import './assets/style.css'
import './plugins/element.js' import './plugins/element.js'
import './themes/light/index.scss' import './themes/light/index.scss'
import VueDraggableResizable from 'duiba-draggable-resizable';
Vue.component('vue-draggable-resizable', VueDraggableResizable);
new Vue({ new Vue({
router, router,
store, store,
......
...@@ -47,6 +47,10 @@ const attrShortMapper = { ...@@ -47,6 +47,10 @@ const attrShortMapper = {
'source': 'background-image' 'source': 'background-image'
}; };
// 编辑时想拖拽组件需要生成的css属性
// 只需要位置,不需要来源透明度等等
const operatProps = ['x', 'y', 'width', 'height', 'rotate'];
// 属性单位 对照表, 如果是数值的时候需要添加单位 // 属性单位 对照表, 如果是数值的时候需要添加单位
const attrUnitMapper = { const attrUnitMapper = {
x: 'px', x: 'px',
...@@ -169,10 +173,10 @@ export const styles = { ...@@ -169,10 +173,10 @@ export const styles = {
return ['transform', [`rotate(${value}deg)`]]; //`transform: rotate(${value}deg);`; return ['transform', [`rotate(${value}deg)`]]; //`transform: rotate(${value}deg);`;
case 'background-image': case 'background-image':
return ['background-image', [`url(${value})`]]; //`background-image: url(${value});background-position:center;background-size:contain;`; return ['background-image', [`url(${value})`]]; //`background-image: url(${value});background-position:center;background-size:contain;`;
case 'scale-x': // case 'scale-x':
return ['transform', [`scaleX(${value})`]]; //`transform: scaleX(${value});`; // return ['transform', [`scaleX(${value})`]]; //`transform: scaleX(${value});`;
case 'scale-y': // case 'scale-y':
return ['transform', [`scaleY(${value})`]]; //`transform: scaleY(${value});`; // return ['transform', [`scaleY(${value})`]]; //`transform: scaleY(${value});`;
case 'visible': case 'visible':
return ['display', [value ? 'block' : 'none']]; // `display: ${value ? 'block' : 'none'};`; return ['display', [value ? 'block' : 'none']]; // `display: ${value ? 'block' : 'none'};`;
default: default:
...@@ -208,7 +212,10 @@ export const styles = { ...@@ -208,7 +212,10 @@ export const styles = {
* 根据组件数据,生成完整的style * 根据组件数据,生成完整的style
* @param {*} component * @param {*} component
*/ */
getComponentStyle(component, project, componentList) { getComponentStyle(component, project, componentList, onlyOpera) {
if (!component || !component.uuid) {
return '';
}
// debugger; // debugger;
let result = ''; let result = '';
let cmpSelfProps = completeSelfProps(component); let cmpSelfProps = completeSelfProps(component);
...@@ -223,6 +230,22 @@ export const styles = { ...@@ -223,6 +230,22 @@ export const styles = {
}); });
} }
if (cmpSelfProps.scaleX) {
cmpSelfProps.width *= cmpSelfProps.scaleX;
}
if (cmpSelfProps.scaleY) {
cmpSelfProps.height *= cmpSelfProps.scaleY;
}
if (onlyOpera) {
_.forIn(cmpSelfProps, (val, key) => {
if (operatProps.indexOf(key) === -1) {
delete cmpSelfProps[key];
}
});
}
// console.log('cmpSelfProps after inherit ', cmpSelfProps); // console.log('cmpSelfProps after inherit ', cmpSelfProps);
cmpSelfProps = styles.getStylesFromObj(cmpSelfProps, project); cmpSelfProps = styles.getStylesFromObj(cmpSelfProps, project);
_.forIn(cmpSelfProps, (value, key) => { _.forIn(cmpSelfProps, (value, key) => {
......
...@@ -6,32 +6,165 @@ ...@@ -6,32 +6,165 @@
:key="item.uuid" :key="item.uuid"
v-for="item in componentList" v-for="item in componentList"
> >
<wrapper :component-data="item"/> <wrap :component-data="item"/>
</div> </div>
<template v-if="!!this.activeComponentId">
<vue-draggable-resizable
:prevent-deactivation="true"
class-name="db-draggable"
:min-width="1"
:min-height="1"
:z="2"
:active="true"
:style="styleObject"
v-bind="position"
@dragging="handleDragging"
@resizing="handleResize"
@resizestop="resizeStop"
@deactivated="handleDeactivated"
>
</vue-draggable-resizable>
</template>
</div> </div>
<div class="zero-draw-panel-body"></div>
</div> </div>
</template> </template>
<style lang="less">
</style>
<script> <script>
import { mapGetters } from 'vuex'; import { mapState, mapGetters } from 'vuex';
import wrapper from './wrapper'; import wrap from './wrap';
import { styles, getParentCmps } from '../../../utils/common';
import properties from '../../../utils/properties';
import VueDraggableResizable from 'vue-draggable-resizable';
export default { export default {
components: { wrapper }, components: { wrap, VueDraggableResizable },
methods: { methods: {
activeComponent(item) { handleDeactivated() {
this.$store.dispatch('activeComponent', item); // this.$store.dispatch('changeEditaleStatus', false);
},
handleResize(x, y, w, h) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponent.properties;
if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
this.$store.dispatch('modifyProperties', {
x: x,
y: y,
width: w,
height: h
});
console.log('handleResize', x, y, w, h);
}
}, },
changeActiveIdList(item) {
this.$store.commit('changeActiveIdList', item); handleDragging(x, y) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponent.properties;
if (_prop.x !== x || _prop.y !== y) {
this.$store.dispatch('modifyProperties', {
x: x,
y: y
});
console.log('handleDragging', x, y);
}
},
resizeStop(x, y, w, h) {
console.log('resizeStop', x, y, w, h);
} }
}, },
computed: { computed: {
...mapGetters(['componentList']) ...mapState(['project']),
...mapGetters(['activeComponent', 'componentList', 'activeComponentId']),
active() {
return !!this.activeComponentId;
// return this.activeComponentId === (this.activeComponent || {}).uuid;
},
styleObject() {
return styles.getComponentStyle(this.activeComponent, this.project, this.componentList, true);
},
position() {
let _props = this.activeComponent.properties || {};
const _node = properties.node;
// console.log('********', _props);
let result = {
x: _props.x || _node.x.value,
y: _props.y || _node.y.value,
w: _props.width || _node.width.value,
h: _props.height || _node.height.value
};
console.log('####position', result);
return result;
}
} }
}; };
</script> </script>
<style lang="scss">
.db-draggable {
position: absolute;
box-sizing: border-box;
&.active {
border: 1px dashed black;
}
}
.handle {
box-sizing: border-box;
display: none;
position: absolute;
width: 10px;
height: 10px;
font-size: 1px;
background: #EEE;
border: 1px solid #333;
}
.handle-tl {
top: -10px;
left: -10px;
cursor: nw-resize;
}
.handle-tm {
top: -10px;
left: 50%;
margin-left: -5px;
cursor: n-resize;
}
.handle-tr {
top: -10px;
right: -10px;
cursor: ne-resize;
}
.handle-ml {
top: 50%;
margin-top: -5px;
left: -10px;
cursor: w-resize;
}
.handle-mr {
top: 50%;
margin-top: -5px;
right: -10px;
cursor: e-resize;
}
.handle-bl {
bottom: -10px;
left: -10px;
cursor: sw-resize;
}
.handle-bm {
bottom: -10px;
left: 50%;
margin-left: -5px;
cursor: s-resize;
}
.handle-br {
bottom: -10px;
right: -10px;
cursor: se-resize;
}
</style>
<template>
<!-- <vue-draggable-resizable
:minw="1"
:minh="1"
:z="2"
:style="styleObject"
:class="[active ? 'choosed-cmp' : 'unchoosed-cmp', isTyping && 'isTyping']"
v-bind="position"
@dragging="handleDragging"
@resizing="handleResize"
@deactivated="handleDeactivated"
>
<div
class="sword-compomnent-content-wrapper"
:contenteditable="false"
@dblclick="handleEnableInput"
@input="handleInput"
@keyup.delete.prevent="changeEditRange"
>
</div>
</vue-draggable-resizable> -->
<custom-node :custom-style="styleObject" :properties="componentData.properties"></custom-node>
</template>
<script>
import { mapState, mapGetters } from 'vuex';
import { styles } from '../../../utils/common';
import customNode from '../../../components/customElement/node/index.vue';
export default {
props: {
componentData: {
type: Object,
require: true
}
},
data() {
return {};
},
components: {
'custom-node': customNode
},
computed: {
...mapState(['project']),
...mapGetters(['componentList']),
styleObject() {
return styles.getComponentStyle(this.componentData, this.project, this.componentList);
}
}
};
</script>
<style>
</style>
...@@ -76,7 +76,7 @@ export default { ...@@ -76,7 +76,7 @@ export default {
if (!this.active) { if (!this.active) {
return false; return false;
} }
let _prop = this.componentData.properties; let _prop = this.activeComponentId.properties;
if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) { if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
this.$store.dispatch('modifyProperties', { this.$store.dispatch('modifyProperties', {
......
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