Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Z
zeroing-editor
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
劳工
zeroing-editor
Commits
acd1cda3
Commit
acd1cda3
authored
Oct 18, 2019
by
张晨辰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: undo redo
parent
e7b8cd9d
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
182 additions
and
151 deletions
+182
-151
SampleMenu.vue
src/components/SampleMenu.vue
+1
-1
index.vue
src/components/customSettings/slider/index.vue
+0
-3
index.vue
src/components/customSettings/source/index.vue
+24
-1
en.json
src/locales/en.json
+3
-1
project.js
src/store/modules/project.js
+67
-41
common.js
src/utils/common.js
+29
-13
Editor.vue
src/views/Editor.vue
+6
-0
ToolBar.vue
src/views/Editor/ToolBar.vue
+16
-9
drawPanel.vue
src/views/Editor/components/drawPanel.vue
+1
-1
dynamicComponent.vue
src/views/Editor/components/dynamicComponent.vue
+3
-4
wrapper.vue
src/views/Editor/components/wrapper.vue
+32
-77
No files found.
src/components/SampleMenu.vue
View file @
acd1cda3
<
template
>
<div
class=
"menu"
>
<el-badge
class=
"menu-item"
v-for=
"(item, key) of data"
:key=
"key"
is-dot
:hidden=
"!menuBadge(key)"
>
<el-link
@
click=
"clickItem(key)"
:icon=
"item.icon"
>
<el-link
@
click=
"clickItem(key)"
:icon=
"item.icon"
:disabled=
"item.disabled"
>
{{
item
.
text
}}
</el-link>
</el-badge>
...
...
src/components/customSettings/slider/index.vue
View file @
acd1cda3
...
...
@@ -36,9 +36,6 @@ export default {
swvalue
:
this
.
value
||
0
};
},
mounted
()
{
console
.
log
(
'slider created'
,
this
.
value
);
},
watch
:
{
swvalue
(
v
)
{
this
.
$emit
(
'change'
,
v
);
...
...
src/components/customSettings/source/index.vue
View file @
acd1cda3
<
template
>
<el-input
v-model=
"swvalue"
@
drop
.
native=
"drop"
@
dragover
.
native=
"dragOver"
></el-input>
<el-popover
placement=
"top"
trigger=
"hover"
width=
"auto"
:content=
"url"
>
<img
v-if=
"url"
:src=
"url"
alt=
""
/>
<el-input
v-model=
"swvalue"
slot=
"reference"
@
drop
.
native=
"drop"
@
dragover
.
native=
"dragOver"
></el-input>
</el-popover>
</
template
>
<
style
>
</
style
>
...
...
@@ -29,6 +37,21 @@ export default {
dragOver
(
e
)
{
e
.
preventDefault
();
}
},
computed
:
{
url
:
function
()
{
if
(
this
.
swvalue
)
{
if
(
this
.
swvalue
.
indexOf
(
'asset://'
)
>
-
1
)
{
let
uuid
=
this
.
swvalue
.
split
(
'//'
)[
1
];
let
_ass
=
this
.
$store
.
state
.
project
.
data
.
assets
.
find
(
a
=>
a
.
uuid
===
uuid
);
return
_ass
?
_ass
.
url
:
''
;
}
else
{
return
this
.
swvalue
;
}
}
else
{
return
''
;
}
}
}
};
</
script
>
src/locales/en.json
View file @
acd1cda3
...
...
@@ -66,7 +66,9 @@
"preview"
:
"Preview"
,
"publish"
:
"Publish"
,
"data-mapping"
:
"DataMapping"
,
"exit"
:
"Exit"
"exit"
:
"Exit"
,
"undo"
:
"Undo"
,
"redo"
:
"Redo"
},
"view_node_menu"
:
{
"node"
:
"Node"
,
...
...
src/store/modules/project.js
View file @
acd1cda3
...
...
@@ -8,7 +8,7 @@ import { projectApi } from "../../api";
// import { compoleteComponentData } from '../../utils/compoleteCmpData';
import
path
from
"path"
;
import
generateUUID
from
"uuid/v4"
;
import
{
getCmpProps
}
from
'../../utils/common'
;
import
{
getCmpProps
,
flattenViews
,
getCmpByUUID
}
from
'../../utils/common'
;
import
{
saveAs
}
from
"../../utils"
;
export
const
projectStore
=
{
...
...
@@ -26,6 +26,8 @@ export const projectStore = {
activeViews
:
''
,
dragUUID
:
''
,
dirty
:
false
,
operateStack
:
[],
stackIndex
:
0
},
mutations
:
{
setDirty
(
state
,
dirty
=
true
)
{
...
...
@@ -62,23 +64,39 @@ export const projectStore = {
state
.
activeComponent
.
properties
=
state
.
activeComponent
.
properties
||
{};
console
.
log
(
'mutations activeComponent'
,
state
);
}
// state.activeComponent = item;
},
/**
* 修改当前组件的属性
* @param {*} state
* @param {*} data
*/
modifyProperties
(
state
,
data
)
{
if
(
!
data
||
!
data
.
label
)
{
modifyProperties
(
state
,
props
)
{
if
(
!
props
)
{
return
;
}
let
_prop
=
_
.
cloneDeep
(
state
.
activeComponent
.
properties
||
{});
_prop
[
data
.
label
]
=
data
.
value
;
// state.activeComponent.properties[data.label] = data.value;
if
(
state
.
operateStack
.
length
)
{
// state.operateStack.shift();
if
(
state
.
stackIndex
!==
0
)
{
state
.
operateStack
=
state
.
operateStack
.
slice
(
state
.
stackIndex
);
}
}
else
{
state
.
operateStack
.
unshift
({
uuid
:
state
.
activeComponent
.
uuid
,
properties
:
_
.
cloneDeep
(
_prop
)
});
}
state
.
stackIndex
=
0
;
// 开始编辑的时候,重置操作栈的下标
_prop
=
Object
.
assign
({},
_prop
,
props
);
state
.
operateStack
.
unshift
({
uuid
:
state
.
activeComponent
.
uuid
,
properties
:
_
.
cloneDeep
(
_prop
)
});
Vue
.
set
(
state
.
activeComponent
,
'properties'
,
_prop
);
console
.
log
(
'modifyProperties'
,
state
.
activeComponent
);
console
.
log
(
'operateStack'
,
state
.
operateStack
);
// console.log('modifyProperties', state.activeComponent);
},
/**
* 修改当前组件
...
...
@@ -112,6 +130,28 @@ export const projectStore = {
console
.
log
(
'assetDragStart'
,
data
);
state
.
dragUUID
=
data
.
uuid
;
},
/**
* 重做/撤销
* @param {*} state
* @param {*} step
*/
undoRedo
(
state
,
step
)
{
let
_beforeStack
=
state
.
operateStack
[
state
.
stackIndex
];
state
.
stackIndex
+=
step
;
let
_afterStack
=
state
.
operateStack
[
state
.
stackIndex
];
if
(
_beforeStack
.
uuid
!==
_afterStack
.
uuid
)
{
// 如果uuid不一样,说明是不同节点的操作,需要把下标多移动一位
state
.
stackIndex
+=
step
;
}
console
.
log
(
'undoRedo'
,
state
.
stackIndex
);
let
_operate
=
state
.
operateStack
[
state
.
stackIndex
];
if
(
_operate
)
{
let
_cmp
=
getCmpByUUID
(
_operate
.
uuid
,
state
.
data
.
views
);
if
(
_cmp
)
{
_cmp
.
properties
=
_operate
.
properties
;
}
}
},
modifyProject
(
state
,
)
{
},
...
...
@@ -205,13 +245,6 @@ export const projectStore = {
* 当前激活的组件
*/
activeComponent
:
state
=>
{
// if (state.activeComponent) {
// let _cmp = state.activeComponent || {}
// console.log('activeComponent', _cmp);
// return { ..._cmp, uuid: _cmp.uuid || generateUUID() }
// } else {
// return {};
// }
return
state
.
activeComponent
;
},
/**
...
...
@@ -224,21 +257,6 @@ export const projectStore = {
* 扁平化所有节点
*/
componentList
:
state
=>
{
const
flatten
=
arr
=>
{
return
arr
.
reduce
((
flat
,
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
])
:
[];
...
...
@@ -246,7 +264,7 @@ export const projectStore = {
_view
=
state
.
data
.
views
.
filter
(
v
=>
v
.
uuid
===
state
.
activeViews
)
}
let
result
=
flatten
(
_
.
cloneDeep
(
_view
));
let
result
=
flatten
Views
(
_
.
cloneDeep
(
_view
));
console
.
log
(
'componentList'
,
result
);
return
result
;
}
...
...
@@ -296,7 +314,8 @@ export const projectStore = {
* @param {*} param
* @param {*} data
*/
activeComponent
({
commit
,
state
},
data
)
{
activeComponent
(
context
,
data
)
{
// debugger;
let
getTopView
=
node
=>
{
if
(
node
.
parent
&&
!
node
.
parent
.
parent
)
{
return
node
;
...
...
@@ -307,20 +326,24 @@ export const projectStore = {
let
_view
=
getTopView
(
data
.
node
);
if
(
_view
&&
_view
.
data
)
{
state
.
activeViews
=
_view
.
data
.
uuid
;
context
.
state
.
activeViews
=
_view
.
data
.
uuid
;
}
commit
(
'activeComponent'
,
data
.
data
);
// let _cmp = context.getters.componentList.find(c => c.uuid === data.data.uuid)
context
.
commit
(
'activeComponent'
,
data
.
data
);
},
/**
* 修改属性
*/
modifyProperties
({
commit
,
state
},
data
)
{
modifyProperties
({
commit
,
state
},
props
)
{
// debugger;
// 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度
if
(
data
.
label
===
'source'
)
{
let
_source
=
Object
.
keys
(
props
).
indexOf
(
'source'
)
>
-
1
;
if
(
_source
)
{
let
_props
=
state
.
activeComponent
.
properties
;
if
(
!
_props
.
width
||
!
_props
.
height
)
{
let
_url
=
data
.
value
;
let
_url
=
props
[
'source'
];
//_source
.value;
if
(
_url
.
indexOf
(
'asset://'
)
===
0
)
{
let
uuid
=
_url
.
split
(
'//'
)[
1
];
let
asset
=
state
.
data
.
assets
.
find
(
a
=>
a
.
uuid
===
uuid
);
...
...
@@ -329,12 +352,15 @@ export const projectStore = {
let
_img
=
new
Image
();
_img
.
src
=
_url
;
_img
.
onload
=
function
()
{
commit
(
'modifyProperties'
,
{
label
:
'width'
,
value
:
_img
.
width
});
commit
(
'modifyProperties'
,
{
label
:
'height'
,
value
:
_img
.
height
});
commit
(
'modifyProperties'
,
{
width
:
_img
.
width
,
height
:
_img
.
height
});
}
}
}
commit
(
'modifyProperties'
,
data
)
commit
(
'modifyProperties'
,
props
)
},
/**
* 修改组件
...
...
@@ -349,6 +375,6 @@ export const projectStore = {
zip
.
generateAsync
({
type
:
"blob"
}).
then
(
function
(
content
)
{
saveAs
(
content
,
`view-
${
view
.
name
}
.zrv`
);
});
}
,
}
},
};
src/utils/common.js
View file @
acd1cda3
...
...
@@ -80,22 +80,38 @@ function getParentCmps(uuid, list) {
export
{
getParentCmps
,
completeSelfProps
};
/**
* 移除组件从父级继承的属性
* @param {*} cmp
* @param {*} list
*/
export
const
removeParentProps
=
function
(
cmp
,
list
)
{
export
const
getCmpByUUID
=
function
(
uuid
,
views
)
{
if
(
!
uuid
)
{
return
null
;
}
let
_node
=
views
.
find
(
v
=>
v
.
uuid
===
uuid
);
if
(
_node
)
{
return
_node
}
else
{
for
(
let
index
=
0
;
index
<
views
.
length
;
index
++
)
{
if
(
views
[
index
].
children
&&
views
[
index
].
children
.
length
)
{
return
getCmpByUUID
(
uuid
,
views
[
index
].
children
)
}
}
}
}
/**
* 根据
* @param {*} cmp
* @param {*} list
* 扁平化视图数组
* @param {*} views
*/
export
const
buildPropsByParent
=
function
(
cmp
,
list
)
{
export
const
flattenViews
=
function
(
views
)
{
return
views
.
reduce
((
flat
,
toFlat
)
=>
{
if
(
toFlat
.
children
)
{
let
_children
=
toFlat
.
children
.
map
(
c
=>
{
c
.
parent
=
toFlat
.
uuid
;
return
c
;
});
return
flat
.
concat
([
toFlat
].
concat
(
flattenViews
(
_children
)));
}
else
{
return
flat
.
concat
([
toFlat
]);
}
},
[]);
}
/**
...
...
@@ -217,7 +233,7 @@ export const styles = {
});
result
+=
`background-position: center;background-size: 100% 100%;`
//
console.log('getComponentStyle', result);
console
.
log
(
'getComponentStyle'
,
result
);
return
result
;
}
}
...
...
src/views/Editor.vue
View file @
acd1cda3
...
...
@@ -157,6 +157,12 @@
case
'details'
:
this
.
$refs
.
projectDialogsDialog
.
show
();
break
;
case
'undo'
:
this
.
$store
.
commit
(
'undoRedo'
,
1
);
break
;
case
'redo'
:
this
.
$store
.
commit
(
'undoRedo'
,
-
1
);
break
;
case
'data-mapping'
:
this
.
$refs
.
dataMappingDialog
.
show
();
break
;
...
...
src/views/Editor/ToolBar.vue
View file @
acd1cda3
...
...
@@ -18,19 +18,26 @@
name
:
"ToolBar"
,
components
:
{
SampleMenu
},
data
()
{
const
menuConfig
=
this
.
$t
(
'menu'
);
const
menu
=
{};
for
(
let
item
of
Object
.
keys
(
menuConfig
))
{
menu
[
item
]
=
{
text
:
menuConfig
[
item
]}
}
return
{
menu
,
}
return
{}
},
computed
:
{
...
mapState
([
'project'
])
]),
menu
:
function
()
{
const
menuConfig
=
this
.
$t
(
'menu'
);
let
menu
=
{};
for
(
let
item
of
Object
.
keys
(
menuConfig
))
{
menu
[
item
]
=
{
text
:
menuConfig
[
item
],
disabled
:
false
}
}
if
(
menu
[
'undo'
])
{
menu
[
'undo'
][
'disabled'
]
=
!
this
.
project
.
operateStack
.
length
||
this
.
project
.
operateStack
.
length
===
this
.
project
.
stackIndex
+
1
}
if
(
menu
[
'redo'
])
{
menu
[
'redo'
][
'disabled'
]
=
this
.
project
.
stackIndex
===
0
;
}
return
menu
;
}
},
methods
:
{
clickMenu
(
menuItem
)
{
...
...
src/views/Editor/components/drawPanel.vue
View file @
acd1cda3
...
...
@@ -17,7 +17,7 @@
</
style
>
<
script
>
import
{
map
State
,
mapActions
,
map
Getters
}
from
'vuex'
;
import
{
mapGetters
}
from
'vuex'
;
import
wrapper
from
'./wrapper'
;
export
default
{
...
...
src/views/Editor/components/dynamicComponent.vue
View file @
acd1cda3
...
...
@@ -137,10 +137,9 @@ export default {
methods
:
{
handleChange
(
v
)
{
console
.
log
(
'handleChange'
,
v
);
this
.
$store
.
dispatch
(
'modifyProperties'
,
{
label
:
this
.
label
,
value
:
v
});
let
_prop
=
{};
_prop
[
this
.
label
]
=
v
;
this
.
$store
.
dispatch
(
'modifyProperties'
,
_prop
);
},
handleInput
(
v
)
{
if
(
this
.
item
.
type
===
'input'
)
{
...
...
src/views/Editor/components/wrapper.vue
View file @
acd1cda3
...
...
@@ -28,7 +28,7 @@
import
{
mapState
,
mapGetters
}
from
'vuex'
;
import
{
styles
,
getParentCmps
}
from
'../../../utils/common'
;
import
properties
from
'../../../utils/properties'
;
import
customNode
from
'../../../components/customElement/node/index.vue'
import
customNode
from
'../../../components/customElement/node/index.vue'
;
export
default
{
props
:
{
...
...
@@ -44,7 +44,7 @@ export default {
return
{};
},
components
:
{
"custom-node"
:
customNode
'custom-node'
:
customNode
},
methods
:
{
handleEnableInput
()
{
...
...
@@ -72,75 +72,38 @@ export default {
// id: this.cmpId
// });
},
handleResize
(
left
,
top
,
w
,
h
)
{
const
id
=
this
.
cmpId
;
handleResize
(
x
,
y
,
w
,
h
)
{
if
(
!
this
.
active
)
{
return
false
;
}
let
_prop
=
this
.
componentData
.
properties
;
// this.$store.dispatch('batchModifyComponent', [
// {
// key: ['bindings', 'outline', 'position', 'top', 'v'],
// value: top,
// id
// },
// {
// key: ['bindings', 'outline', 'position', 'left', 'v'],
// value: left,
// id
// },
// {
// key: ['bindings', 'outline', 'position', 'width', 'v'],
// value: w,
// id
// },
// {
// key: ['bindings', 'outline', 'position', 'height', 'v'],
// value: h,
// id
// }
// ]);
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
);
}
},
handleDragging
(
left
,
top
)
{
handleDragging
(
x
,
y
)
{
if
(
!
this
.
active
)
{
return
false
;
}
console
.
log
(
'handleDragging'
,
left
,
top
);
// console.log('getParentCmps', getParentCmps);
let
_prop
=
this
.
componentData
.
properties
;
if
(
_prop
.
x
!==
x
||
_prop
.
y
!==
y
)
{
this
.
$store
.
dispatch
(
'modifyProperties'
,
{
x
:
x
,
y
:
y
});
console
.
log
(
'handleDragging'
,
x
,
y
);
}
// 文本编辑状态 与 位置锁定状态无法拖动
// if (
// this.isTyping ||
// path(
// ['bindings', 'outline', 'position', 'fixed', 'v'],
// this.componentData
// )
// ) {
// return -1;
// }
// const leftKeys = ['bindings', 'outline', 'position', 'left', 'v'];
// const topKeys = ['bindings', 'outline', 'position', 'top', 'v'];
// if (this.$store.state.activeIdList.length > 1) {
// // 多组件移动
// this.$store.dispatch('modifyComponentListPosition', {
// leftDistance: left - path(leftKeys, this.componentData),
// topDistance: top - path(topKeys, this.componentData)
// });
// } else {
// // console.log('active component change---------');
// // 单组件移动
// const id = this.cmpId;
// this.$store.dispatch('activeComponent', id);
// this.$store.dispatch('modifyComponent', {
// key: leftKeys,
// value: left,
// id
// });
// this.$store.dispatch('modifyComponent', {
// key: topKeys,
// value: top,
// id
// });
// }
// return 0;
}
},
computed
:
{
...
...
@@ -162,26 +125,15 @@ export default {
position
()
{
let
_props
=
this
.
componentData
.
properties
||
{};
const
_node
=
properties
.
node
;
console
.
log
(
'********'
,
_props
);
//
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
);
// if (this.active) {
// return result;
// } else {
// return {
// x: 30,
// y: 30,
// w: 40,
// h: 40
// }
// }
return
result
;
}
},
...
...
@@ -204,6 +156,9 @@ export default {
.vdr.active
{
border-color
:
transparent
;
}
.vdr.active.unchoosed-cmp
{
border
:
none
;
}
.vdr.choosed-cmp
{
border
:
1px
solid
rgba
(
157
,
172
,
255
,
0.9
);
cursor
:
move
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment