使用vuetify重构

This commit is contained in:
Next 2020-04-07 00:51:08 +08:00
parent 515259a06b
commit a6462012a1
35 changed files with 224 additions and 13173 deletions

View File

@ -1,4 +1,4 @@
# ccc-devtools v2.3.3 # ccc-devtools v3.0.0
Cocos Creator 网页调试工具,运行时查看、修改节点树,实时更新节点属性,可视化显示缓存资源。 Cocos Creator 网页调试工具,运行时查看、修改节点树,实时更新节点属性,可视化显示缓存资源。
## 预览 ## 预览

539
config.js
View File

@ -4,350 +4,24 @@ const NEX_CONFIG = {
title: 'Node', title: 'Node',
key: 'cc.Node', key: 'cc.Node',
rows: [ rows: [
// Position { name: 'Name', key: 'name', type: 'text' },
[{ { name: 'X', key: 'x', type: 'number' },
type: 'label', { name: 'Y', key: 'y', type: 'number' },
span: 6, { name: 'Width', key: 'width', type: 'number' },
field: 'Position' { name: 'Height', key: 'height', type: 'number' },
}, { { name: 'Angle', key: 'angle', type: 'number' },
type: 'label', { name: 'ScaleX', key: 'scaleX', type: 'number' },
span: 1, { name: 'ScaleY', key: 'scaleY', type: 'number' },
field: 'X' { name: 'Opacity', key: 'opacity', type: 'number' },
}, { { name: 'Color', key: 'hex_color', type: 'color' },
type: 'number', { name: 'Group', key: 'group', type: 'text' },
span: 8,
field: 'x'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 8,
field: 'y'
}],
// Angle
[{
type: 'label',
span: 6,
field: 'Angle'
}, {
type: 'number',
span: 18,
field: 'angle'
}],
// Scale
[{
type: 'label',
span: 6,
field: 'Scale'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 8,
field: 'scaleX'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 8,
field: 'scaleY'
}],
// Anchor
[{
type: 'label',
span: 6,
field: 'Anchor'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 8,
field: 'anchorX'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 8,
field: 'anchorY'
}],
// Size
[{
type: 'label',
span: 6,
field: 'Size'
}, {
type: 'label',
span: 1,
field: 'W'
}, {
type: 'number',
span: 8,
field: 'width'
}, {
type: 'label',
span: 1,
field: 'H'
}, {
type: 'number',
span: 8,
field: 'height'
}],
// Color
[{
type: 'label',
span: 6,
field: 'Color',
}, {
type: 'color',
span: 18,
field: 'hex_color',
rawField: 'color',
}],
// Opacity
[{
type: 'label',
span: 6,
field: 'Opacity'
}, {
type: 'number',
span: 18,
field: 'opacity'
}],
// Skew
[{
type: 'label',
span: 6,
field: 'Skew'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 8,
field: 'skewX'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 8,
field: 'skewY'
}],
// Group
[{
type: 'label',
span: 6,
field: 'Group'
}, {
type: 'input',
span: 18,
field: 'group'
}]
] ]
}, },
node3d: { node3d: {
title: 'Node', title: 'Node',
key: 'cc.Node', key: 'cc.Node',
rows: [ rows: [
// Position // TODO:
[{
type: 'label',
span: 6,
field: 'Position'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 5,
field: 'x'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 5,
field: 'y'
}, {
type: 'label',
span: 1,
field: 'Z'
}, {
type: 'number',
span: 5,
field: 'z'
}],
// Angle
[{
type: 'label',
span: 6,
field: 'Rotation'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: '3DAngle',
span: 5,
field: 'x'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: '3DAngle',
span: 5,
field: 'y'
}, {
type: 'label',
span: 1,
field: 'Z'
}, {
type: '3DAngle',
span: 5,
field: 'z'
}],
// Scale
[{
type: 'label',
span: 6,
field: 'Scale'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 5,
field: 'scaleX'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 5,
field: 'scaleY'
}, {
type: 'label',
span: 1,
field: 'Z'
}, {
type: 'number',
span: 5,
field: 'scaleZ'
}],
// Anchor
[{
type: 'label',
span: 6,
field: 'Anchor'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 8,
field: 'anchorX'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 8,
field: 'anchorY'
}],
// Size
[{
type: 'label',
span: 6,
field: 'Size'
}, {
type: 'label',
span: 1,
field: 'W'
}, {
type: 'number',
span: 8,
field: 'width'
}, {
type: 'label',
span: 1,
field: 'H'
}, {
type: 'number',
span: 8,
field: 'height'
}],
// Color
[{
type: 'label',
span: 6,
field: 'Color',
}, {
type: 'color',
span: 18,
field: 'hex_color',
rawField: 'color',
}],
// Opacity
[{
type: 'label',
span: 6,
field: 'Opacity'
}, {
type: 'number',
span: 18,
field: 'opacity'
}],
// Skew
[{
type: 'label',
span: 6,
field: 'Skew'
}, {
type: 'label',
span: 1,
field: 'X'
}, {
type: 'number',
span: 8,
field: 'skewX'
}, {
type: 'label',
span: 1,
field: 'Y'
}, {
type: 'number',
span: 8,
field: 'skewY'
}],
// Group
[{
type: 'label',
span: 6,
field: 'Group'
}, {
type: 'input',
span: 18,
field: 'group'
}]
] ]
}, },
}, },
@ -356,198 +30,23 @@ const NEX_CONFIG = {
title: 'cc.Camera', title: 'cc.Camera',
key: 'cc.Camera', key: 'cc.Camera',
rows: [ rows: [
// Zoom Ratio { name: 'Zoom Ratio', key: 'zoomRatio', type: 'number' },
[{ { name: 'Depth', key: 'depth', type: 'number' },
type: 'label', { name: 'Bacground Color', key: 'hex_backgroundColor', rawKey: 'backgroundColor', type: 'color' },
span: 6,
field: 'Zoom Ratio'
}, {
type: 'number',
span: 18,
field: 'zoomRatio'
}],
// Background Color
[{
type: 'label',
span: 6,
field: 'Bg Color'
}, {
type: 'color',
span: 18,
field: 'hex_backgroundColor',
rawField: 'backgroundColor'
}],
// Depth
[{
type: 'label',
span: 6,
field: 'Depth'
}, {
type: 'number',
span: 18,
field: 'depth'
}],
] ]
}, },
'cc.Sprite': { 'cc.Sprite': {
key: 'cc.Sprite', key: 'cc.Sprite',
title: 'cc.Sprite', title: 'cc.Sprite',
rows: [ rows: []
// Type
[{
type: 'label',
span: 6,
field: 'Type'
}, {
type: 'select',
span: 18,
field: 'type',
options: [{
label: 'SIMPLE',
value: 0
}, {
label: 'SLICED',
value: 1
}, {
label: 'TILED',
vlaue: 2
}, {
label: 'FILLED',
value: 3
}, {
label: 'MESH',
value: 4
}]
}],
// Size Mode
[{
type: 'label',
span: 6,
field: 'Size Mode'
}, {
type: 'select',
span: 18,
field: 'sizeMode',
options: [{
label: 'CUSTOM',
value: 0
}, {
label: 'TRIMMED',
value: 1
}, {
label: 'RAW',
vlaue: 2
}]
}],
// Trim
[{
type: 'label',
span: 6,
field: 'Trim'
}, {
type: 'bool',
span: 18,
field: 'trim'
}],
]
}, },
'cc.Label': { 'cc.Label': {
title: 'cc.Label', title: 'cc.Label',
key: 'cc.Label', key: 'cc.Label',
rows: [ rows: [
// String { name: 'String', key: 'string', type: 'textarea' },
[{ { name: 'Font Size', key: 'fontSize', type: 'number' },
type: 'label', { name: 'Line Height', key: 'lineHeight', type: 'number' },
span: 6,
field: 'String'
}, {
type: 'textarea',
span: 18,
field: 'string'
}],
// Horizontal Align
[{
type: 'label',
span: 6,
field: 'Horizontal'
}, {
type: 'select',
span: 18,
field: 'horizontalAlign',
options: [{
label: 'LEFT',
value: 0
}, {
label: 'CENTER',
value: 1
}, {
label: 'RIGHT',
value: 2
}]
}],
// Vertical Align
[{
type: 'label',
span: 6,
field: 'Vertical'
}, {
type: 'select',
span: 18,
field: 'verticalAlign',
options: [{
label: 'TOP',
value: 0
}, {
label: 'CENTER',
value: 1
}, {
label: 'BOTTOM',
value: 2
}]
}],
// Font Size
[{
type: 'label',
span: 6,
field: 'Font Size'
}, {
type: 'number',
span: 18,
field: 'fontSize'
}],
// Line Height
[{
type: 'label',
span: 6,
field: 'Line Height',
}, {
type: 'number',
span: 18,
field: 'lineHeight'
}],
// Overflow
[{
type: 'label',
span: 6,
field: 'Overflow'
}, {
type: 'select',
span: 18,
field: 'overflow',
options: [{
label: 'NONE',
value: 0
}, {
label: 'CLAMP',
value: 1
}, {
label: 'SHRINK',
value: 2
}, {
label: 'RESIZE_HEIGHT',
value: 3
}]
}],
] ]
} }
} }

View File

@ -1,36 +0,0 @@
body {
background-color: #333;
}
.el-color-picker, .el-color-picker__trigger {
width: 100% !important;
}
.el-input-number .el-input__inner {
text-align: left;
}
.el-input-number.is-controls-right .el-input__inner {
padding-left: 5px;
padding-right: 5px;
}
.el-card__body {
padding-left: 20px;
padding-right: 10px;
}
.ivu-collapse-content {
color: #515a6e;
padding: 0 5px 0 16px;
background-color: #fff;
}
.el-input-number--mini .el-input-number__decrease, .el-input-number--mini .el-input-number__increase {
width: 12px;
font-size: 12px;
}
.el-select.el-select--mini {
width: 100%;
}

View File

@ -1,78 +0,0 @@
.ivu-split-trigger {
background: #444 !important;
}
.right-panel *,
.ivu-split-trigger,
.el-color-dropdown,
.el-color-dropdown *:not(.el-button--text),
.el-popover,
.el-popover * ,
#panelCtl .el-button{
border-color: #333 !important;
color: #bbb !important;
}
.el-popover,
.el-color-dropdown input,
.right-panel input,
.right-panel textarea,
.right-panel .el-checkbox__inner:not(.is-checked) {
background-color: #333 !important;
color: #bbb !important;
}
.right-panel button,
.right-panel span[role='button'],
.right-panel .ant-tree,
.right-panel .demo-split-pane,
.right-panel .el-card,
.right-panel .el-tree,
.el-color-dropdown,
.el-popover {
background-color: #222 !important;
}
.right-panel .el-button {
padding-left: 10px !important;
padding-right: 10px !important;
}
.right-panel .top-pane span,
.right-panel .ant-tree,
.right-panel .demo-split-pane,
.right-panel .el-card,
.right-panel .el-tree {
color: #aaa !important;
}
.right-panel .ant-tree-node-selected {
background-color: #456 !important;
}
.right-panel .ant-tree-node-content-wrapper:hover,
.right-panel .el-tree-node .el-tree-node__content:hover {
background-color: #567 !important;
}
.el-switch.is-checked .el-switch__core,
.el-tree-node.is-current .el-tree-node__content,
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #367 !important;
}
.right-panel .el-checkbox__label,
.right-panel .el-button,
.el-color-dropdown, button {
color: #59a !important;
background-color: #222 !important;
}
.tree-panel,
.prop-panel,
.ivu-modal-content,
.ivu-table-column-center,
.ivu-modal-header-inner {
background-color: #222 !important;
color: #bbb !important;
}

View File

@ -1,222 +1,155 @@
<link rel="stylesheet" type="text/css" href="app/editor/static/preview-templates/ccc-devtools/libs/vue-beauty/css/vue-beauty.min.css"> <link href="ccc-devtools/libs/css/materialdesignicons.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="app/editor/static/preview-templates/ccc-devtools/libs/element/css/element-ui.css"> <link href="ccc-devtools/libs/css/vuetify.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="app/editor/static/preview-templates/ccc-devtools/libs/iview/css/iview.css">
<link rel="stylesheet" type="text/css" href="app/editor/static/preview-templates/ccc-devtools/css/style.css">
<div id="app"> <v-app id="app">
<div v-if="isDevMode" style="display: flex;min-height: 100vh;"> <v-app-bar app clipped-left color="gray" dense v-if="true">
<!-- 左边游戏预览区域 --> <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<div id="game_panel" <!-- <v-toolbar-title class="mr-5 align-center">
style="display:flex;flex:auto;flex-direction: column;"> <span class="title"><a>ccc-devtools</a></span>
<div id="top" style="flex: none"></div> </v-toolbar-title> -->
</div> <div id="recompiling"><span>Recompiling...</span></div>
<!-- 右边节点树和属性区域 --> <v-spacer></v-spacer>
<div class="right-panel" style="flex: none;display: block;width: 400px;"> <div class="toolbar">
<!-- 节点树面板 --> <div class="item">
<div class="tree-panel" style="height: 50vh;overflow: auto;border-bottom: 1px solid #2d2d2d;"> <select id="opts-device">
<el-input v-if="!isAutoRefreshTree" placeholder="搜索节点" v-model="filterText" size="mini" <option value="0">Default</option>
id="searchInput"></el-input> </select>
<v-tree v-if="isDevMode&&isAutoRefreshTree" :data="sceneTreeData" ref="sceneTree" </div>
@select="handleNodesSelect" <div class="item">
style="min-width: 250px;height: 100%;overflow-x:hidden;overflow-y:auto;background: white;"> <v-btn id="btn-rotate" small height="25"><span style="color: #aaa;">Rotate</span></v-btn>
</v-tree> </div>
<el-tree v-if="isDevMode&&!isAutoRefreshTree" :data="sceneTreeData" :draggable="true" <span style="font-size: small;display: none;" class="item">Debug Mode:</span>
:props="nodeProps" :default-expanded-keys="defaultExpandedKeys" empty-text="暂无数据..." <div class="item" style="display: none;">
:node-key="'_id'" :expand-on-click-node="false" :filter-node-method="filterNode" <select id="opts-debug-mode">
ref="sceneTree" @node-click="handleNodeClick" <option value="0">None</option>
style="min-width: 250px;height: 100%;overflow-x:hidden;overflow-y:auto;"> <option value="1">Info</option>
<span class="custom-tree-node" slot-scope="{ node, data }"> <option value="2">Warn</option>
<span <option value="3">Error</option>
v-bind:style="{color: data.activeInHierarchy?'#606266':'#C0C4CC'}">{{ node.label }}</span> <option value="4">Info For Web Page</option>
</span> <option value="5">Warn For Web Page</option>
</el-tree> <option value="6">Error For Web Page</option>
<el-button v-if="!isAutoRefreshTree" @click="handleRefreshTree" icon="el-icon-refresh" </select>
size="mini" style="position: absolute;right:0;top:0;"></el-button> </div>
<div style="position: absolute;right:0;bottom:51vh;width: 100px;height:20px;"> <div class="item">
<span style="line-height:20px;">自动刷新</span> <v-btn id="btn-show-fps" small height="25"><span style="color: #aaa;">Show FPS</span></v-btn>
<el-switch v-model="isAutoRefreshTree" active-color="#0099ff" inactive-color="gray"> </div>
</el-switch> <div class="item">
</div> <span style="font-size: small;color: #aaa;" class="item">FPS:</span><input id="input-set-fps"
type="number" />
</div>
<div style="margin-right: 0px;" class="item">
<v-btn id="btn-pause" small height="25"><span style="color: #aaa;">Pause</span></v-btn>
</div>
<div class="item">
<v-btn id="btn-step" style="display: none;" small height="25">
<span style="color: #aaa;">Step</span>
</v-btn>
</div>
<div class="item">
<v-btn id="btn-recompile" small height="25"><span style="color: #aaa;">Recompile</span></v-btn>
</div>
</div>
</v-app-bar>
<!-- <el-button @click="handleSwitchTreeMode" icon="el-icon-refresh" size="mini" style="position: absolute;right:0;bottom:0;"></el-button> --> <v-navigation-drawer v-model="drawer" app clipped fixed width="512">
</div> <v-container style="height: 50%;overflow: auto;">
<!-- 节点属性面板 --> <v-text-field v-model="treeSearchText" dense label="Search Node or Component" dark flat solo-inverted
<div class="prop-panel" style="background: white;height: 50vh;overflow:auto;"> hide-details clearable clear-icon="mdi-close-circle-outline"></v-text-field>
<div v-if="node"> <v-treeview :items="treeData" item-key="id" dense activatable :search="treeSearchText"
<el-row style="margin:5px 0;"> :active.sync="selectedNodes">
<el-col :span="2" style="text-align:center;padding-top:7px;padding-left:5px;"> <template v-slot:label="{ item, active }">
<el-checkbox v-model="node.active"></el-checkbox> <label v-if="item.active" style="color: white;">{{ item.name }}</label>
</el-col> <label v-else style="color: gray;">{{ item.name }}</label>
<el-col :span="18"> </template>
<el-input v-model="node.name" size="mini"></el-input> </v-treeview>
</el-col> </v-container>
<el-col :span="4"> <v-container style="border-top: 2px solid darkgray;height: 50%;overflow-y: auto;">
<div style="width: 100%;height:28px;border: solid 1px rgb(220, 223, 230);border-radius: 4px;text-align: center;" <template v-if="selectedNode">
@click="handleChangeNodeSchema"><span style="line-height: 28px;" <!-- Node -->
:style="{color: is3DNode?'#409EFF':'#606266'}">2.5d</span></div> <table style="width: 100%;color: white;" border="1">
</el-col> <thead>
<tr>
<th colspan="2" style="text-align: left; padding: 10px;">
<div class="float-left" style="display:inline-flex;">
<v-simple-checkbox v-model="selectedNode.active"></v-simple-checkbox>
<span style="margin-left: 10px;">{{ nodeSchema.title }}</span>
</div>
<div class="float-right">
<v-icon style="margin-left: 10px;margin-right: 10px;">mdi-adjust</v-icon>
<v-icon>mdi-send</v-icon>
</div>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in nodeSchema.rows" :key="row.key">
<td style="padding: 10px;width: 40%;">{{ row.name }}</td>
<td style="width: 60%;">
<v-color-picker v-if="row.type == 'color'" class="ma-2" canvas-height="80" width="259"
hide-inputs v-model="selectedNode[row.key]"></v-color-picker>
<input v-else :type="row.type" v-model="selectedNode[row.key]"
style="padding: 10px;width: 100%;"></input>
</td>
</tr>
</tbody>
</table>
<!-- Components -->
<table v-for="component in componentsSchema" style="width: 100%;color: white;" border="1">
<thead>
<tr>
<th colspan="2" style="text-align: left; padding: 10px;">
<div class="float-left" style="display:inline-flex;">
<v-simple-checkbox v-model="selectedNode[component.key].enabled">
</v-simple-checkbox>
<span style="margin-left: 10px;">{{ component.title }}</span>
</div>
<div class="float-right">
<v-icon>mdi-send</v-icon>
</div>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in component.rows" :key="row.key">
<td style="padding: 10px;width: 40%;">{{ row.name }}</td>
<td style="width: 60%;">
<v-color-picker v-if="row.type == 'color'" class="ma-2" canvas-height="80" width="259"
hide-inputs v-model="selectedNode[component.key][row.key]"></v-color-picker>
<textarea v-else-if="row.type == 'textarea'" rows="1"
v-model="selectedNode[component.key][row.key]" style="padding: 10px;width: 100%;">
</textarea>
<input v-else :type="row.type" v-model="selectedNode[component.key][row.key]"
style="padding: 10px;width: 100%;"></input>
</td>
</tr>
</tbody>
</table>
</template>
</v-container>
</v-navigation-drawer>
</el-row> <v-content>
<el-card v-if="nodeSchema"> <v-container fill-height>
<div> <div id="content" class="content">
<span>{{ nodeSchema.title }}</span> <div class="contentWrap">
<el-button style="float: right; padding: 3px 0;" type="text" <div id="GameDiv" class="wrapper"><canvas id="GameCanvas"></canvas>
@click="outputNodeHandler">输出引用</el-button> <div id="splash">
<el-button style="float: right; padding: 3px 0;margin-right: 10px;" type="text" <div class="progress-bar stripes"><span></span></div>
@click="drawNodeRect">标记位置</el-button> </div>
</div> <div id="bulletin">
<hr style="margin: 10px 0;" /> <div id="sceneIsEmpty" class="inner">预览场景中啥都没有,加点什么,或在编辑器中打开其它场景吧</div>
<div> </div>
<el-row style="height: 28px;margin-bottom:3px;" v-for="(row, ri) in nodeSchema.rows" </div>
:key="ri"> </div>
<el-col v-for="(col, ci) in row" :key="ci" :span="col.span" </div>
style="text-align: left;line-height: 28px;"> </v-container>
<span v-if="col.type == 'label'">{{col.field}}</span> </v-content>
<el-input-number v-if="col.type == 'number'" v-model="node[col.field]"
controls-position="right" size="mini" style="width: 100%;">
</el-input-number>
<el-input-number v-if="col.type == '3DAngle'"
v-model="node.eulerAngles[col.field]" controls-position="right"
size="mini" style="width: 100%;"></el-input-number>
<el-input v-if="col.type == 'input'" v-model="node[col.field]" size="mini">
</el-input>
<el-color-picker v-if="col.type == 'color'" :ref="col.key" size="mini"
v-model="node[col.field]"></el-color-picker>
</el-col>
</el-row>
</div>
</el-card>
<el-card v-for="(section,index) in componentsSchema" :key="section.key"
style="margin: 10px 0;">
<div>
<el-checkbox v-model="node[section.key].enabled">{{ section.title }}</el-checkbox>
<el-button style="float: right; padding: 3px 0" type="text"
@click="outputComponentHandler(section.key)">输出引用</el-button>
</div>
<hr v-if="section.rows" style="margin: 10px 0;" />
<div>
<el-row style="height: 28px;margin-bottom:3px;" v-for="(row,ri) in section.rows"
:key="ri">
<el-col v-for="(col,ci) in row" :key="ci" :span="col.span"
style="text-align: left;line-height: 28px;">
<span v-if="col.type == 'label'">{{col.field}}</span>
<el-input-number v-if="col.type == 'number'"
v-model="node[section.key][col.field]" controls-position="right"
size="mini" style="width: 100%;"></el-input-number>
<el-input v-if="col.type == 'input'" v-model="node[section.key][col.field]"
size="mini"></el-input>
<el-input v-if="col.type == 'textarea'" type="textarea" :rows="1"
v-model="node[section.key][col.field]" size="mini">
</el-input>
<el-color-picker v-if="col.type == 'color'" :ref="col.key" size="mini"
v-model="node[section.key][col.field]"></el-color-picker>
<el-checkbox v-if="col.type == 'bool'"
v-model="node[section.key][col.field]"></el-checkbox>
<el-select v-if="col.type == 'select'"
v-model="node[section.key][col.field]" size="mini">
<el-option v-for="item in col.options" :key="item.value"
:label="item.label" :value="item.value">
</el-option>
</el-select>
</el-col>
</el-row>
</div>
</el-card>
</div>
</div>
</div>
</div>
<!-- 控制按钮 -->
<div id="panelCtl" style="position:absolute;left:5px;top:50px;height: 50px;display: flex;align-items: center;">
<el-popover width="150" placement="top-start" trigger="click">
<el-button type="info" icon="el-icon-setting" circle slot="reference" size="mini"></el-button>
<div>
<el-row style="margin:5px 0;">
<el-col :span="12" style="text-align:left;padding-top:7px;padding-left:5px;">
节点树
</el-col>
<el-col :span="12">
<el-switch style="margin: 5px;" v-model="isDevMode" @change="handleChangeMode"
active-color="#0099ff" inactive-color="gray">
</el-switch>
</el-col>
</el-row>
<el-row style="margin:5px 0;">
<el-col :span="12" style="text-align:left;padding-top:7px;padding-left:5px;">
调试信息
</el-col>
<el-col :span="12">
<el-switch style="margin: 5px;" v-model="isShowProfile" @change="handleChangeStats"
active-color="#0099ff" inactive-color="gray">
</el-switch>
</el-col>
</el-row>
<el-row style="margin:5px 0;">
<el-col :span="12" style="text-align:left;padding-top:7px;padding-left:5px;">
缓存
</el-col>
<el-col :span="12">
<el-switch style="margin: 5px;" v-model="isShowCache" @change="handleChangeCachePanel"
active-color="#0099ff" inactive-color="gray">
</el-switch>
</el-col>
</el-row>
<el-row style="margin:5px 0;">
<el-col :span="12" style="text-align:left;padding-top:7px;padding-left:5px;">
暗黑主题
</el-col>
<el-col :span="12">
<el-switch style="margin: 5px;" v-model="isDarkTheme" @change="handleChangeTheme"
active-color="#0099ff" inactive-color="gray">
</el-switch>
</el-col>
</el-row>
<el-row style="margin:5px 0;">
<el-col :span="12" style="text-align:left;padding-top:7px;padding-left:5px;">
检查版本
</el-col>
<el-col :span="12">
<el-switch style="margin: 5px;" v-model="isCheckVersion" @change="handleChangeCheckVersion"
active-color="#0099ff" inactive-color="gray">
</el-switch>
</el-col>
</el-row>
<el-row style="margin:5px 0;">
<el-col :span="12" style="text-align:left;padding-top:7px;padding-left:5px;">
源码
</el-col>
<el-col :span="12">
<el-badge value="new" :hidden="!needUpdate">
<Icon style="margin: 5px;" type="logo-github" size="24" @click="openGithub" />
</el-badge>
</el-col>
</el-row>
</div>
</el-popover>
</div>
<!-- 缓存面板弹窗 -->
<Modal v-model="isShowCache" width="800" :mask-closable="false" :mask="false" scrollable @on-cancel="closeCachePanel()" :title="cacheTitle" footer-hide="true">
<i-table border :columns="cacheColumns" height="600" size="small" :data="cacheData" :loading="cacheDataLoading">
<template slot-scope="{ row, index }" slot="cache_preview">
<img :src="window.location.protocol + '//' + window.location.host + '/' + row.preview" style="max-height: 40px;max-width: 120px;" v-if="row.preview">
<div v-if="!row.preview" style="max-height: 40px;">_</div>
</template>
<template slot-scope="{ row, index }" slot="cache_action">
<i-button type="primary" size="small" @click="showCacheItem(row.id)">Detail</i-button>
<i-button type="error" size="small" @click="releaseCacheItem(row.id)">Release</i-button>
</template>
<template slot-scope="{ row, index }" slot="cache_size">
{{row.size !== -1 ? row.size + 'MB' : '_'}}
</template>
</i-table>
</Modal>
</div>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/libs/vue/vue.min.js"></script> </v-app>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/libs/vue-beauty/js/vue-beauty.min.js"></script>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/libs/element/js/element-ui.js"></script>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/libs/iview/js/iview.js"></script>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/libs/stats/Stats.js"></script>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/config.js"></script>
<script type="text/javascript" charset="utf-8" src="app/editor/static/preview-templates/ccc-devtools/js/app.js"></script>
<script src="ccc-devtools/libs/js/vue.min.js"></script>
<script src="ccc-devtools/libs/js/vuetify.js"></script>
<script src="ccc-devtools/config.js"></script>
<script src="ccc-devtools/preview.js"></script>
<!-- app/editor/static/preview-templates/ -->

596
js/app.js
View File

@ -1,596 +0,0 @@
let app = new Vue({
el: '#app',
data: {
needUpdate: false,
is3DNode: false,
isDevMode: false,
isShowProfile: false,
isShowCache: false,
isAutoRefreshTree: true,
isDarkTheme: false,
isCheckVersion: false,
filterText: '',
splitLeft: 0.7,
splitRight: 0.5,
defaultExpandedKeys: [],
sceneTreeData: [],
nodeProps: {
children: 'children',
label: 'name',
isLeaf: 'leaf'
},
node: null,
nodeSchema: {},
componentsSchema: [],
intervalId: -1,
cacheTitle: '缓存',
cacheColumns: [{
title: 'Type',
key: 'content',
width: 150,
align: 'center',
filters: [{
label: 'png',
value: 'png'
}, {
label: 'jpg',
value: 'jpg'
}, {
label: 'cc.Texture2D',
value: 'cc.Texture2D'
}, {
label: 'cc.SpriteFrame',
value: 'cc.SpriteFrame'
}, {
label: 'cc.Sprite',
value: 'cc.Sprite'
}, {
label: 'cc.Prefab',
value: 'cc.Prefab'
}, {
label: 'cc.AnimationClip',
value: 'cc.AnimationClip'
}],
filterMultiple: false,
filterMethod(value, row) {
return row.content === value;
}
}, {
title: 'Name',
key: 'name',
width: 220,
align: 'center',
sortable: true
}, {
title: 'Size',
slot: 'cache_size',
key: 'size',
align: 'center',
width: 120,
sortable: true
}, {
title: 'Preview',
slot: 'cache_preview',
align: 'center',
width: 150
}, {
title: 'Queue',
key: 'queueId',
sortable: true,
width: 120,
align: 'center'
}, {
title: 'Action',
slot: 'cache_action',
width: 150,
align: 'center',
fixed: 'right'
}],
cacheData: [],
cacheDataLoading: false
},
methods: {
api: function (url, cb) {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
let response = xhr.responseText;
cb(JSON.parse(xhr.responseText));
}
};
xhr.open("GET", url, true);
xhr.send();
},
compareVersion: function (localVersion, remoteVersion) {
let vL = localVersion.split('.');
let vR = remoteVersion.split('.');
for (let i = 0; i < vL.length; ++i) {
let a = parseInt(vL[i], 10);
let b = parseInt(vR[i] || '0', 10);
if (a === b) {
continue;
} else if (a > b) {
return false;
} else if (a < b) {
return true;
}
}
if (vR.length > vL.length) {
return true;
} else {
return false;
}
},
checkVersion: function () {
this.api('https://raw.githubusercontent.com/potato47/ccc-devtools/master/version.json', (
data) => {
let remoteVersion = data.version;
this.api('app/editor/static/preview-templates/ccc-devtools/version.json', (
data) => {
let localVersion = data.version;
versionStatus = this.compareVersion(localVersion, remoteVersion);
this.$data.needUpdate = versionStatus;
console.groupCollapsed('ccc-devtoos')
console.log('本地版本:' + localVersion);
console.log('远程版本:' + remoteVersion);
console.log('更新地址:' + 'https://github.com/potato47/ccc-devtools.git');
console.groupEnd('ccc-devtoos');
});
});
},
handleRefreshTree() {
this.$data.sceneTreeData = [];
setTimeout(() => {
this.updateTreeData();
}, 0);
},
handleSwitchTreeMode() {
},
updateTreeData() {
this.$data.sceneTreeData = cc.director.getScene().children;
this.defaultExpandedKeys = [this.$data.sceneTreeData[0]._id];
},
handleNodesSelect(nodes) {
if (nodes.length === 1) {
this.handleNodeClick(nodes[0]);
} else {
this.handleNodeClick(null);
}
},
handleNodeClick(node) {
if (node) {
this.$data.node = node;
if (!node.hex_color) {
cc.js.getset(node, 'hex_color', () => {
return '#' + node.color.toHEX('#rrggbb');
}, (hex) => {
node.color = new cc.Color().fromHEX(hex);
}, false, true);
}
let superPreLoad = node._onPreDestroy;
node._onPreDestroy = () => {
superPreLoad.apply(node);
if (this.$data && this.$data.node === node) {
this.$data.node = null;
}
}
this.$data.nodeSchema = this.$data.is3DNode ? NEX_CONFIG.nodeSchema.node3d : NEX_CONFIG
.nodeSchema.node2d;
let componentsSchema = [];
for (let component of node._components) {
let schema = NEX_CONFIG.componentsSchema[component.__classname__];
if (schema) {
node[schema.key] = node.getComponent(schema.key);
for (let i = 0; i < schema.rows.length; i++) {
for (let j = 0; j < schema.rows[i].length; j++) {
if (schema.rows[i][j].type === 'color') {
if (!node[schema.key][schema.rows[i][j].field]) {
cc.js.getset(node[schema.key], schema.rows[i][j].field, () => {
return '#' + node.getComponent(schema.key)[schema.rows[i][j]
.rawField].toHEX('#rrggbb');
}, (hex) => {
node.getComponent(schema.key)[schema.rows[i][j].rawField] =
new cc.Color().fromHEX(hex);
}, false, true);
}
}
}
}
} else {
schema = {
title: component.__classname__,
key: component.__classname__
};
node[schema.key] = node.getComponent(schema.key);
}
componentsSchema.push(schema);
}
this.$data.componentsSchema = componentsSchema;
} else {
this.$data.node = null;
}
},
outputNodeHandler(target) {
let i = 1;
while (window['temp' + i] !== undefined) {
i++;
}
window['temp' + i] = this.$data.node;
console.log('temp' + i);
console.log(window['temp' + i]);
},
outputComponentHandler(data) {
let i = 1;
while (window['temp' + i] !== undefined) {
i++;
}
window['temp' + i] = this.$data.node.getComponent(data);
console.log('temp' + i);
console.log(window['temp' + i]);
},
drawNodeRect(node) {
cc.where(this.$data.node);
},
releaseCacheItem(id) {
console.log('resease item ', id);
cc.loader.release(id);
},
showCacheItem(id) {
console.log(cc.loader._cache[id]);
},
openGithub() {
window.open('https://github.com/potato47/ccc-devtools');
},
filterNode(value, node) {
if (!value) return true;
return node.name.toLowerCase().indexOf(value.toLowerCase()) !== -1;
},
openCachePanel() {
this.$data.cacheDataLoading = true;
setTimeout(() => {
let rawCacheData = cc.loader._cache;
let cacheData = [];
let totalTextureSize = 0;
for (let k in rawCacheData) {
let item = rawCacheData[k];
// console.log(item)
if (item.type !== 'js' && item.type !== 'json') {
let itemName = '_';
let preview = '';
let content = item.content.__classname__ ? item.content.__classname__ : item.type;
let formatSize = -1;
if (item.type === 'png' || item.type === 'jpg') {
let texture = rawCacheData[k.replace('.' + item.type, '.json')];
if (texture && texture._owner && texture._owner._name) {
itemName = texture._owner._name;
preview = texture.content.url;
}
} else {
if (item.content.name && item.content.name.length > 0) {
itemName = item.content.name;
} else if (item._owner) {
itemName = item._owner.name || '_';
}
if (content === 'cc.Texture2D') {
let texture = item.content;
preview = texture.url;
let textureSize = texture.width * texture.height * ((texture._native === '.jpg' ? 3 : 4) / 1024 / 1024);
totalTextureSize += textureSize;
// sizeStr = textureSize.toFixed(3) + 'M';
formatSize = Math.round(textureSize * 1000) / 1000;
} else if (content === 'cc.SpriteFrame') {
preview = item.content._texture.url;
}
}
cacheData.push({
queueId: item.queueId,
type: item.type,
name: itemName,
preview: preview,
id: item.id,
content: content,
size: formatSize
});
}
}
this.$data.cacheData = cacheData;
this.$data.cacheTitle = `缓存 [文件总数:${cacheData.length}][纹理缓存:${totalTextureSize.toFixed(2) + 'M'}]`;
this.$data.cacheDataLoading = false;
}, 0);
},
closeCachePanel() {
this.$data.cacheData = [];
this.$data.cacheTitle = `缓存`;
},
openDevMode() {
setTimeout(() => {
if (!cc.Node.prototype.isLeaf) {
cc.js.getset(cc.Node.prototype, 'isLeaf', function () {
return !this.children || this.childrenCount === 0;
}, function (value) {
}, false, true);
}
let top = document.getElementById('top');
top.appendChild(document.getElementsByClassName('toolbar')[0]);
document.getElementById('game_panel').appendChild(document.getElementById('content'));
let scene = cc.director.getScene();
if (scene) {
this.updateTreeData();
}
cc.director.on(cc.Director.EVENT_AFTER_SCENE_LAUNCH, () => {
this.updateTreeData();
}, this);
cc.director.on(cc.Director.EVENT_BEFORE_SCENE_LOADING, () => {
this.$data.node = null;
this.$data.sceneTreeData = [];
this.$data.treeParam = [];
}, this);
localStorage.setItem('isDevMode', 1);
}, 0);
},
closeDevMode() {
this.$data.node = null;
this.$data.sceneTreeData = [];
cc.director.targetOff(this);
clearInterval(this.$data.intervalId);
document.body.appendChild(document.getElementsByClassName('toolbar')[0]);
document.body.appendChild(document.getElementById('content'));
localStorage.setItem('isDevMode', 0);
},
handleChangeNodeSchema() {
if (this.is3DNode) {
this.is3DNode = false;
} else {
this.is3DNode = true;
}
this.$data.nodeSchema = this.$data.is3DNode ? NEX_CONFIG.nodeSchema.node3d : NEX_CONFIG.nodeSchema
.node2d;
},
handleChangeMode(data) {
data ? this.openDevMode() : this.closeDevMode();
},
handleChangeCachePanel(data) {
data ? this.openCachePanel() : this.closeCachePanel();
},
handleChangeStats() {
if (this.$data.isShowProfile) {
let addStats = function (stats) {
stats.dom.style.position = 'relative';
stats.dom.style.float = 'right';
stats.dom.style.marginLeft = '10px';
stats.dom.style.marginBottom = '10px';
// stats.dom.style.pointerEvents = 'none';
stats.dom.className = 'statsPanel';
document.getElementById('panelCtl').appendChild(stats.dom);
localStorage.setItem('isShowProfile', '1')
}
let animate = () => {
if (this.$data.isShowProfile) {
stats.update();
requestAnimationFrame(animate);
}
}
let stats = new Stats();
addStats(stats);
animate();
} else {
let panels = document.getElementsByClassName('statsPanel');
while (panels.length > 0) {
panels[0].parentElement.removeChild(panels[0]);
}
localStorage.setItem('isShowProfile', '0');
}
},
handleChangeCheckVersion(isCheckVersion) {
if (isCheckVersion) {
localStorage.setItem('isCheckVersion', '1');
this.checkVersion();
} else {
localStorage.setItem('isCheckVersion', '0');
}
},
handleChangeTheme(isDark) {
isDark ? this.addDarkTheme() : this.removeDarkTheme();
},
// 添加暗色主题
addDarkTheme() {
let link = document.createElement('link');
link.type = 'text/css';
link.id = "theme-css-dark";
link.rel = 'stylesheet';
link.href = 'app/editor/static/preview-templates/ccc-devtools/css/themes/dark.css';
document.getElementsByTagName("head")[0].appendChild(link);
localStorage.setItem('isDarkTheme', 1);
},
// 删除暗色主题
removeDarkTheme() {
document.getElementById('theme-css-dark').remove();
localStorage.setItem('isDarkTheme', 0);
},
fitFullScreen() {
document.getElementsByClassName('toolbar')[0].style.display = 'none';
let gameDiv = document.getElementById('GameDiv');
let gameContainer = document.getElementById('Cocos2dGameContainer');
let gameCanvas = document.getElementById('GameCanvas');
gameDiv.style.width = '100%';
gameDiv.style.height = '100%';
gameCanvas.style.width = '100%';
gameCanvas.style.height = '100%';
// document.body.style.cssText+="-webkit-transform: rotate(-90deg);-moz-transform: rotate(-90deg)";
},
initConsoleUtil() {
if (cc.tree) return;
cc.tree = function (key) {
let index = key || 0;
let treeNode = function (node) {
let nameStyle =
`color: ${node.parent === null || node.activeInHierarchy ? 'green' : 'grey'}; font-size: 14px;font-weight:bold`;
let propStyle =
`color: black; background: lightgrey;margin-left: 5px;border-radius:3px;padding: 0 3px;font-size: 10px;font-weight:bold`;
let indexStyle =
`color: orange; background: black;margin-left: 5px;border-radius:3px;padding:0 3px;fonrt-size: 10px;font-weight:bold;`
let nameValue = `%c${node.name}`;
let propValue =
`%c${node.x.toFixed(0) + ',' + node.y.toFixed(0) + ',' + node.width.toFixed(0) + ',' + node.height.toFixed(0) + ',' + node.scale.toFixed(1)}`
let indexValue = `%c${index++}`;
if (node.childrenCount > 0) {
console.groupCollapsed(nameValue + propValue + indexValue, nameStyle,
propStyle, indexStyle);
for (let i = 0; i < node.childrenCount; i++) {
treeNode(node.children[i]);
}
console.groupEnd();
} else {
console.log(nameValue + propValue + indexValue, nameStyle, propStyle,
indexStyle);
}
}
if (key) {
let node = cc.cat(key);
index = node['tempIndex'];
treeNode(node);
} else {
let scene = cc.director.getScene();
treeNode(scene);
}
return '属性依次为x,y,width,height,scale.使用cc.cat(id)查看详细属性.';
}
cc.cat = function (key) {
let index = 0;
let target;
let sortId = function (node) {
if (target) return;
if (cc.js.isNumber(key)) {
if (key === index++) {
target = node;
return;
}
} else {
if (key.toLowerCase() === node.name.toLowerCase()) {
target = node;
return;
} else {
index++;
}
}
if (node.childrenCount > 0) {
for (let i = 0; i < node.childrenCount; i++) {
sortId(node.children[i]);
}
}
}
let scene = cc.director.getScene();
sortId(scene);
target['tempIndex'] = cc.js.isNumber(key) ? key : index;
return target;
}
cc.list = function (key) {
let targets = [];
let step = function (node) {
if (node.name.toLowerCase().indexOf(key.toLowerCase()) > -1) {
targets.push(node);
}
if (node.childrenCount > 0) {
for (let i = 0; i < node.childrenCount; i++) {
step(node.children[i]);
}
}
}
let scene = cc.director.getScene();
step(scene);
if (targets.length === 1) {
return targets[0];
} else {
return targets;
}
}
cc.where = function (key) {
let target = key.name ? key : cc.cat(key);
if (!target) {
return null;
}
let rect = target.getBoundingBoxToWorld();
let borderNode = new cc.Node();
let bgNode = new cc.Node();
let graphics = bgNode.addComponent(cc.Graphics);
let scene = cc.director.getScene();
scene.addChild(bgNode);
bgNode.addChild(borderNode);
bgNode.position = scene.convertToNodeSpaceAR(rect.center);
let isZeroSize = rect.width === 0 || rect.height === 0;
if (isZeroSize) {
graphics.circle(0, 0, 100);
graphics.fillColor = cc.Color.GREEN;
graphics.fill();
} else {
bgNode.width = rect.width;
bgNode.height = rect.height;
graphics.rect(-bgNode.width / 2, -bgNode.height / 2, bgNode.width, bgNode.height);
graphics.strokeColor = cc.Color.RED;
graphics.lineWidth = 10;
graphics.stroke()
}
setTimeout(() => {
if (cc.isValid(bgNode)) {
bgNode.destroy();
}
}, 2000);
return target;
}
}
},
watch: {
filterText(val) {
this.$refs.sceneTree.filter(val);
// console.log(val);
}
},
created: function () {
document.body.insertBefore(document.getElementById('app'), document.body.firstChild);
let onCCInit = () => {
this.initConsoleUtil();
if (cc.sys.isMobile) {
this.fitFullScreen();
}
if (localStorage.getItem('isDevMode') === '1') {
this.$data.isDevMode = true;
this.openDevMode();
} else {
this.$data.isDevMode = false;
}
if (localStorage.getItem('isDarkTheme') === '1') {
this.$data.isDarkTheme = true;
this.addDarkTheme();
} else {
this.$data.isDarkTheme = false;
}
if (localStorage.getItem('isCheckVersion') === '1') {
this.$data.isCheckVersion = true;
this.checkVersion();
} else {
this.$data.isCheckVersion = false;
}
this.$data.isShowProfile = localStorage.getItem('isShowProfile') === '1';
setTimeout(() => {
this.handleChangeStats();
}, 0);
}
let checkCC = () => {
if (window.cc && window.cc.director) {
onCCInit();
clearInterval(this.$data.intervalId);
} else {
// console.log('cc is not init');
}
}
this.$data.intervalId = setInterval(checkCC, 500);
setTimeout(checkCC, 0);
},
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,200 +0,0 @@
var Stats = function () {
var mode = 0;
var container = document.createElement('div');
container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000';
container.addEventListener('click', function (event) {
event.preventDefault();
showPanel(++mode % container.children.length);
}, false);
//
function addPanel(panel) {
container.appendChild(panel.dom);
return panel;
}
function showPanel(id) {
for (var i = 0; i < container.children.length; i++) {
container.children[i].style.display = i === id ? 'block' : 'none';
}
mode = id;
}
function getDrawcalls() {
if (window.cc) {
return cc.g_NumberOfDraws || cc.renderer.drawCalls;
} else {
return Infinity;
}
}
function getTexMemory() {
if (window.cc) {
let totalTextureSize = 0;
let cacheData = cc.loader._cache;
for (let k in cacheData) {
let item = cacheData[k];
if (item.content && item.content.__classname__ && item.content.__classname__ === 'cc.Texture2D') {
let texture = item.content;
let textureSize = texture.width * texture.height * ((texture._native === '.jpg' ? 3 : 4) / 1024 / 1024);
totalTextureSize += textureSize;
}
}
return totalTextureSize;
} else {
return Infinity;
}
}
//
var beginTime = (performance || Date).now(), prevTime = beginTime, frames = 0;
var texPanel = addPanel(new Stats.Panel('纹理内存', 'MB', '#0ff', '#002'));
var dcPanel = addPanel(new Stats.Panel('DrawCall', '', '#ff8', '#221'));
var fpsPanel = addPanel(new Stats.Panel('FPS', '', '#0f0', '#020'));
var msPanel = addPanel(new Stats.Panel('渲染时间', 'MS', '#f08', '#201'));
// if (self.performance && self.performance.memory) {
// var memPanel = addPanel(new Stats.Panel('MB', '#f08', '#201'));
// }
showPanel(0);
return {
REVISION: 16,
dom: container,
addPanel: addPanel,
showPanel: showPanel,
begin: function () {
beginTime = (performance || Date).now();
},
end: function () {
frames++;
var time = (performance || Date).now();
msPanel.update(time - beginTime, 200);
if (time >= prevTime + 1000) {
fpsPanel.update((frames * 1000) / (time - prevTime), 100);
prevTime = time;
frames = 0;
// if (memPanel) {
// var memory = performance.memory;
// memPanel.update(memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576);
// }
texPanel.update(getTexMemory(), 1000);
dcPanel.update(getDrawcalls(), 500);
}
return time;
},
update: function () {
beginTime = this.end();
},
// Backwards Compatibility
domElement: container,
setMode: showPanel
};
};
Stats.Panel = function (name, unit, fg, bg) {
var min = Infinity, max = 0, round = Math.round;
var PR = round(window.devicePixelRatio || 1);
var WIDTH = 80 * PR, HEIGHT = 48 * PR,
TEXT_X = 3 * PR, TEXT_Y = 2 * PR,
GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,
GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;
var canvas = document.createElement('canvas');
canvas.width = WIDTH;
canvas.height = HEIGHT;
canvas.style.cssText = 'width:80px;height:48px';
var context = canvas.getContext('2d');
context.font = 'bold ' + (9 * PR) + 'px Helvetica,Arial,sans-serif';
context.textBaseline = 'top';
context.fillStyle = bg;
context.fillRect(0, 0, WIDTH, HEIGHT);
context.fillStyle = fg;
context.fillText(name, TEXT_X, TEXT_Y);
context.fillRect(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);
context.fillStyle = bg;
context.globalAlpha = 0.9;
context.fillRect(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);
return {
dom: canvas,
update: function (value, maxValue) {
min = Math.min(min, value);
max = Math.max(max, value);
context.fillStyle = bg;
context.globalAlpha = 1;
context.fillRect(0, 0, WIDTH, GRAPH_Y);
context.fillStyle = fg;
// context.fillText(round(value) + ' ' + name + ' (' + round(min) + '-' + round(max) + ')', TEXT_X, TEXT_Y);
context.fillText(name + ' ' + round(value) + unit, TEXT_X, TEXT_Y);
context.drawImage(canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT);
context.fillRect(GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT);
context.fillStyle = bg;
context.globalAlpha = 0.9;
context.fillRect(GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round((1 - (value / maxValue)) * GRAPH_HEIGHT));
}
};
};
// export { Stats as default };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

6
libs/vue/vue.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,176 +0,0 @@
(function () {
'use strict';
// init device resolutions
var devices = [
{ name: 'Apple iPhone 5', width: 320, height: 568, ratio: 2 },
{ name: 'Apple iPhone 6', width: 375, height: 667, ratio: 2 },
{ name: 'Apple iPhone 6 Plus', width: 414, height: 736, ratio: 3 },
{ name: 'Apple iPhone 7', width: 375, height: 667, ratio: 2 },
{ name: 'Apple iPhone 7 Plus', width: 414, height: 736, ratio: 3 },
{ name: 'Apple iPhone X', width: 375, height: 812, ratio: 3 },
{ name: 'Apple iPad', width: 1024, height: 768, ratio: 2 },
{ name: 'Apple iPad Air 2', width: 768, height: 1024, ratio: 2 },
{ name: 'Apple iPad Pro 10.5-inch', width: 834, height: 1112, ratio: 2 },
{ name: 'Apple iPad Pro 12.9-inch', width: 1024, height: 1366, ratio: 2 },
{ name: 'Huawei P9', width: 540, height: 960, ratio: 2 },
{ name: 'Huawei Mate9 Pro', width: 720, height: 1280, ratio: 2 },
{ name: 'Goolge Nexus 5', width: 360, height: 640, ratio: 3 },
{ name: 'Goolge Nexus 5X', width: 411, height: 731, ratio: 2.625 },
{ name: 'Goolge Nexus 6', width: 412, height: 732, ratio: 3.5 },
{ name: 'Goolge Nexus 7', width: 960, height: 600, ratio: 2 },
];
var designWidth = _CCSettings.designWidth;
var designHeight = _CCSettings.designHeight;
var rotated = false;
var canvas = document.getElementById('GameCanvas');
window.onload = function () {
if (window.__quick_compile__) {
window.__quick_compile__.load(onload);
}
else {
onload();
}
};
function getEmulatedScreenSize () {
var w, h;
// var idx = optsDevice.value;
var idx = '4';
rotated = true;
if ( idx === '0' ) {
w = designWidth;
h = designHeight;
}
else {
var info = devices[parseInt(idx) - 1];
w = info.width;
h = info.height;
}
return {
width: rotated ? h : w,
height: rotated ? w : h
};
}
function onload() {
// socket
// =======================
// Receives a refresh event from the editor, which triggers the reload of the page
var socket = window.io();
socket.on('browser:reload', function () {
window.location.reload();
});
socket.on('browser:confirm-reload', function () {
var r = confirm('Reload?');
if (r) {
window.location.reload();
}
});
function updateResolution () {
var size = getEmulatedScreenSize();
var gameDiv = document.getElementById('GameDiv');
gameDiv.style.width = size.width + 'px';
gameDiv.style.height = size.height + 'px';
cc.view.setCanvasSize(size.width, size.height);
}
// init engine
// =======================
var AssetOptions = {
libraryPath: 'res/import',
rawAssetsBase: 'res/raw-',
rawAssets: _CCSettings.rawAssets
};
// jsList
var jsList = _CCSettings.jsList || [];
jsList = jsList.map(function (x) { return AssetOptions.rawAssetsBase + x; });
if (_CCSettings.jsBundleForWebPreview) {
jsList.push(_CCSettings.jsBundleForWebPreview);
}
window.__modular.init(_CCSettings.scripts);
jsList = jsList.concat(window.__modular.srcs);
var option = {
id: canvas,
scenes: _CCSettings.scenes,
debugMode: _CCSettings.debug ? cc.debug.DebugMode.INFO : cc.debug.DebugMode.ERROR,
showFPS: _CCSettings.debug,
frameRate: 60,
groupList: _CCSettings.groupList,
collisionMatrix: _CCSettings.collisionMatrix,
jsList: jsList
};
cc.AssetLibrary.init(AssetOptions);
cc.game.run(option, function () {
updateResolution();
cc.view.enableRetina(true);
cc.debug.setDisplayStats(true);
// Loading splash scene
// var splash = document.getElementById('splash');
// var progressBar = splash.querySelector('.progress-bar span');
cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, function () {
// splash.style.display = 'none';
});
cc.game.pause();
// load stashed scene
cc.loader.load('preview-scene.json', function (error, json) {
if (error) {
cc.error(error.stack);
return;
}
cc.loader.onProgress = function (completedCount, totalCount, item) {
var percent = 100 * completedCount / totalCount;
// if (progressBar) {
// progressBar.style.width = percent.toFixed(2) + '%';
// }
};
cc.AssetLibrary.loadJson(json,
function (err, sceneAsset) {
if (err) {
cc.error(err.stack);
return;
}
var scene = sceneAsset.scene;
scene._name = sceneAsset._name;
cc.director.runSceneImmediate(scene, function () {
// play game
cc.game.resume();
});
cc.loader.onProgress = null;
}
);
});
// purge
//noinspection JSUnresolvedVariable
_CCSettings = undefined;
});
};
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

View File

@ -1,88 +0,0 @@
<html>
<head>
<link rel="icon" href="app/editor/static/preview-templates/favicon.ico">
</link>
<meta charset="utf-8">
<title><%=title%></title>
<link rel="stylesheet" type="text/css" href="style.css" />
<!-- <link href="libs/css/googlefonts.css" rel="stylesheet" type="text/css"> -->
<link href="libs/css/materialdesignicons.min.css" rel="stylesheet" type="text/css">
<link href="libs/css/vuetify.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<v-app id="app">
<v-app-bar app clipped-left color="gray" dense>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title class="mr-5 align-center">
<span class="title">Title</span>
</v-toolbar-title>
<v-spacer></v-spacer>
</v-app-bar>
<v-navigation-drawer v-model="drawer" app clipped fixed width="512">
<v-container style="height: 50%;overflow: auto;">
<v-text-field v-model="search" dense label="Search Node or Component" dark flat solo-inverted hide-details clearable
clear-icon="mdi-close-circle-outline"></v-text-field>
<v-treeview :items="nodes" item-key="id" dense activatable :search="search" @click="handleNodeClick">
<template v-slot:label="{ item, open }">
<label v-if="item.active" style="color: white;">{{ item.name }}</label>
<label v-else style="color: gray;">{{ item.name }}</label>
</template>
</v-treeview>
</v-container>
<v-container style="border-top: 2px solid darkgray;overflow-y: auto;">
<v-row>
<v-col cols="4">
<label>Position</label>
</v-col>
<v-col cols="8">
<label>12,12</label>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<label>width</label>
</v-col>
<v-col cols="8">
<label>250</label>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<label>height</label>
</v-col>
<v-col cols="8">
<label>250</label>
</v-col>
</v-row>
</v-container>
</v-navigation-drawer>
<v-content>
<v-container fill-height>
<v-card id="GameDiv" class="mx-auto" outlined>
<canvas id="GameCanvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
</v-card>
</v-container>
</v-content>
</v-app>
<!-- <div id="splash">
<div class="progress-bar stripes">
<span style="width: 0%"></span>
</div>
</div> -->
<script src="libs/js/vue.min.js"></script>
<script src="libs/js/vuetify.js"></script>
<script src="preview.js"></script>
<script src="settings.js" charset="utf-8"></script>
<script src="app/editor/static/preview-templates/modular.js" charset="utf-8"></script>
<script src="boot.js" charset="utf-8"></script>
<script src="/socket.io/socket.io.js" charset="utf-8"></script>
<script src="app/engine/bin/<%=cocos2d%>" charset="utf-8"></script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

View File

@ -1,99 +0,0 @@
body {
cursor: default;
color: #888;
background-color: #333;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
height: 100%; /* for firefox */
width: 100%;
position: absolute;
padding: 0px;
border: 0px;
margin: 0px;
}
body, canvas, div {
outline: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
canvas {
background-color: rgba(0, 0, 0, 0);
}
/* #splash {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #171717 url(./splash.png) no-repeat center;
background-size: 40%;
} */
.content {
display: -webkit-flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
-webkit-align-items: center;
align-items: center;
-webkit-flex-direction: column;
flex-direction: column;
-webkit-flex: auto;
flex: auto;
}
.progress-bar {
background-color: #1a1a1a;
position: absolute;
left: 25%;
top: 80%;
height: 15px;
padding: 5px;
width: 50%;
/*margin: 0 -175px; */
border-radius: 5px;
box-shadow: 0 1px 5px #000 inset, 0 1px 0 #444;
}
.progress-bar span {
display: block;
height: 100%;
border-radius: 3px;
box-shadow: 0 1px 0 rgba(255, 255, 255, .5) inset;
transition: width .4s ease-in-out;
background-color: #34c2e3;
}
.stripes span {
background-size: 30px 30px;
background-image: linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
transparent 75%, transparent);
animation: animate-stripes 1s linear infinite;
}
#GameDiv {
margin:0 auto;
}
/* #Cocos2dGameContainer {
margin:0 auto;
} */

View File

@ -6,41 +6,24 @@ const app = new Vue({
}), }),
data: { data: {
drawer: false, drawer: false,
loading: true, treeData: [],
nodes: [], selectedNodes: [],
intervalId: -1, intervalId: -1,
search: null, treeSearchText: null,
node: null,
nodeSchema: {}, nodeSchema: {},
componentsSchema: [], componentsSchema: [],
}, },
created() { created() {
// this.$vuetify.theme.dark = true; this.startUpdateTree();
this.updateTree();
}, },
computed: { computed: {
filter() { treeFilter() {
return (item, search, textKey) => item[textKey].indexOf(search) > -1; return (item, search, textKey) => item[textKey].indexOf(search) > -1;
}, },
}, selectedNode() {
methods: { if (!this.selectedNodes.length) return undefined
showTree: function () { let node = getNodeById(this.selectedNodes[0]);
if (!this.$data.drawer || !window.cc || !cc.director.getScene() || !cc.director.getScene().children) return;
this.$data.nodes = getChildren(cc.director.getScene());
},
updateTree: function () {
this.$data.intervalId = setInterval(() => {
this.showTree();
}, 200);
},
stopUpdateTree: function () {
clearInterval(this.$data.intervalId);
},
handleNodeClick(node) {
console.log(node);
return;
if (node) { if (node) {
this.$data.node = node;
if (!node.hex_color) { if (!node.hex_color) {
cc.js.getset(node, 'hex_color', () => { cc.js.getset(node, 'hex_color', () => {
return '#' + node.color.toHEX('#rrggbb'); return '#' + node.color.toHEX('#rrggbb');
@ -52,29 +35,24 @@ const app = new Vue({
let superPreLoad = node._onPreDestroy; let superPreLoad = node._onPreDestroy;
node._onPreDestroy = () => { node._onPreDestroy = () => {
superPreLoad.apply(node); superPreLoad.apply(node);
if (this.$data && this.$data.node === node) { if (this.selectedNodes.length > 0 && this.selectedNodes[0] === node._id) {
this.$data.node = null; this.selectedNodes.pop();
} }
} }
this.$data.nodeSchema = this.$data.is3DNode ? NEX_CONFIG.nodeSchema.node3d : NEX_CONFIG this.nodeSchema = NEX_CONFIG.nodeSchema.node2d;
.nodeSchema.node2d;
let componentsSchema = []; let componentsSchema = [];
for (let component of node._components) { for (let component of node._components) {
let schema = NEX_CONFIG.componentsSchema[component.__classname__]; let schema = NEX_CONFIG.componentsSchema[component.__classname__];
if (schema) { if (schema) {
node[schema.key] = node.getComponent(schema.key); node[schema.key] = node.getComponent(schema.key);
for (let i = 0; i < schema.rows.length; i++) { for (let i = 0; i < schema.rows.length; i++) {
for (let j = 0; j < schema.rows[i].length; j++) { if (schema.rows[i].type === 'color') {
if (schema.rows[i][j].type === 'color') { if (!node[schema.key][schema.rows[i].key]) {
if (!node[schema.key][schema.rows[i][j].field]) { cc.js.getset(node[schema.key], schema.rows[i].key, () => {
cc.js.getset(node[schema.key], schema.rows[i][j].field, () => { return '#' + node.getComponent(schema.key)[schema.rows[i].rawKey].toHEX('#rrggbb');
return '#' + node.getComponent(schema.key)[schema.rows[i][j] }, (hex) => {
.rawField].toHEX('#rrggbb'); node.getComponent(schema.key)[schema.rows[i].rawKey] = new cc.Color().fromHEX(hex);
}, (hex) => { }, false, true);
node.getComponent(schema.key)[schema.rows[i][j].rawField] =
new cc.Color().fromHEX(hex);
}, false, true);
}
} }
} }
} }
@ -87,10 +65,23 @@ const app = new Vue({
} }
componentsSchema.push(schema); componentsSchema.push(schema);
} }
this.$data.componentsSchema = componentsSchema; this.componentsSchema = componentsSchema;
} else {
this.$data.node = null;
} }
return node;
},
},
methods: {
refreshTree: function () {
if (!this.$data.drawer || !window.cc || !cc.director.getScene() || !cc.director.getScene().children) return;
this.$data.treeData = getChildren(cc.director.getScene());
},
startUpdateTree: function () {
this.$data.intervalId = setInterval(() => {
this.refreshTree();
}, 200);
},
stopUpdateTree: function () {
clearInterval(this.$data.intervalId);
}, },
} }
}); });
@ -101,3 +92,23 @@ function getChildren(node) {
return { id: child._id, name: child.name, active: child.activeInHierarchy, children }; return { id: child._id, name: child.name, active: child.activeInHierarchy, children };
}); });
} }
function getNodeById(id) {
let target;
const search = function (node) {
if (node._id === id) {
target = node;
return;
}
if (node.childrenCount) {
for (let i = 0; i < node.childrenCount; i++) {
if (!target) {
search(node.children[i]);
}
}
}
}
const scene = cc.director.getScene();
search(scene);
return target;
}