Commit 39d9f8fdcce6dcbaafd765986a55ffeaa58e4b6a
1 parent
1102fe32
feat(preview): build preview engine
Showing
9 changed files
with
230 additions
and
9 deletions
back-end/h5-api/api/work/config/routes.json
back-end/h5-api/api/work/controllers/Work.js
| @@ -5,4 +5,10 @@ | @@ -5,4 +5,10 @@ | ||
| 5 | * to customize this controller | 5 | * to customize this controller |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | -module.exports = {}; | 8 | +module.exports = { |
| 9 | + // GET /previewOne | ||
| 10 | + // strapi-hook-ejs: https://github.com/strapi/strapi/tree/master/packages/strapi-hook-ejs | ||
| 11 | + previewOne: async (ctx) => { | ||
| 12 | + return ctx.render('engine', {work: { page2: []}}); | ||
| 13 | + } | ||
| 14 | +}; |
back-end/h5-api/config/hook.json
| @@ -6,5 +6,13 @@ | @@ -6,5 +6,13 @@ | ||
| 6 | "Define the hooks' load order by putting their names in this array in the right order" | 6 | "Define the hooks' load order by putting their names in this array in the right order" |
| 7 | ], | 7 | ], |
| 8 | "after": [] | 8 | "after": [] |
| 9 | + }, | ||
| 10 | + "ejs": { | ||
| 11 | + "enabled": true, | ||
| 12 | + "viewExt": "ejs", | ||
| 13 | + "partial": true, | ||
| 14 | + "cache": false, | ||
| 15 | + "debug": true, | ||
| 16 | + "layout": false | ||
| 9 | } | 17 | } |
| 10 | } | 18 | } |
back-end/h5-api/package.json
| @@ -18,20 +18,22 @@ | @@ -18,20 +18,22 @@ | ||
| 18 | "eslint-plugin-react": "^7.14.0" | 18 | "eslint-plugin-react": "^7.14.0" |
| 19 | }, | 19 | }, |
| 20 | "dependencies": { | 20 | "dependencies": { |
| 21 | + "ejs": "^2.6.2", | ||
| 22 | + "knex": "latest", | ||
| 21 | "lodash": "^4.17.5", | 23 | "lodash": "^4.17.5", |
| 24 | + "sqlite3": "latest", | ||
| 22 | "strapi": "3.0.0-beta.13", | 25 | "strapi": "3.0.0-beta.13", |
| 23 | "strapi-admin": "3.0.0-beta.13", | 26 | "strapi-admin": "3.0.0-beta.13", |
| 24 | - "strapi-utils": "3.0.0-beta.13", | ||
| 25 | - "strapi-plugin-settings-manager": "3.0.0-beta.13", | ||
| 26 | - "strapi-plugin-content-type-builder": "3.0.0-beta.13", | 27 | + "strapi-hook-bookshelf": "3.0.0-beta.13", |
| 28 | + "strapi-hook-ejs": "^3.0.0-alpha.26.2", | ||
| 29 | + "strapi-hook-knex": "3.0.0-beta.13", | ||
| 27 | "strapi-plugin-content-manager": "3.0.0-beta.13", | 30 | "strapi-plugin-content-manager": "3.0.0-beta.13", |
| 28 | - "strapi-plugin-users-permissions": "3.0.0-beta.13", | 31 | + "strapi-plugin-content-type-builder": "3.0.0-beta.13", |
| 29 | "strapi-plugin-email": "3.0.0-beta.13", | 32 | "strapi-plugin-email": "3.0.0-beta.13", |
| 33 | + "strapi-plugin-settings-manager": "3.0.0-beta.13", | ||
| 30 | "strapi-plugin-upload": "3.0.0-beta.13", | 34 | "strapi-plugin-upload": "3.0.0-beta.13", |
| 31 | - "strapi-hook-bookshelf": "3.0.0-beta.13", | ||
| 32 | - "strapi-hook-knex": "3.0.0-beta.13", | ||
| 33 | - "knex": "latest", | ||
| 34 | - "sqlite3": "latest" | 35 | + "strapi-plugin-users-permissions": "3.0.0-beta.13", |
| 36 | + "strapi-utils": "3.0.0-beta.13" | ||
| 35 | }, | 37 | }, |
| 36 | "author": { | 38 | "author": { |
| 37 | "name": "A Strapi developer" | 39 | "name": "A Strapi developer" |
back-end/h5-api/views/engine-example.ejs
0 → 100644
| 1 | +<html> | ||
| 2 | + <head> | ||
| 3 | + <title>Luban H5 Preview</title> | ||
| 4 | + </head> | ||
| 5 | + <script>window.__work = <%- JSON.stringify(work) %></script> | ||
| 6 | + <body> | ||
| 7 | + Q: What's this? | ||
| 8 | + A: A tiny render engine based on ejs for Luban H5 work | ||
| 9 | + </body> | ||
| 10 | +</html> | ||
| 0 | \ No newline at end of file | 11 | \ No newline at end of file |
front-end/h5/public/engine-example.html
0 → 100644
| 1 | +<!DOCTYPE html> | ||
| 2 | +<html lang="en"> | ||
| 3 | + <head> | ||
| 4 | + <meta charset="utf-8"> | ||
| 5 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
| 6 | + <meta name="viewport" content="width=device-width,initial-scale=1.0"> | ||
| 7 | + <title>work.html</title> | ||
| 8 | + <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | ||
| 9 | + <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"> | ||
| 10 | + <meta content="yes" name="apple-mobile-web-app-capable"> | ||
| 11 | + <meta content="black" name="apple-mobile-web-app-status-bar-style"> | ||
| 12 | + <meta content="telephone=no" name="format-detection"> | ||
| 13 | + <meta content="email=no" name="format-detection"> | ||
| 14 | + <script type="text/javascript" src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/flexible.js"></script> | ||
| 15 | + <!-- <link rel="stylesheet" href="/be-static/be-static-luban-h5/engine/engine.css"> --> | ||
| 16 | + <!-- <script src="/be-static/be-static-luban-h5/engine/engine.js"></script> --> | ||
| 17 | + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css"> | ||
| 18 | + <link rel="stylesheet" href="https://meyerweb.com/eric/tools/css/reset/reset.css"> | ||
| 19 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script> | ||
| 20 | + <style> | ||
| 21 | + .swiper-container { | ||
| 22 | + width: 100%; | ||
| 23 | + height: 100vh; | ||
| 24 | + } | ||
| 25 | + </style> | ||
| 26 | + <script> | ||
| 27 | + window.__work = {"id":12,"title":"default title","description":"default desc","cover_image_url":null,"is_publish":null,"create_time":"2019-07-21 06:07:44","update_time":"2019-07-21 06:07:44","pages":[{"elements":[{"name":"lbp-button","uuid":1563721976946,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[]},{"elements":[]},{"elements":[{"name":"lbp-button","uuid":1563721991112,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[{"name":"lbp-button","uuid":1563721995650,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]}],"created_at":"2019-07-21T06:07:44.636Z","updated_at":"2019-07-21T06:07:44.636Z"} | ||
| 28 | + </script> | ||
| 29 | + </head> | ||
| 30 | + <body> | ||
| 31 | + <noscript> | ||
| 32 | + <strong>We're sorry but luban-h5 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> | ||
| 33 | + </noscript> | ||
| 34 | + <div id="app"></div> | ||
| 35 | + <!-- built files will be auto injected --> | ||
| 36 | + <script> | ||
| 37 | + var mySwiper = new Swiper('.swiper-container', { | ||
| 38 | + // Optional parameters | ||
| 39 | + direction: 'vertical', | ||
| 40 | + loop: false, | ||
| 41 | + // If we need pagination | ||
| 42 | + pagination: { | ||
| 43 | + el: '.swiper-pagination', | ||
| 44 | + }, | ||
| 45 | + // Navigation arrows | ||
| 46 | + navigation: { | ||
| 47 | + nextEl: '.swiper-button-next', | ||
| 48 | + prevEl: '.swiper-button-prev', | ||
| 49 | + }, | ||
| 50 | + // And if we need scrollbar | ||
| 51 | + scrollbar: { | ||
| 52 | + el: '.swiper-scrollbar', | ||
| 53 | + }, | ||
| 54 | + }); | ||
| 55 | + </script> | ||
| 56 | + </body> | ||
| 57 | +</html> |
front-end/h5/public/engine.html
0 → 100644
| 1 | +<!DOCTYPE html> | ||
| 2 | +<html lang="en"> | ||
| 3 | + <head> | ||
| 4 | + <meta charset="utf-8"> | ||
| 5 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
| 6 | + <meta name="viewport" content="width=device-width,initial-scale=1.0"> | ||
| 7 | + <title>work.html</title> | ||
| 8 | + <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | ||
| 9 | + <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"> | ||
| 10 | + <meta content="yes" name="apple-mobile-web-app-capable"> | ||
| 11 | + <meta content="black" name="apple-mobile-web-app-status-bar-style"> | ||
| 12 | + <meta content="telephone=no" name="format-detection"> | ||
| 13 | + <meta content="email=no" name="format-detection"> | ||
| 14 | + <script type="text/javascript" src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/flexible.js"></script> | ||
| 15 | + <!-- <link rel="stylesheet" href="/be-static/be-static-luban-h5/engine/engine.css"> --> | ||
| 16 | + <!-- <script src="/be-static/be-static-luban-h5/engine/engine.js"></script> --> | ||
| 17 | + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css"> | ||
| 18 | + <link rel="stylesheet" href="https://meyerweb.com/eric/tools/css/reset/reset.css"> | ||
| 19 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script> | ||
| 20 | + <style> | ||
| 21 | + .swiper-container { | ||
| 22 | + width: 100%; | ||
| 23 | + height: 100vh; | ||
| 24 | + } | ||
| 25 | + </style> | ||
| 26 | + <!-- <script> | ||
| 27 | + window.__work = {"id":12,"title":"default title","description":"default desc","cover_image_url":null,"is_publish":null,"create_time":"2019-07-21 06:07:44","update_time":"2019-07-21 06:07:44","pages":[{"elements":[{"name":"lbp-button","uuid":1563721976946,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[]},{"elements":[]},{"elements":[{"name":"lbp-button","uuid":1563721991112,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]},{"elements":[{"name":"lbp-button","uuid":1563721995650,"pluginProps":{"text":"按钮","fontSize":14,"color":"black","backgroundColor":"#ffffff","borderColor":"#eeeeee","borderWidth":2,"borderRadius":0,"lineHeight":1,"textAlign":"center"},"commonStyle":{"top":208,"left":106,"width":100,"height":40,"zindex":1,"textAlign":"center","color":"#000000","backgroundColor":"#ffffff","fontSize":14},"events":[]}]}],"created_at":"2019-07-21T06:07:44.636Z","updated_at":"2019-07-21T06:07:44.636Z"} | ||
| 28 | + </script> --> | ||
| 29 | + </head> | ||
| 30 | + <body> | ||
| 31 | + <noscript> | ||
| 32 | + <strong>We're sorry but luban-h5 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> | ||
| 33 | + </noscript> | ||
| 34 | + <div id="app"></div> | ||
| 35 | + <!-- built files will be auto injected --> | ||
| 36 | + <script> | ||
| 37 | + var mySwiper = new Swiper('.swiper-container', { | ||
| 38 | + // Optional parameters | ||
| 39 | + direction: 'vertical', | ||
| 40 | + loop: false, | ||
| 41 | + // If we need pagination | ||
| 42 | + pagination: { | ||
| 43 | + el: '.swiper-pagination', | ||
| 44 | + }, | ||
| 45 | + // Navigation arrows | ||
| 46 | + navigation: { | ||
| 47 | + nextEl: '.swiper-button-next', | ||
| 48 | + prevEl: '.swiper-button-prev', | ||
| 49 | + }, | ||
| 50 | + // And if we need scrollbar | ||
| 51 | + scrollbar: { | ||
| 52 | + el: '.swiper-scrollbar', | ||
| 53 | + }, | ||
| 54 | + }); | ||
| 55 | + </script> | ||
| 56 | + </body> | ||
| 57 | +</html> |
front-end/h5/src/components/core/editor/engine/index.js
0 → 100644
| 1 | +/** | ||
| 2 | + * 作品预览的渲染引擎,其实就是简单遍历 pages 以及 elements,显示即可 | ||
| 3 | + */ | ||
| 4 | +import Vue from 'vue' | ||
| 5 | +import Antd from 'ant-design-vue' | ||
| 6 | +import 'ant-design-vue/dist/antd.css' | ||
| 7 | +import 'font-awesome/css/font-awesome.min.css' | ||
| 8 | +import loadPluginMixin from '../../../../mixins/load-plugins.js' | ||
| 9 | +import Element from '../../models/element' | ||
| 10 | + | ||
| 11 | +Vue.config.productionTip = false | ||
| 12 | +Vue.use(Antd) | ||
| 13 | +const Engine = { | ||
| 14 | + name: 'engine', | ||
| 15 | + mixins: [loadPluginMixin], | ||
| 16 | + methods: { | ||
| 17 | + renderPreview (h, _elements) { | ||
| 18 | + const elements = _elements.map(element => new Element(element)) | ||
| 19 | + return ( | ||
| 20 | + <div style={{ height: '100%', position: 'relative' }}> | ||
| 21 | + { | ||
| 22 | + elements.map((element, index) => { | ||
| 23 | + const style = element.getStyle({ position: 'absolute' }) | ||
| 24 | + const data = { | ||
| 25 | + style, | ||
| 26 | + props: element.getProps({ mode: 'preview' }) | ||
| 27 | + } | ||
| 28 | + return h(element.name, data) | ||
| 29 | + }) | ||
| 30 | + } | ||
| 31 | + </div> | ||
| 32 | + ) | ||
| 33 | + } | ||
| 34 | + }, | ||
| 35 | + render (h) { | ||
| 36 | + const work = window.__work | ||
| 37 | + return ( | ||
| 38 | + <div id="work-container" data-work-id={work.id}> | ||
| 39 | + <div class="swiper-container"> | ||
| 40 | + <div class="swiper-wrapper">{ | ||
| 41 | + work.pages.map(page => { | ||
| 42 | + return ( | ||
| 43 | + <section class="swiper-slide flat"> | ||
| 44 | + {/* this.walk(h, page.elements) */} | ||
| 45 | + { this.renderPreview(h, page.elements) } | ||
| 46 | + </section> | ||
| 47 | + ) | ||
| 48 | + }) | ||
| 49 | + }</div> | ||
| 50 | + <div class="swiper-pagination"></div> | ||
| 51 | + </div> | ||
| 52 | + </div> | ||
| 53 | + ) | ||
| 54 | + } | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +new Vue({ | ||
| 58 | + components: { | ||
| 59 | + engine: Engine | ||
| 60 | + }, | ||
| 61 | + render: h => h('engine') | ||
| 62 | +}).$mount('#app') |
front-end/h5/vue.config.js
| @@ -5,5 +5,16 @@ module.exports = { | @@ -5,5 +5,16 @@ module.exports = { | ||
| 5 | : '/', | 5 | : '/', |
| 6 | devServer: { | 6 | devServer: { |
| 7 | proxy: 'http://localhost:1337' | 7 | proxy: 'http://localhost:1337' |
| 8 | + }, | ||
| 9 | + pages: { | ||
| 10 | + index: { | ||
| 11 | + entry: 'src/main.js', | ||
| 12 | + template: 'public/index.html', | ||
| 13 | + filename: 'index.html', | ||
| 14 | + title: 'Index Page' | ||
| 15 | + }, | ||
| 16 | + engine: { | ||
| 17 | + entry: 'src/components/core/editor/engine/index.js' | ||
| 18 | + } | ||
| 8 | } | 19 | } |
| 9 | } | 20 | } |