Commit 28a72036fdd8922fc2af2318a0a8c0a7a7289d0c

Authored by ly525
1 parent 0208a797

feat: show avaiable animation list

front-end/h5/package.json
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 "deploy": "rm -rf dist && npm run build && ./deploy.sh" 11 "deploy": "rm -rf dist && npm run build && ./deploy.sh"
12 }, 12 },
13 "dependencies": { 13 "dependencies": {
  14 + "animate.css": "^3.7.2",
14 "ant-design-vue": "^1.3.14", 15 "ant-design-vue": "^1.3.14",
15 "core-js": "^2.6.5", 16 "core-js": "^2.6.5",
16 "element-ui": "^2.9.1", 17 "element-ui": "^2.9.1",
front-end/h5/src/components/core/editor/edit-panel/animation.js 0 → 100644
  1 +import { animationOptions, animationValue2Name, firstLevelAnimationOptions } from '@/constants/animation.js'
  2 +import 'animate.css'
  3 +
  4 +export default {
  5 + data: () => ({
  6 + animationQueue: [],
  7 + activeCollapsePanel: [],
  8 + activePreviewAnimation: '',
  9 + drawerVisible: false
  10 + }),
  11 + methods: {
  12 + addAnimation () {
  13 + this.animationQueue.push({
  14 + type: '',
  15 + duration: 0,
  16 + delay: 0,
  17 + countNum: 1,
  18 + infinite: false
  19 + })
  20 + this.activeCollapsePanel = `${this.animationQueue.length - 1}`
  21 + },
  22 + deleteAnimate (index) {
  23 + this.animationQueue.splice(index, 1)
  24 + },
  25 + runAnimate () {
  26 + },
  27 + renderSecondAnimationTabs (animations) {
  28 + return (
  29 + <a-tabs
  30 + defaultActiveKey={animations[0].value}
  31 + onChange={tab => {}}
  32 + style="width:100%;"
  33 + tabBarStyle={{ marginLeft: '-16px' }}
  34 + size="small"
  35 + tabBarGutter={0}
  36 + tabPosition="left"
  37 + >
  38 + {
  39 + animations.map(group => (
  40 + <a-tab-pane tab={group.label || group.value} key={group.value}>
  41 + <a-list
  42 + grid={{ gutter: 12, column: 2 }}
  43 + dataSource={group.children}
  44 + renderItem={(item, index) => (
  45 + // [key point] onMouseover vs onMouseenter
  46 + // https://stackoverflow.com/questions/7286532/jquery-mouseenter-vs-mouseover
  47 + // https://www.quirksmode.org/js/events_mouse.html#mouseenter
  48 + <a-list-item>
  49 + <div
  50 + class={[this.activePreviewAnimation === item.value && item.value + ' animated', 'shortcut-button']}
  51 + onMouseenter={(e) => {
  52 + this.activePreviewAnimation = item.value
  53 + }}
  54 + onMouseleave={() => {
  55 + // [key point] why not set activePreviewAnimation='' after mouseleave, see more here: https://stackoverflow.com/questions/32279782/mouseenter-called-multiple-times
  56 + // this.activePreviewAnimation = ''
  57 + }}
  58 + >
  59 + {item.label}
  60 + </div>
  61 + </a-list-item>
  62 + )}
  63 + >
  64 + </a-list>
  65 + </a-tab-pane>
  66 + ))
  67 + }
  68 + </a-tabs>
  69 + )
  70 + },
  71 + renderAvaiableAnimations () {
  72 + return (
  73 + <a-tabs
  74 + defaultActiveKey={firstLevelAnimationOptions[0].label}
  75 + onChange={tab => {}}
  76 + style="width:100%;"
  77 + tabBarStyle={{}}
  78 + size="small"
  79 + tabBarGutter={0}
  80 + >
  81 + {
  82 + firstLevelAnimationOptions.map(firstGroup => (
  83 + <a-tab-pane tab={firstGroup.label} key={firstGroup.label}>
  84 + {/* group.label.match(firstGroup.value) <-> !!'abc'.match(/a|e/) === true */}
  85 + {this.renderSecondAnimationTabs(animationOptions.filter(group => !!group.label.match(firstGroup.value)))}
  86 + </a-tab-pane>
  87 + ))
  88 + }
  89 + </a-tabs>
  90 + )
  91 + },
  92 + renderAnimationOptions () {
  93 + return (
  94 + <a-form layout="horizontal">
  95 + <a-form-item label="动画类型" labelCol={{ span: 5 }} wrapperCol={{ span: 16, offset: 2 }}>
  96 + {/* <a-popover placement="left" title="动画列表" trigger="click">
  97 + <template slot="content">
  98 + {this.renderAvaiableAnimations()}
  99 + </template>
  100 + <a-button type="primary">动画列表</a-button>
  101 + </a-popover> */}
  102 + <a-button type="link" size="small" icon="ordered-list" onClick={() => { this.drawerVisible = true }}>动画列表</a-button>
  103 + </a-form-item>
  104 + <a-form-item label="动画时间" labelCol={{ span: 5 }} wrapperCol={{ span: 16, offset: 2 }} style="margin-bottom:0;">
  105 + <a-form-item style={{ display: 'inline-block', width: 'calc(50% - 12px)' }}>
  106 + <a-slider id="test" defaultValue={30} />
  107 + </a-form-item>
  108 + <a-form-item style={{ display: 'inline-block', width: 'calc(50% - 12px)' }}>
  109 + <a-input-number min={1} max={20} size="small" formatter={value => `${value}秒`}/>
  110 + </a-form-item>
  111 + </a-form-item>
  112 + <a-form-item label="循环播放" labelCol={{ span: 5 }} wrapperCol={{ span: 16, offset: 2 }} style="margin-bottom:0;">
  113 + <a-switch v-decorator="['switch', { valuePropName: 'checked' }]" />
  114 + </a-form-item>
  115 + </a-form>
  116 + )
  117 + }
  118 + },
  119 + render (h) {
  120 + return (
  121 + <div class="main-animate widget" id="animation-edit-panel">
  122 + <a-button-group>
  123 + <a-button type="primary" onClick={this.addAnimation}><a-icon type="plus" />添加动画</a-button>
  124 + <a-button type="primary" onClick={this.runAnimate}>运行动画<a-icon type="right-circle" /></a-button>
  125 + </a-button-group>
  126 + {
  127 + this.animationQueue.length &&
  128 + <a-collapse activeKey={this.activeCollapsePanel} onChange={(val) => { this.activeCollapsePanel = val }} class="collapse-wrapper">
  129 + {
  130 + this.animationQueue.map((addedAnimation, index) => (
  131 + <a-collapse-panel key={`${index}`}>
  132 + <template slot="header">
  133 + <span>动画{index + 1}</span>
  134 + <a-tag color="orange">{animationValue2Name[addedAnimation.type] }</a-tag>
  135 + {/* <a-icon onClick={this.deleteAnimate(index)}></a-icon> */}
  136 + </template>
  137 + {this.renderAnimationOptions()}
  138 + </a-collapse-panel>
  139 + ))
  140 + }
  141 + </a-collapse>
  142 + }
  143 +
  144 + <a-drawer
  145 + title="请选择动画"
  146 + placement="left"
  147 + closable={true}
  148 + onClose={() => { this.drawerVisible = false }}
  149 + visible={this.drawerVisible}
  150 + width={400}
  151 + wrapStyle={{ margin: '-16px' }}
  152 + >
  153 + <div style="width: 100%;">
  154 + {this.renderAvaiableAnimations()}
  155 + </div>
  156 + </a-drawer>
  157 + </div>
  158 + )
  159 + }
  160 +}
front-end/h5/src/components/core/editor/index.js
@@ -8,6 +8,7 @@ import RenderEditCanvas from &#39;./canvas/edit&#39; @@ -8,6 +8,7 @@ import RenderEditCanvas from &#39;./canvas/edit&#39;
8 import RenderPreviewCanvas from './canvas/preview' 8 import RenderPreviewCanvas from './canvas/preview'
9 import RenderPropsEditor from './edit-panel/props' 9 import RenderPropsEditor from './edit-panel/props'
10 import RenderScriptEditor from './edit-panel/script' 10 import RenderScriptEditor from './edit-panel/script'
  11 +import RenderAnimationEditor from './edit-panel/animation'
11 import RenderActoionEditor from './edit-panel/action' 12 import RenderActoionEditor from './edit-panel/action'
12 import RenderShortcutsPanel from './shortcuts-panel/index' 13 import RenderShortcutsPanel from './shortcuts-panel/index'
13 import PreviewDialog from './modals/preview.vue' 14 import PreviewDialog from './modals/preview.vue'
@@ -281,7 +282,7 @@ export default { @@ -281,7 +282,7 @@ export default {
281 {/* { this.renderPropsEditorPanel(h) } */} 282 {/* { this.renderPropsEditorPanel(h) } */}
282 <RenderPropsEditor/> 283 <RenderPropsEditor/>
283 </a-tab-pane> 284 </a-tab-pane>
284 - <a-tab-pane label="动画" key='动画' tab='动画'>动画</a-tab-pane> 285 + <a-tab-pane label="动画" key='动画' tab='动画'><RenderAnimationEditor /></a-tab-pane>
285 <a-tab-pane label="动作" key='动作' tab='动作'>{this.activeTabKey === '动作'}{ this.activeTabKey === '动作' && <RenderActoionEditor/> }</a-tab-pane> 286 <a-tab-pane label="动作" key='动作' tab='动作'>{this.activeTabKey === '动作'}{ this.activeTabKey === '动作' && <RenderActoionEditor/> }</a-tab-pane>
286 <a-tab-pane label="脚本" key='脚本' tab='脚本'><RenderScriptEditor/></a-tab-pane> 287 <a-tab-pane label="脚本" key='脚本' tab='脚本'><RenderScriptEditor/></a-tab-pane>
287 </a-tabs> 288 </a-tabs>
front-end/h5/src/components/core/styles/index.scss
  1 +@mixin shortcut-button {
  2 + border: 1px dashed #fff;
  3 + height: 60px;
  4 + display: flex;
  5 + align-items: center;
  6 + justify-content: center;
  7 + cursor: pointer;
  8 + transition: all .25s;
  9 + background-color: #f5f8fb;
  10 + margin-bottom: 15px;
  11 + flex-direction: column;
  12 + color: #393e46;
  13 + width: 100%;
  14 +
  15 + &:disabled {
  16 + cursor: not-allowed;
  17 + }
  18 + .shortcut-icon {
  19 + padding: 4px;
  20 + // display: block;
  21 + // font-size: 16px;
  22 + // margin-bottom: 10px;
  23 + }
  24 +}
  25 +
1 #luban-editor-layout, 26 #luban-editor-layout,
2 #luban-work-manager-layout { 27 #luban-work-manager-layout {
3 .header { 28 .header {
@@ -29,30 +54,10 @@ @@ -29,30 +54,10 @@
29 } 54 }
30 55
31 .shortcut-button { 56 .shortcut-button {
32 - border: 1px dashed #fff;  
33 - height: 60px;  
34 - display: flex;  
35 - align-items: center;  
36 - justify-content: center;  
37 - cursor: pointer;  
38 - transition: all .25s;  
39 - background-color: #f5f8fb;  
40 - margin-bottom: 15px;  
41 - flex-direction: column;  
42 - color: #393e46;  
43 - width: 100%;  
44 -  
45 - &:disabled {  
46 - cursor: not-allowed;  
47 - }  
48 - .shortcut-icon {  
49 - padding: 4px;  
50 - // display: block;  
51 - // font-size: 16px;  
52 - // margin-bottom: 10px;  
53 - } 57 + @include shortcut-button;
54 } 58 }
55 59
  60 +
56 .canvas-wrapper { 61 .canvas-wrapper {
57 border: 1px dashed #e7e7e7; 62 border: 1px dashed #e7e7e7;
58 // padding: '12px'; 63 // padding: '12px';
@@ -122,7 +127,25 @@ @@ -122,7 +127,25 @@
122 background-repeat: no-repeat; 127 background-repeat: no-repeat;
123 background-position: center center; 128 background-position: center center;
124 } 129 }
  130 +}
  131 +
  132 +.shortcut-button {
  133 + @include shortcut-button;
  134 +}
  135 +
  136 +// 动画编辑面板定制
  137 +#animation-edit-panel {
  138 + .ant-collapse-header {
  139 + padding: 6px 0 6px 40px;
  140 + }
  141 +
  142 + .collapse-wrapper {
  143 + margin-top: 12px;
125 144
  145 + .ant-form-item {
  146 + margin-bottom: 0;
  147 + }
  148 + }
126 } 149 }
127 150
128 .default-router-link { 151 .default-router-link {
front-end/h5/src/constants/animation.js 0 → 100644
  1 +// #!zh: 可选的动画列表的第一个层级
  2 +export const firstLevelAnimationOptions = [
  3 + {
  4 + label: '进入',
  5 + value: /进/
  6 + },
  7 + {
  8 + label: '退出',
  9 + value: /退/
  10 + },
  11 + {
  12 + label: '强调',
  13 + value: /强调|特殊/
  14 + }
  15 +]
  16 +
  17 +export const animationOptions = [
  18 + {
  19 + label: '',
  20 + value: '空',
  21 + children: [
  22 + {
  23 + label: '无',
  24 + value: ''
  25 + }
  26 + ]
  27 + },
  28 + {
  29 + label: '强调',
  30 + value: 'Attention Seekers',
  31 + children: [
  32 + {
  33 + label: '旋转',
  34 + value: 'justRotate'
  35 + }, {
  36 + label: '弹跳',
  37 + value: 'bounce'
  38 + },
  39 + {
  40 + label: '闪烁',
  41 + value: 'flash'
  42 + },
  43 + {
  44 + label: '跳动',
  45 + value: 'pulse'
  46 + },
  47 + {
  48 + label: '抖动',
  49 + value: 'shake'
  50 + },
  51 + {
  52 + label: '摇摆',
  53 + value: 'swing'
  54 + },
  55 + {
  56 + label: '橡皮圈',
  57 + value: 'rubberBand'
  58 + },
  59 + {
  60 + label: '果冻',
  61 + value: 'jello'
  62 + },
  63 + {
  64 + label: '',
  65 + value: 'tada'
  66 + },
  67 + {
  68 + label: '',
  69 + value: 'wobble'
  70 + }
  71 + ]
  72 + },
  73 +
  74 + {
  75 + label: '弹跳进入',
  76 + value: 'Bouncing Entrances',
  77 + children: [{
  78 + label: '弹跳进入',
  79 + value: 'bounceIn'
  80 + },
  81 + {
  82 + label: '向下弹跳进入',
  83 + value: 'bounceInDown'
  84 + },
  85 + {
  86 + label: '向右弹跳进入',
  87 + value: 'bounceInLeft'
  88 + },
  89 + {
  90 + label: '向左弹跳进入',
  91 + value: 'bounceInRight'
  92 + },
  93 + {
  94 + label: '向上弹跳进入',
  95 + value: 'bounceInUp'
  96 + }
  97 + ]
  98 + },
  99 +
  100 + {
  101 + label: '弹跳退出',
  102 + value: 'Bouncing Exits',
  103 + children: [{
  104 + label: '弹跳退出',
  105 + value: 'bounceOut'
  106 + },
  107 + {
  108 + label: '向下弹跳退出',
  109 + value: 'bounceOutDown'
  110 + },
  111 + {
  112 + label: '向左弹跳退出',
  113 + value: 'bounceOutLeft'
  114 + },
  115 + {
  116 + label: '向右弹跳退出',
  117 + value: 'bounceOutRight'
  118 + },
  119 + {
  120 + label: '向上弹跳退出',
  121 + value: 'bounceOutUp'
  122 + }
  123 + ]
  124 + },
  125 +
  126 + {
  127 + label: '渐显进入',
  128 + value: 'Fading Entrances',
  129 + children: [
  130 + {
  131 + label: '渐显进入',
  132 + value: 'fadeIn'
  133 + },
  134 + {
  135 + label: '向下渐显进入',
  136 + value: 'fadeInDown'
  137 + },
  138 + {
  139 + label: '由屏幕外向下渐显进入',
  140 + value: 'fadeInDownBig'
  141 + },
  142 + {
  143 + label: '向右显进入',
  144 + value: 'fadeInLeft'
  145 + },
  146 + {
  147 + label: '由屏幕外向右渐显进入',
  148 + value: 'fadeInLeftBig'
  149 + },
  150 + {
  151 + label: '向左渐显进入',
  152 + value: 'fadeInRight'
  153 + },
  154 + {
  155 + label: '由屏幕外向左渐显进入',
  156 + value: 'fadeInRightBig'
  157 + },
  158 + {
  159 + label: '向上渐显进入',
  160 + value: 'fadeInUp'
  161 + },
  162 + {
  163 + label: '由屏幕外向上渐显进入',
  164 + value: 'fadeInUpBig'
  165 + }
  166 + ]
  167 + },
  168 +
  169 + {
  170 + label: '渐隐退出',
  171 + value: 'Fading Exits',
  172 + children: [
  173 + {
  174 + label: '渐隐退出',
  175 + value: 'fadeOut'
  176 + },
  177 + {
  178 + label: '向下渐隐退出',
  179 + value: 'fadeOutDown'
  180 + },
  181 + {
  182 + label: '向下渐隐退出屏幕外',
  183 + value: 'fadeOutDownBig'
  184 + },
  185 + {
  186 + label: '向左渐隐退出',
  187 + value: 'fadeOutLeft'
  188 + },
  189 + {
  190 + label: '向左渐隐退出屏幕外',
  191 + value: 'fadeOutLeftBig'
  192 + },
  193 + {
  194 + label: '向右渐隐退出',
  195 + value: 'fadeOutRight'
  196 + },
  197 + {
  198 + label: '向右渐隐退出屏幕外',
  199 + value: 'fadeOutRightBig'
  200 + },
  201 + {
  202 + label: '向上渐隐退出',
  203 + value: 'fadeOutUp'
  204 + },
  205 + {
  206 + label: '向上渐隐退出屏幕外',
  207 + value: 'fadeOutUpBig'
  208 + }
  209 + ]
  210 + },
  211 +
  212 + {
  213 + label: '翻动',
  214 + value: 'Flippers',
  215 + children: [{
  216 + label: '翻动',
  217 + value: 'flip'
  218 + },
  219 + {
  220 + label: '纵向翻动',
  221 + value: 'flipInX'
  222 + },
  223 + {
  224 + label: '横向翻动',
  225 + value: 'flipInY'
  226 + },
  227 + {
  228 + label: '立体纵向翻动',
  229 + value: 'flipOutX'
  230 + },
  231 + {
  232 + label: '立体横向翻动',
  233 + value: 'flipOutY'
  234 + }
  235 + ]
  236 + },
  237 +
  238 + {
  239 + label: '加速进出',
  240 + value: 'Lightspeed',
  241 + children: [{
  242 + label: '加速进入',
  243 + value: 'lightSpeedIn'
  244 + },
  245 + {
  246 + label: '加速退出',
  247 + value: 'lightSpeedOut'
  248 + }
  249 + ]
  250 + },
  251 +
  252 + {
  253 + label: '旋转渐显',
  254 + value: 'Rotating Entrances',
  255 + children: [{
  256 + label: '旋转渐显',
  257 + value: 'rotateIn'
  258 + },
  259 + {
  260 + label: '左下角旋转渐显',
  261 + value: 'rotateInDownLeft'
  262 + },
  263 + {
  264 + label: '旋转渐显',
  265 + value: '右下角rotateInDownRight'
  266 + },
  267 + {
  268 + label: '左上角旋转渐显',
  269 + value: 'rotateInUpLeft'
  270 + },
  271 + {
  272 + label: '右上角旋转渐显',
  273 + value: 'rotateInUpRight'
  274 + }
  275 + ]
  276 + },
  277 +
  278 + {
  279 + label: '旋转渐隐',
  280 + value: 'Rotating Exits',
  281 + children: [
  282 + {
  283 + label: '旋转渐隐',
  284 + value: 'rotateOut'
  285 + },
  286 + {
  287 + label: '左下角旋转渐隐',
  288 + value: 'rotateOutDownLeft'
  289 + },
  290 + {
  291 + label: '左下角旋转渐隐',
  292 + value: 'rotateOutDownRight'
  293 + },
  294 + {
  295 + label: '左上角旋转渐隐',
  296 + value: 'rotateOutUpLeft'
  297 + },
  298 + {
  299 + label: '右上角旋转渐隐',
  300 + value: 'rotateOutUpRight'
  301 + }
  302 + ]
  303 + },
  304 +
  305 + {
  306 + label: '平移进入',
  307 + value: 'Sliding Entrances',
  308 + children: [{
  309 + label: '向上平移进入',
  310 + value: 'slideInUp'
  311 + },
  312 + {
  313 + label: '向下平移进入',
  314 + value: 'slideInDown'
  315 + },
  316 + {
  317 + label: '向右平移进入',
  318 + value: 'slideInLeft'
  319 + },
  320 + {
  321 + label: '向左平移进入',
  322 + value: 'slideInRight'
  323 + }
  324 +
  325 + ]
  326 + },
  327 + {
  328 + label: '平移退出',
  329 + value: 'Sliding Exits',
  330 + children: [{
  331 + label: '向上平移退出',
  332 + value: 'slideOutUp'
  333 + },
  334 + {
  335 + label: '向下平移退出',
  336 + value: 'slideOutDown'
  337 + },
  338 + {
  339 + label: '向左平移退出',
  340 + value: 'slideOutLeft'
  341 + },
  342 + {
  343 + label: '向右平移退出',
  344 + value: 'slideOutRight'
  345 + }
  346 + ]
  347 + },
  348 +
  349 + {
  350 + label: '放大进入',
  351 + value: 'Zoom Entrances',
  352 + children: [{
  353 + label: '放大进入',
  354 + value: 'zoomIn'
  355 + },
  356 + {
  357 + label: '向下放大进入',
  358 + value: 'zoomInDown'
  359 + },
  360 + {
  361 + label: '向右放大进入',
  362 + value: 'zoomInLeft'
  363 + },
  364 + {
  365 + label: '向左放大进入',
  366 + value: 'zoomInRight'
  367 + },
  368 + {
  369 + label: '向上放大进入',
  370 + value: 'zoomInUp'
  371 + }
  372 + ]
  373 + },
  374 +
  375 + {
  376 + label: '缩小退出',
  377 + value: 'Zoom Exits',
  378 + children: [{
  379 + label: '缩小退出',
  380 + value: 'zoomOut'
  381 + },
  382 + {
  383 + label: '向下缩小退出',
  384 + value: 'zoomOutDown'
  385 + },
  386 + {
  387 + label: '向左缩小退出',
  388 + value: 'zoomOutLeft'
  389 + },
  390 + {
  391 + label: '向右缩小退出',
  392 + value: 'zoomOutRight'
  393 + },
  394 + {
  395 + label: '向上缩小退出',
  396 + value: 'zoomOutUp'
  397 + }
  398 + ]
  399 + },
  400 +
  401 + {
  402 + label: '特殊效果',
  403 + value: 'Specials',
  404 + children: [
  405 + {
  406 + label: '悬挂',
  407 + value: 'hinge'
  408 + },
  409 + {
  410 + label: '滚动进入',
  411 + value: 'rollIn'
  412 + },
  413 + {
  414 + label: '滚动退出',
  415 + value: 'rollOut'
  416 + }
  417 + ]
  418 + }
  419 +]
  420 +
  421 +/**
  422 + * @return {Object} { animationValue: animatonLabel }
  423 + */
  424 +export const animationValue2Name = animationOptions.reduce((obj, curr) => {
  425 + const items = curr.children
  426 + items.forEach(item => { obj[item.value] = item.label })
  427 + return obj
  428 +}, {})
front-end/h5/yarn.lock
@@ -1369,6 +1369,11 @@ amdefine@&gt;=0.0.4: @@ -1369,6 +1369,11 @@ amdefine@&gt;=0.0.4:
1369 resolved "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" 1369 resolved "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
1370 integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= 1370 integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
1371 1371
  1372 +animate.css@^3.7.2:
  1373 + version "3.7.2"
  1374 + resolved "https://registry.npm.taobao.org/animate.css/download/animate.css-3.7.2.tgz#e73e0d50e92cb1cfef1597d9b38a9481020e08ea"
  1375 + integrity sha1-5z4NUOkssc/vFZfZs4qUgQIOCOo=
  1376 +
1372 ansi-colors@^3.0.0: 1377 ansi-colors@^3.0.0:
1373 version "3.2.4" 1378 version "3.2.4"
1374 resolved "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" 1379 resolved "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"