Commit 0bd23421a802bb762764e0fbbfbeb8edd50a3e62
1 parent
a34f5f11
feat(preview): add preview modal
Showing
10 changed files
with
371 additions
and
13 deletions
back-end/h5-api/views/engine.ejs
| @@ -17,6 +17,9 @@ | @@ -17,6 +17,9 @@ | ||
| 17 | <script>window.__work = <%- JSON.stringify(work) %></script> | 17 | <script>window.__work = <%- JSON.stringify(work) %></script> |
| 18 | <script src="/engine-assets/engine.js"></script> | 18 | <script src="/engine-assets/engine.js"></script> |
| 19 | <style> | 19 | <style> |
| 20 | + * { | ||
| 21 | + outline: none; | ||
| 22 | + } | ||
| 20 | .swiper-container { | 23 | .swiper-container { |
| 21 | width: 100%; | 24 | width: 100%; |
| 22 | height: 100vh; | 25 | height: 100vh; |
| @@ -26,7 +29,9 @@ | @@ -26,7 +29,9 @@ | ||
| 26 | 29 | ||
| 27 | <body> | 30 | <body> |
| 28 | <div id="app"> | 31 | <div id="app"> |
| 29 | - <engine /> | 32 | + <button class="swiper-button-next" style="position: fixed;left: 1000px">Next</button> |
| 33 | + <button class="swiper-button-prev" style="position: fixed;left: 1000px">Prev</button> | ||
| 34 | + <engine /> | ||
| 30 | </div> | 35 | </div> |
| 31 | <script> | 36 | <script> |
| 32 | // Vue.component('engine', window.Engine) | 37 | // Vue.component('engine', window.Engine) |
| @@ -59,6 +64,18 @@ | @@ -59,6 +64,18 @@ | ||
| 59 | el: '.swiper-scrollbar', | 64 | el: '.swiper-scrollbar', |
| 60 | }, | 65 | }, |
| 61 | }); | 66 | }); |
| 67 | + | ||
| 68 | + function displayMessage ({ origin, data }) { | ||
| 69 | + if (data && origin === "http://localhost:8080") { | ||
| 70 | + document.querySelector(`.swiper-button-${data}`).click() | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + if (window.addEventListener) { | ||
| 75 | + window.addEventListener("message", displayMessage, false); | ||
| 76 | + } else { | ||
| 77 | + window.attachEvent("onmessage", displayMessage); | ||
| 78 | + } | ||
| 62 | </script> | 79 | </script> |
| 63 | <!-- build:js scripts/vendor.js --> | 80 | <!-- build:js scripts/vendor.js --> |
| 64 | <!-- endbuild --> | 81 | <!-- endbuild --> |
front-end/h5/package.json
| @@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
| 15 | "core-js": "^2.6.5", | 15 | "core-js": "^2.6.5", |
| 16 | "element-ui": "^2.9.1", | 16 | "element-ui": "^2.9.1", |
| 17 | "font-awesome": "4.7.0", | 17 | "font-awesome": "4.7.0", |
| 18 | + "qrcode": "^1.4.1", | ||
| 18 | "register-service-worker": "^1.6.2", | 19 | "register-service-worker": "^1.6.2", |
| 19 | "strapi-sdk-javascript": "^0.3.1", | 20 | "strapi-sdk-javascript": "^0.3.1", |
| 20 | "vue": "^2.6.10", | 21 | "vue": "^2.6.10", |
front-end/h5/public/index.html
| @@ -6,6 +6,11 @@ | @@ -6,6 +6,11 @@ | ||
| 6 | <meta name="viewport" content="width=device-width,initial-scale=1.0"> | 6 | <meta name="viewport" content="width=device-width,initial-scale=1.0"> |
| 7 | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | 7 | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
| 8 | <title>鲁班-H5</title> | 8 | <title>鲁班-H5</title> |
| 9 | + <style> | ||
| 10 | + * { | ||
| 11 | + outline: none; | ||
| 12 | + } | ||
| 13 | + </style> | ||
| 9 | </head> | 14 | </head> |
| 10 | <body> | 15 | <body> |
| 11 | <noscript> | 16 | <noscript> |
front-end/h5/src/components/core/editor/index.js
| @@ -10,6 +10,7 @@ import RenderPropsEditor from './edit-panel/props' | @@ -10,6 +10,7 @@ import RenderPropsEditor from './edit-panel/props' | ||
| 10 | import RenderScriptEditor from './edit-panel/script' | 10 | import RenderScriptEditor from './edit-panel/script' |
| 11 | import RenderActoionEditor from './edit-panel/action' | 11 | import RenderActoionEditor from './edit-panel/action' |
| 12 | import RenderShortcutsPanel from './shortcuts-panel/index' | 12 | import RenderShortcutsPanel from './shortcuts-panel/index' |
| 13 | +import PreviewDialog from './modals/preview.vue' | ||
| 13 | 14 | ||
| 14 | const sidebarMenus = [ | 15 | const sidebarMenus = [ |
| 15 | { | 16 | { |
| @@ -34,7 +35,8 @@ export default { | @@ -34,7 +35,8 @@ export default { | ||
| 34 | data: () => ({ | 35 | data: () => ({ |
| 35 | activeMenuKey: 'pluginList', | 36 | activeMenuKey: 'pluginList', |
| 36 | isPreviewMode: false, | 37 | isPreviewMode: false, |
| 37 | - activeTabKey: '属性' | 38 | + activeTabKey: '属性', |
| 39 | + previewVisible: false | ||
| 38 | }), | 40 | }), |
| 39 | computed: { | 41 | computed: { |
| 40 | ...mapState('editor', { | 42 | ...mapState('editor', { |
| @@ -109,7 +111,7 @@ export default { | @@ -109,7 +111,7 @@ export default { | ||
| 109 | <a-button class="transparent-bg" style={{ color: 'white' }} type="dashed" size="small" onClick={() => undoRedoHistory.redo()}><i class={['shortcut-icon', 'fa', `fa-mail-forward`]} aria-hidden='true'/> 重做</a-button> | 111 | <a-button class="transparent-bg" style={{ color: 'white' }} type="dashed" size="small" onClick={() => undoRedoHistory.redo()}><i class={['shortcut-icon', 'fa', `fa-mail-forward`]} aria-hidden='true'/> 重做</a-button> |
| 110 | </a-button-group> | 112 | </a-button-group> |
| 111 | </a-menu-item> | 113 | </a-menu-item> |
| 112 | - <a-menu-item key="1" class="transparent-bg"><a-button type="primary" size="small">预览</a-button></a-menu-item> | 114 | + <a-menu-item key="1" class="transparent-bg"><a-button type="primary" size="small" onClick={() => { this.previewVisible = true }}>预览</a-button></a-menu-item> |
| 113 | <a-menu-item key="2" class="transparent-bg"><a-button size="small" onClick={() => this.saveWork()}>保存</a-button></a-menu-item> | 115 | <a-menu-item key="2" class="transparent-bg"><a-button size="small" onClick={() => this.saveWork()}>保存</a-button></a-menu-item> |
| 114 | <a-menu-item key="3" class="transparent-bg"><a-button size="small">发布</a-button></a-menu-item> | 116 | <a-menu-item key="3" class="transparent-bg"><a-button size="small">发布</a-button></a-menu-item> |
| 115 | </a-menu> | 117 | </a-menu> |
| @@ -185,6 +187,7 @@ export default { | @@ -185,6 +187,7 @@ export default { | ||
| 185 | </a-tabs> | 187 | </a-tabs> |
| 186 | </a-layout-sider> | 188 | </a-layout-sider> |
| 187 | </a-layout> | 189 | </a-layout> |
| 190 | + <PreviewDialog visible={this.previewVisible} handleClose={() => { this.previewVisible = false }} /> | ||
| 188 | </a-layout> | 191 | </a-layout> |
| 189 | ) | 192 | ) |
| 190 | }, | 193 | }, |
front-end/h5/src/components/core/editor/modals/preview.vue
0 → 100644
| 1 | +<script> | ||
| 2 | +import { mapActions, mapState } from 'vuex' | ||
| 3 | +import QRCode from 'qrcode' | ||
| 4 | +export default { | ||
| 5 | + props: { | ||
| 6 | + visible: { | ||
| 7 | + type: Boolean, | ||
| 8 | + default: false | ||
| 9 | + }, | ||
| 10 | + handleClose: { | ||
| 11 | + type: Function, | ||
| 12 | + default: () => {} | ||
| 13 | + } | ||
| 14 | + }, | ||
| 15 | + computed: { | ||
| 16 | + ...mapState('editor', { | ||
| 17 | + work: state => state.work, | ||
| 18 | + }), | ||
| 19 | + releaseUrl () { | ||
| 20 | + return `//localhost:1337/works/preview/${this.work.id}` | ||
| 21 | + } | ||
| 22 | + }, | ||
| 23 | + data() { | ||
| 24 | + return { | ||
| 25 | + confirmLoading: false, | ||
| 26 | + qrcodeSize: 500, | ||
| 27 | + } | ||
| 28 | + }, | ||
| 29 | + watch: { | ||
| 30 | + visible (val) { | ||
| 31 | + if (!val) return; | ||
| 32 | + this.$nextTick(() => this.drawQRcode()); | ||
| 33 | + }, | ||
| 34 | + }, | ||
| 35 | + methods: { | ||
| 36 | + ...mapActions('editor', [ | ||
| 37 | + 'saveWork', | ||
| 38 | + 'updateWork' | ||
| 39 | + ]), | ||
| 40 | + handleOk(e) { | ||
| 41 | + this.confirmLoading = true; | ||
| 42 | + this.saveWork().then(res => { | ||
| 43 | + this.handleClose() | ||
| 44 | + this.confirmLoading = false; | ||
| 45 | + }) | ||
| 46 | + // setTimeout(() => { | ||
| 47 | + // }, 2000); | ||
| 48 | + }, | ||
| 49 | + handleCancel(e) { | ||
| 50 | + console.log('Clicked cancel button'); | ||
| 51 | + this.handleClose() | ||
| 52 | + }, | ||
| 53 | + drawQRcode () { | ||
| 54 | + var canvas = document.getElementById('qrcode-container'); | ||
| 55 | + QRCode.toCanvas(canvas, this.releaseUrl, { scale: 4 }, err => { | ||
| 56 | + console.log(err); | ||
| 57 | + }); | ||
| 58 | + }, | ||
| 59 | + postMessage2Iframe (message) { | ||
| 60 | + let iframeWin = document.getElementById('iframe-for-preview').contentWindow | ||
| 61 | + // iframeWin.postMessage('next', window.location.origin); | ||
| 62 | + iframeWin.postMessage(message, 'http://localhost:1337'); | ||
| 63 | + } | ||
| 64 | + }, | ||
| 65 | + render (h) { | ||
| 66 | + return ( | ||
| 67 | + <div> | ||
| 68 | + <a-modal | ||
| 69 | + title="作品设置" | ||
| 70 | + visible={this.visible} | ||
| 71 | + confirmLoading={this.confirmLoading} | ||
| 72 | + onOk={this.handleOk} | ||
| 73 | + onCancel={this.handleCancel} | ||
| 74 | + width="70%" | ||
| 75 | + okText="保存" | ||
| 76 | + > | ||
| 77 | + <div class="preview-wrapper"> | ||
| 78 | + <a-row gutter={20}> | ||
| 79 | + <a-col span={8}> | ||
| 80 | + <div class="phone-wrapper"> | ||
| 81 | + <div class="phone"> | ||
| 82 | + <div class="float-ctrl-panel"> | ||
| 83 | + <a class="page-controller" onClick={(e) => { this.postMessage2Iframe('prev') }}>上一页</a> | ||
| 84 | + <a class="page-controller" onClick={(e) => { this.postMessage2Iframe('next') }}>下一页</a> | ||
| 85 | + {/** | ||
| 86 | + <a-button icon="up" shape="circle" onClick={() => { this.postMessage2Iframe('prev') }}></a-button> | ||
| 87 | + <a-button icon="down" shape="circle" onClick={() => { this.postMessage2Iframe('next') }}></a-button> | ||
| 88 | + <a-icon type="up" class="page-controller" onClick={() => { this.postMessage2Iframe('prev') }}/> | ||
| 89 | + <a-icon type="down" class="page-controller" onClick={() => { this.postMessage2Iframe('next') }}/> | ||
| 90 | + */} | ||
| 91 | + </div> | ||
| 92 | + <iframe | ||
| 93 | + id="iframe-for-preview" | ||
| 94 | + src="http://localhost:1337/works/preview/12" | ||
| 95 | + frameborder="0" | ||
| 96 | + style="height: 100%;width: 100%;" | ||
| 97 | + ></iframe> | ||
| 98 | + {/** <engine :work="editingWork" :map-config="{}" /> */} | ||
| 99 | + </div> | ||
| 100 | + </div> | ||
| 101 | + </a-col> | ||
| 102 | + <a-col span={12} offset={4}> | ||
| 103 | + <div class="setting"> | ||
| 104 | + <div class="info"> | ||
| 105 | + <div class="label">设置作品信息</div> | ||
| 106 | + <a-input | ||
| 107 | + class="input" | ||
| 108 | + value={this.work.title} | ||
| 109 | + onChange={e => this.updateWork({ title: e.target.value})} | ||
| 110 | + // onBlur={this.saveTitle} | ||
| 111 | + placeholder="请输入标题" | ||
| 112 | + ></a-input> | ||
| 113 | + <a-input | ||
| 114 | + class="input" | ||
| 115 | + value={this.work.description} | ||
| 116 | + onChange={e => this.updateWork({ description: e.target.value})} | ||
| 117 | + // v-model="description" | ||
| 118 | + // onBlur={this.saveDescription} | ||
| 119 | + placeholder="请输入描述" | ||
| 120 | + type="textarea" | ||
| 121 | + ></a-input> | ||
| 122 | + </div> | ||
| 123 | + <div class="qrcode my-4"> | ||
| 124 | + <div class="label">手机扫码分享给好友</div> | ||
| 125 | + <div class="code"> | ||
| 126 | + <canvas style="float: left" id="qrcode-container"></canvas> | ||
| 127 | + <a-radio-group class="radios" value={this.qrcodeSize} onChange={e => {this.qrcodeSize = e.target.value}}> | ||
| 128 | + <a-radio label={500} value={500}>500x500</a-radio> | ||
| 129 | + <a-radio label={1000} value={1000}>1000x1000</a-radio> | ||
| 130 | + <a-radio label={2000} value={2000}>2000x2000</a-radio> | ||
| 131 | + </a-radio-group> | ||
| 132 | + </div> | ||
| 133 | + </div> | ||
| 134 | + </div> | ||
| 135 | + </a-col> | ||
| 136 | + </a-row> | ||
| 137 | + </div> | ||
| 138 | + </a-modal> | ||
| 139 | + </div> | ||
| 140 | + ) | ||
| 141 | + }, | ||
| 142 | + mounted () { | ||
| 143 | + } | ||
| 144 | +} | ||
| 145 | +</script> | ||
| 146 | + | ||
| 147 | + | ||
| 148 | +<style lang="scss"> | ||
| 149 | +.preview-wrapper { | ||
| 150 | + position: relative; | ||
| 151 | + min-height: 600px; | ||
| 152 | + min-width: 800px; | ||
| 153 | + | ||
| 154 | + .phone-wrapper { | ||
| 155 | + position: absolute; | ||
| 156 | + // margin-top: -300px; | ||
| 157 | + left: 10px; | ||
| 158 | + top: 50%; | ||
| 159 | + width: 320px; | ||
| 160 | + height: 600px; | ||
| 161 | + box-sizing: content-box; | ||
| 162 | + .phone { | ||
| 163 | + position: absolute; | ||
| 164 | + // left: 40px; | ||
| 165 | + width: 100%; | ||
| 166 | + height: calc(638px - 70px); | ||
| 167 | + display: inline-block; | ||
| 168 | + background: #fff; | ||
| 169 | + box-sizing: content-box; | ||
| 170 | + border-top: 10px solid #f6f6f6; | ||
| 171 | + border-left: 10px solid #f6f6f6; | ||
| 172 | + border-right: 10px solid #f6f6f6; | ||
| 173 | + border-bottom: 20px solid #f6f6f6; | ||
| 174 | + border-radius: 20px; | ||
| 175 | + -webkit-transform-origin: 100% 0; | ||
| 176 | + transform-origin: 100% 0; | ||
| 177 | + -webkit-transform: scale(1); | ||
| 178 | + transform: scale(1); | ||
| 179 | + | ||
| 180 | + .float-ctrl-panel { | ||
| 181 | + position: absolute; | ||
| 182 | + top: 100px; | ||
| 183 | + right: -40px; | ||
| 184 | + | ||
| 185 | + .page-controller { | ||
| 186 | + display: block; | ||
| 187 | + cursor: pointer; | ||
| 188 | + width: 30px; | ||
| 189 | + height: 80px; | ||
| 190 | + border-top-right-radius: 5px; | ||
| 191 | + border-bottom-right-radius: 5px; | ||
| 192 | + background: #2096f9; | ||
| 193 | + font-size: 12px; | ||
| 194 | + text-align: center; | ||
| 195 | + border: 1px solid #2096f9; | ||
| 196 | + color: #fff; | ||
| 197 | + // position: absolute; | ||
| 198 | + padding: 14px 8px; | ||
| 199 | + margin-top: 12px; | ||
| 200 | + // margin-top: -50px; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + } | ||
| 206 | + .setting { | ||
| 207 | + color: #4a4a4a; | ||
| 208 | + font-size: 14px; | ||
| 209 | + float: right; | ||
| 210 | + width: 380px; | ||
| 211 | + .info { | ||
| 212 | + .input { | ||
| 213 | + margin-top: 10px; | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + .qrcode { | ||
| 217 | + margin-top: 20px; | ||
| 218 | + } | ||
| 219 | + .code { | ||
| 220 | + // !#zh 防止浮动塌陷 | ||
| 221 | + overflow: hidden; | ||
| 222 | + .radios { | ||
| 223 | + width: 80px; | ||
| 224 | + margin-top: 5px; | ||
| 225 | + margin-left: 30px; | ||
| 226 | + label { | ||
| 227 | + margin-left: 0px; | ||
| 228 | + margin-top: 10px; | ||
| 229 | + } | ||
| 230 | + button { | ||
| 231 | + margin-top: 15px; | ||
| 232 | + } | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + .link { | ||
| 236 | + width: 100%; | ||
| 237 | + display: block; | ||
| 238 | + } | ||
| 239 | + .edit { | ||
| 240 | + text-align: center; | ||
| 241 | + margin-top: 20px; | ||
| 242 | + } | ||
| 243 | + } | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | +</style> | ||
| 0 | \ No newline at end of file | 247 | \ No newline at end of file |
front-end/h5/src/components/core/models/element.js
| 1 | +import { parsePx } from '../../../utils/element.js' | ||
| 2 | + | ||
| 1 | const clone = (value) => JSON.parse(JSON.stringify(value)) | 3 | const clone = (value) => JSON.parse(JSON.stringify(value)) |
| 2 | 4 | ||
| 3 | const defaultProps = { | 5 | const defaultProps = { |
| @@ -56,14 +58,14 @@ class Element { | @@ -56,14 +58,14 @@ class Element { | ||
| 56 | return pluginProps | 58 | return pluginProps |
| 57 | } | 59 | } |
| 58 | 60 | ||
| 59 | - getStyle ({ position = 'static' }) { | 61 | + getStyle ({ position = 'static', isRem = false }) { |
| 60 | const pluginProps = this.pluginProps | 62 | const pluginProps = this.pluginProps |
| 61 | const commonStyle = this.commonStyle | 63 | const commonStyle = this.commonStyle |
| 62 | let style = { | 64 | let style = { |
| 63 | - top: `${pluginProps.top || commonStyle.top}px`, | ||
| 64 | - left: `${pluginProps.left || commonStyle.left}px`, | ||
| 65 | - width: `${pluginProps.width || commonStyle.width}px`, | ||
| 66 | - height: `${pluginProps.height || commonStyle.height}px`, | 65 | + top: parsePx(pluginProps.top || commonStyle.top), |
| 66 | + left: parsePx(pluginProps.left || commonStyle.left), | ||
| 67 | + width: parsePx(pluginProps.width || commonStyle.width), | ||
| 68 | + height: parsePx(pluginProps.height || commonStyle.height), | ||
| 67 | fontSize: `${pluginProps.fontSize || commonStyle.fontSize}px`, | 69 | fontSize: `${pluginProps.fontSize || commonStyle.fontSize}px`, |
| 68 | color: pluginProps.color || commonStyle.color, | 70 | color: pluginProps.color || commonStyle.color, |
| 69 | // backgroundColor: pluginProps.backgroundColor || commonStyle.backgroundColor, | 71 | // backgroundColor: pluginProps.backgroundColor || commonStyle.backgroundColor, |
front-end/h5/src/store/modules/work.js
| @@ -18,9 +18,21 @@ export const actions = { | @@ -18,9 +18,21 @@ export const actions = { | ||
| 18 | // commit('pageManager', { type: 'add' }) | 18 | // commit('pageManager', { type: 'add' }) |
| 19 | // commit('setEditingPage') | 19 | // commit('setEditingPage') |
| 20 | }, | 20 | }, |
| 21 | + updateWork ({ commit, state }, payload = {}) { | ||
| 22 | + // update work with strapi | ||
| 23 | + const work = { | ||
| 24 | + ...state.work, | ||
| 25 | + ...payload | ||
| 26 | + } | ||
| 27 | + commit('setWork', work) | ||
| 28 | + }, | ||
| 21 | saveWork ({ commit, state }, payload = {}) { | 29 | saveWork ({ commit, state }, payload = {}) { |
| 22 | // update work with strapi | 30 | // update work with strapi |
| 23 | - strapi.updateEntry('works', state.work.id, state.work) | 31 | + const work = { |
| 32 | + ...state.work, | ||
| 33 | + ...payload | ||
| 34 | + } | ||
| 35 | + strapi.updateEntry('works', state.work.id, work) | ||
| 24 | }, | 36 | }, |
| 25 | fetchWork ({ commit, state }, workId) { | 37 | fetchWork ({ commit, state }, workId) { |
| 26 | strapi.getEntry('works', workId).then(entry => { | 38 | strapi.getEntry('works', workId).then(entry => { |
front-end/h5/src/utils/element.js
| 1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
| 2 | 2 | ||
| 3 | +const DESIGN_DRAFT_WIDTH = 320 | ||
| 4 | +const styleKey = 'commonStyle' | ||
| 5 | + | ||
| 3 | export function getEditorConfigForEditingElement (elementName) { | 6 | export function getEditorConfigForEditingElement (elementName) { |
| 4 | const Ctor = Vue.component(elementName) | 7 | const Ctor = Vue.component(elementName) |
| 5 | // TODO 为何直接 return new Ctor() 并将其赋值给 vuex 的 state 会报错:Cannot convert a Symbol value to a string | 8 | // TODO 为何直接 return new Ctor() 并将其赋值给 vuex 的 state 会报错:Cannot convert a Symbol value to a string |
| 6 | return new Ctor().$options.editorConfig | 9 | return new Ctor().$options.editorConfig |
| 7 | } | 10 | } |
| 8 | 11 | ||
| 9 | -const styleKey = 'commonStyle' | ||
| 10 | export function swapZindex (x, y) { | 12 | export function swapZindex (x, y) { |
| 11 | const tmp = y[styleKey].zindex | 13 | const tmp = y[styleKey].zindex |
| 12 | y[styleKey].zindex = x[styleKey].zindex | 14 | y[styleKey].zindex = x[styleKey].zindex |
| 13 | x[styleKey].zindex = tmp | 15 | x[styleKey].zindex = tmp |
| 14 | } | 16 | } |
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * !#zh 将 px 转换为 rem | ||
| 20 | + * @param {Number} px | ||
| 21 | + */ | ||
| 22 | +function px2Rem (px) { | ||
| 23 | + const number = Math.pow(10, 6) | ||
| 24 | + const val = (px / (DESIGN_DRAFT_WIDTH / 10)) * number | ||
| 25 | + const rem = Math.round(val) / number + 'rem' | ||
| 26 | + return rem | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * | ||
| 31 | + * @param {Number} px 元素的某个属性的像素值,比如 height | ||
| 32 | + * @param {Boolean} isToRem 是否将 px 转换为 rem | ||
| 33 | + */ | ||
| 34 | +export function parsePx (px, isRem = false) { | ||
| 35 | + if (isRem) return px2Rem(px) | ||
| 36 | + return `${px}px` | ||
| 37 | +} |
front-end/h5/vue.config.js
| @@ -12,9 +12,9 @@ module.exports = { | @@ -12,9 +12,9 @@ module.exports = { | ||
| 12 | template: 'public/index.html', | 12 | template: 'public/index.html', |
| 13 | filename: 'index.html', | 13 | filename: 'index.html', |
| 14 | title: 'Index Page' | 14 | title: 'Index Page' |
| 15 | - }, | ||
| 16 | - engine: { | ||
| 17 | - entry: 'src/components/core/editor/engine/index.js' | ||
| 18 | } | 15 | } |
| 16 | + // engine: { | ||
| 17 | + // entry: 'src/engine-entry.js' | ||
| 18 | + // } | ||
| 19 | } | 19 | } |
| 20 | } | 20 | } |
front-end/h5/yarn.lock
| @@ -3399,6 +3399,11 @@ diffie-hellman@^5.0.0: | @@ -3399,6 +3399,11 @@ diffie-hellman@^5.0.0: | ||
| 3399 | miller-rabin "^4.0.0" | 3399 | miller-rabin "^4.0.0" |
| 3400 | randombytes "^2.0.0" | 3400 | randombytes "^2.0.0" |
| 3401 | 3401 | ||
| 3402 | +dijkstrajs@^1.0.1: | ||
| 3403 | + version "1.0.1" | ||
| 3404 | + resolved "https://registry.npm.taobao.org/dijkstrajs/download/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b" | ||
| 3405 | + integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs= | ||
| 3406 | + | ||
| 3402 | dir-glob@^2.0.0, dir-glob@^2.2.2: | 3407 | dir-glob@^2.0.0, dir-glob@^2.2.2: |
| 3403 | version "2.2.2" | 3408 | version "2.2.2" |
| 3404 | resolved "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" | 3409 | resolved "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" |
| @@ -5760,6 +5765,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: | @@ -5760,6 +5765,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: | ||
| 5760 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" | 5765 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" |
| 5761 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= | 5766 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= |
| 5762 | 5767 | ||
| 5768 | +isarray@^2.0.1: | ||
| 5769 | + version "2.0.5" | ||
| 5770 | + resolved "https://registry.npm.taobao.org/isarray/download/isarray-2.0.5.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" | ||
| 5771 | + integrity sha1-ivHkwSISRMxiRZ+vOJQNTmRKVyM= | ||
| 5772 | + | ||
| 5763 | isemail@3.x.x: | 5773 | isemail@3.x.x: |
| 5764 | version "3.2.0" | 5774 | version "3.2.0" |
| 5765 | resolved "https://registry.npm.taobao.org/isemail/download/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" | 5775 | resolved "https://registry.npm.taobao.org/isemail/download/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" |
| @@ -7920,6 +7930,11 @@ pn@^1.1.0: | @@ -7920,6 +7930,11 @@ pn@^1.1.0: | ||
| 7920 | resolved "https://registry.npm.taobao.org/pn/download/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" | 7930 | resolved "https://registry.npm.taobao.org/pn/download/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" |
| 7921 | integrity sha1-4vTO8OIZ9GPBeas3Rj5OHs3Muvs= | 7931 | integrity sha1-4vTO8OIZ9GPBeas3Rj5OHs3Muvs= |
| 7922 | 7932 | ||
| 7933 | +pngjs@^3.3.0: | ||
| 7934 | + version "3.4.0" | ||
| 7935 | + resolved "https://registry.npm.taobao.org/pngjs/download/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" | ||
| 7936 | + integrity sha1-mcp9clll+2VYFOr2XzjxK72/VV8= | ||
| 7937 | + | ||
| 7923 | portfinder@^1.0.20: | 7938 | portfinder@^1.0.20: |
| 7924 | version "1.0.20" | 7939 | version "1.0.20" |
| 7925 | resolved "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" | 7940 | resolved "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" |
| @@ -8440,6 +8455,16 @@ q@^1.1.2: | @@ -8440,6 +8455,16 @@ q@^1.1.2: | ||
| 8440 | resolved "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" | 8455 | resolved "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" |
| 8441 | integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= | 8456 | integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= |
| 8442 | 8457 | ||
| 8458 | +qrcode@^1.4.1: | ||
| 8459 | + version "1.4.1" | ||
| 8460 | + resolved "https://registry.npm.taobao.org/qrcode/download/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b" | ||
| 8461 | + integrity sha1-ISaBSYXQ272a7gUPxSPTGcan3Ds= | ||
| 8462 | + dependencies: | ||
| 8463 | + dijkstrajs "^1.0.1" | ||
| 8464 | + isarray "^2.0.1" | ||
| 8465 | + pngjs "^3.3.0" | ||
| 8466 | + yargs "^13.2.4" | ||
| 8467 | + | ||
| 8443 | qs@6.7.0, qs@^6.5.2: | 8468 | qs@6.7.0, qs@^6.5.2: |
| 8444 | version "6.7.0" | 8469 | version "6.7.0" |
| 8445 | resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" | 8470 | resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" |
| @@ -10895,6 +10920,14 @@ yargs-parser@^13.1.0: | @@ -10895,6 +10920,14 @@ yargs-parser@^13.1.0: | ||
| 10895 | camelcase "^5.0.0" | 10920 | camelcase "^5.0.0" |
| 10896 | decamelize "^1.2.0" | 10921 | decamelize "^1.2.0" |
| 10897 | 10922 | ||
| 10923 | +yargs-parser@^13.1.1: | ||
| 10924 | + version "13.1.1" | ||
| 10925 | + resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-13.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" | ||
| 10926 | + integrity sha1-0mBYUyqgbTZf4JH2ofwGsvfl7KA= | ||
| 10927 | + dependencies: | ||
| 10928 | + camelcase "^5.0.0" | ||
| 10929 | + decamelize "^1.2.0" | ||
| 10930 | + | ||
| 10898 | yargs-parser@^9.0.2: | 10931 | yargs-parser@^9.0.2: |
| 10899 | version "9.0.2" | 10932 | version "9.0.2" |
| 10900 | resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-9.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" | 10933 | resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-9.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" |
| @@ -10955,6 +10988,22 @@ yargs@^13.0.0: | @@ -10955,6 +10988,22 @@ yargs@^13.0.0: | ||
| 10955 | y18n "^4.0.0" | 10988 | y18n "^4.0.0" |
| 10956 | yargs-parser "^13.1.0" | 10989 | yargs-parser "^13.1.0" |
| 10957 | 10990 | ||
| 10991 | +yargs@^13.2.4: | ||
| 10992 | + version "13.3.0" | ||
| 10993 | + resolved "https://registry.npm.taobao.org/yargs/download/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" | ||
| 10994 | + integrity sha1-TGV6VeB+Xyz5R/ijZlZ8BKDe3IM= | ||
| 10995 | + dependencies: | ||
| 10996 | + cliui "^5.0.0" | ||
| 10997 | + find-up "^3.0.0" | ||
| 10998 | + get-caller-file "^2.0.1" | ||
| 10999 | + require-directory "^2.1.1" | ||
| 11000 | + require-main-filename "^2.0.0" | ||
| 11001 | + set-blocking "^2.0.0" | ||
| 11002 | + string-width "^3.0.0" | ||
| 11003 | + which-module "^2.0.0" | ||
| 11004 | + y18n "^4.0.0" | ||
| 11005 | + yargs-parser "^13.1.1" | ||
| 11006 | + | ||
| 10958 | yauzl@2.10.0: | 11007 | yauzl@2.10.0: |
| 10959 | version "2.10.0" | 11008 | version "2.10.0" |
| 10960 | resolved "https://registry.npm.taobao.org/yauzl/download/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" | 11009 | resolved "https://registry.npm.taobao.org/yauzl/download/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" |