1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
import Vue from 'vue';
export default class SketchRender {
constructor(browserId, browserPropsId, canvasId, files) {
this.browserId = browserId;
this.browserPropsId = browserPropsId;
this.browserStore = {
currentPageIndex: 0,
pages: [],
activeLayer: '',
backgroundColor: {
hex: '#000000',
rgba: 'rgba(0,0,0,1)'
},
hasBackgroundColor: false,
hasFill: false,
style: {
blendingMode: 0,
opacity: 1
}
currentPos: {
x: 0,
y: 0,
width: 0,
height: 0
}
};
this.files = files;
if(this.files.hasOwnProperty('document.json')){
this.files['document.json'].async('string')
.then(content => this.renderDocument(JSON.parse(content)));
}
};
render() {
Vue.component('layer', {
name: 'layer',
template:
`<li class="layer" :class="{artboard: layer._class === 'artboard'}">
<a href='#' class="expand pull-left" @click.prevent="expand" v-if="layer.layers">
<span v-if="!expanded">+</span>
<span v-else>-</span>
</a>
<i v-if="layer._class === 'group'" class="fa fa-folder pull-left"></i>
<i v-if="layer._class === 'text'" class="fa fa-font pull-left"></i>
<i v-if="layer._class === 'shapeGroup'" class="fa fa-th-large"></i>
<i v-if="layer._class === 'rectangle'" class="fa fa-square"></i>
<i v-if="layer._class === 'shapePath'" class="fa fa-heart-o"></i>
<i v-if="layer._class === 'symbolInstance'" class="fa fa-refresh"></i>
<i v-if="layer._class === 'symbolMaster'" class="fa fa-refresh"></i>
<i v-if="layer.isLocked" class="fa fa-lock pull-right"></i>
<a href='#' @click.prevent="layerSelected(layer)" :title="layer.name">{{layer.name}}</a>
<ul v-if="layer.layers && expanded">
<layer :active-layer="activeLayer" :class="{active: activeLayer === layer.do_objectID}" v-for="layer in layer.layers" @layerselected="layerSelected" :key="layer.do_objectID" :layer="layer"></layer>
</ul>
</li>`,
props: {
layer: Object,
activeLayer: ""
},
data() {
return {
expanded: false
}
},
methods: {
expand() {
this.expanded = !this.expanded;
},
layerSelected(layer) {
this.$emit('layerselected', layer);
}
}
});
this.vue = new Vue({
el: `#${this.browserId}`,
data: this.browserStore,
computed: {
currentPage() {
return this.pages.length ? this.pages[this.currentPageIndex] : {name: 'loading', layers: []};
}
},
methods: {
rgbToHex(r, g, b) {
r *= 255;
g *= 255;
b *= 255;
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
},
pageSelected(pageIndex) {
this.currentPageIndex = pageIndex;
this.browserStore.currentPos.x = this.browserStore.pages[this.currentPageIndex].frame.x;
this.browserStore.currentPos.y = this.browserStore.pages[this.currentPageIndex].frame.y;
this.browserStore.currentPos.width = this.browserStore.pages[this.currentPageIndex].frame.width;
this.browserStore.currentPos.height = this.browserStore.pages[this.currentPageIndex].frame.height;
},
setBackgroundColor(bgColor) {
if(bgColor){
this.backgroundColor = this.backgroundColor || {};
this.backgroundColor.hex = this.rgbToHex(bgColor.red, bgColor.green, bgColor.blue);
bgColor.red = parseInt(bgColor.red * 255);
bgColor.green = parseInt(bgColor.green * 255);
bgColor.blue = parseInt(bgColor.blue * 255);
this.backgroundColor.rgba = `rgba(${bgColor.red}, ${bgColor.green}, ${bgColor.blue}, ${bgColor.alpha})`
}
},
setFill(bgColor) {
},
setBlendingMode(layer) {
if(layer.hasOwnProperty('style')){
}
},
setOpacity(layer) {
if(layer.hasOwnProperty('style')){
}
},
layerSelected(layer) {
this.currentPos.x = layer.frame.x;
this.currentPos.y = layer.frame.y;
this.currentPos.width = layer.frame.width;
this.currentPos.height = layer.frame.height;
this.activeLayer = layer.do_objectID;
this.hasBackgroundColor = layer.hasBackgroundColor;
this.setBackgroundColor(layer.backgroundColor);
setBlendingMode(layer);
setOpacity(layer);
console.log('layer',layer);
}
}
});
this.vuePos = new Vue({
el: `#${this.browserPropsId}`,
data: this.browserStore
});
};
storePage(pageJSON) {
if(pageJSON){
var page = JSON.parse(pageJSON);
page.isActive = false;
this.browserStore.pages.push(page);
}
};
renderDocument(documentJSON) {
var pages = documentJSON.pages.map(page => `${page._ref}.json`);
this.currentPageIndex = documentJSON.currentPageIndex;
pages.reduce((seq, page) => {
return seq.then((e) => {
this.storePage(e);
return this.files[page].async('string');
});
}, Promise.resolve())
.then((e) => {
this.storePage(e)
this.browserStore.currentPos.x = this.browserStore.pages[this.currentPageIndex].frame.x;
this.browserStore.currentPos.y = this.browserStore.pages[this.currentPageIndex].frame.y;
});
};
};
|