├── LICENSE ├── README.MD └── examples ├── angular ├── README.md ├── assets │ ├── app.css │ └── formJson.js └── hello.html └── vue ├── .gitignore ├── README.md ├── babel.config.js ├── ccc.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── nuc.png │ └── power-off.svg ├── blinker.js ├── components │ └── BlinkerDevice.vue └── main.js └── vue.config.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 i3water 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # blinker-Customizer 2 | blinker提供了两套自定义设备界面的方案: 3 | blinker-Layouter和blinker-Customizer 4 | 5 | blinker-Customizer使用iframe方式嵌入自定义的HTML页面到blinker app中。 6 | -------------------------------------------------------------------------------- /examples/angular/README.md: -------------------------------------------------------------------------------- 1 | ## Project setup 2 | ``` 3 | npm install 4 | ``` 5 | 6 | ### Compiles and hot-reloads for development 7 | ``` 8 | ng serve 9 | ``` 10 | 11 | ### Compiles and minifies for production 12 | ``` 13 | ng build --prod 14 | ``` -------------------------------------------------------------------------------- /examples/angular/assets/app.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100vh; 3 | position: relative; 4 | } 5 | body { 6 | margin: 0; 7 | } 8 | 9 | .main-box { 10 | position: absolute; 11 | top: 0; 12 | background: radial-gradient(circle, #61b4fa, #389bee, #0076d9); 13 | height: 100vh; 14 | width: 100vw; 15 | } 16 | 17 | .bottom-btn-box { 18 | position: absolute; 19 | bottom: 30px; 20 | left: 0; 21 | width: 100%; 22 | height: 60px; 23 | display: flex; 24 | justify-content: center; 25 | align-items: center; 26 | } 27 | 28 | button { 29 | margin: 15px; 30 | width: 60px; 31 | height: 60px; 32 | background: rgba(255, 255, 255, 0.6); 33 | border: none; 34 | border-radius: 50%; 35 | outline: medium; 36 | } 37 | 38 | .text { 39 | background: rgba(255, 255, 255, 0.3); 40 | border: 1px solid #ccc; 41 | border-radius: 8px; 42 | margin: 15px; 43 | padding: 15px; 44 | width: calc(100% - 60px); 45 | } 46 | -------------------------------------------------------------------------------- /examples/angular/assets/formJson.js: -------------------------------------------------------------------------------- 1 | // https://github.com/zhdonghd/jsonFormat 2 | 3 | var generateRes = function(str) { 4 | try { 5 | var json = JSON.parse(str); 6 | if(typeof(json) == "object") 7 | return formatRes(null, json, 0, false, true); 8 | else 9 | return str; 10 | } catch (err) { 11 | return str; 12 | } 13 | } 14 | 15 | var formatRes = function(key, obj, depth, isArray, isEnd) { 16 | var margin = 20; 17 | var els = "", 18 | mlValue = margin * (depth + 1); 19 | 20 | var jsonType = Object.prototype.toString.call(obj); 21 | //区分数组和json对象 22 | if("[object Array]" == jsonType) { //解析数组 23 | els += "

" + (key ? (key + ":") : "") + " [

"; 24 | $.each(obj, function(index, element) { 25 | var type = Object.prototype.toString.call(element), 26 | isLast = index == (obj.length - 1), 27 | value = element; 28 | type = type.match(/\[object (\S*)\]/)[1]; 29 | //基本数据类型 30 | if("Boolean" == type || "Number" == type || "Null" == type) 31 | els += "

" + jsonkey + ": " + value 32 | + "" + (isLast ? "" : ",") + "

"; 33 | else if("String" == type) { 34 | value = value.replace(new RegExp(//g),'\\u003e') 35 | els += "

" + jsonkey + ": \"" + value 36 | + "\"" + (isLast ? "" : ",") + "

"; 37 | } else 38 | els += formatRes(null, element, depth + 1, true, isLast); 39 | }); 40 | 41 | els += "

]" + (isEnd ? "" : ",") + "

"; 42 | } else { //解析json 43 | els += "

" + (key ? (key + ":") : "") + " {

"; 44 | var length = 0; 45 | for(var jsonkey in obj) { 46 | length++; 47 | } 48 | var index = 0; 49 | for(var jsonkey in obj) { 50 | index++; 51 | var value = obj[jsonkey], 52 | isLast = index == length; 53 | var type = Object.prototype.toString.call(value), 54 | el; 55 | type = type.match(/\[object (\S*)\]/)[1]; 56 | //基本数据类型 57 | if("Boolean" == type || "Number" == type || "Null" == type) 58 | el= "

" + jsonkey + ": " + value + "" + (isLast ? "": ",") + "

"; 59 | else if("String" == type) { 60 | value = value.replace(new RegExp(//g),'\\u003e') 61 | el= "

" + jsonkey + ": \"" + value + "\"" + (isLast ? "": ",") + "

"; 62 | } else if("Array" == type) 63 | el = formatRes(jsonkey, value, depth + 1, true, isLast); 64 | else 65 | el = formatRes(jsonkey, value, depth + 1, false, isLast); 66 | 67 | els += el; 68 | } 69 | els += "

}" + (isArray && !isEnd ? ",": "") + "

"; 70 | } 71 | return els; 72 | } -------------------------------------------------------------------------------- /examples/angular/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | blinker Customizer 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 18 |
19 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/vue/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /examples/vue/README.md: -------------------------------------------------------------------------------- 1 | # vue-test 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /examples/vue/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /examples/vue/ccc.js: -------------------------------------------------------------------------------- 1 | 2 | window.addEventListener("message", receiveMessage, false); 3 | Vue.prototype.appData = {} 4 | Vue.prototype.BlinkerHeaderHeight = '0px' 5 | Vue.prototype.send2Device = function (data) { 6 | window.parent.postMessage(data, "*"); 7 | } 8 | window.parent.postMessage({}, "*"); 9 | 10 | function receiveMessage(e) { 11 | // console.log(JSON.stringify(e.data)); 12 | if (e.data == 'undefined' || e.data == null || JSON.stringify(e.data).indexOf('{}') > -1 || JSON.stringify(e.data).indexOf('webpack') > -1) return 13 | if (typeof e.data.headerHeight != "undefined") { 14 | Vue.BlinkerHeaderHeight = e.data.headerHeight + "px"; 15 | console.log(Vue.BlinkerHeaderHeight); 16 | } else { 17 | console.log(e.data); 18 | Object.assign(Vue.appData, e.data); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-test", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^3.6.5", 12 | "node-sass": "^4.14.1", 13 | "svg-gauge": "^1.0.6", 14 | "vue": "^2.6.11" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "~4.4.0", 18 | "@vue/cli-plugin-eslint": "~4.4.0", 19 | "@vue/cli-service": "~4.4.0", 20 | "babel-eslint": "^10.1.0", 21 | "eslint": "^6.7.2", 22 | "eslint-plugin-vue": "^6.2.2", 23 | "sass-loader": "^8.0.2", 24 | "vue-template-compiler": "^2.6.11" 25 | }, 26 | "eslintConfig": { 27 | "root": true, 28 | "env": { 29 | "node": true 30 | }, 31 | "extends": [ 32 | "plugin:vue/essential", 33 | "eslint:recommended" 34 | ], 35 | "parserOptions": { 36 | "parser": "babel-eslint" 37 | }, 38 | "rules": { 39 | "no-unused-vars": [ 40 | 0, 41 | {} 42 | ] 43 | } 44 | }, 45 | "browserslist": [ 46 | "> 1%", 47 | "last 2 versions", 48 | "not dead" 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /examples/vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinker-iot/blinker-customizer/8aeba4d873da11c2da7f54132eb82055fea2687d/examples/vue/public/favicon.ico -------------------------------------------------------------------------------- /examples/vue/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 32 | 33 | 42 | -------------------------------------------------------------------------------- /examples/vue/src/assets/nuc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinker-iot/blinker-customizer/8aeba4d873da11c2da7f54132eb82055fea2687d/examples/vue/src/assets/nuc.png -------------------------------------------------------------------------------- /examples/vue/src/assets/power-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue/src/blinker.js: -------------------------------------------------------------------------------- 1 | export let blinker = function () { }; 2 | 3 | blinker.prototype.headerHeight = '0'; 4 | blinker.prototype.appData = {}; 5 | 6 | export function send2Device(data) { 7 | // console.log(data); 8 | window.parent.postMessage(data, "*"); 9 | } 10 | 11 | window.addEventListener("message", receiveMessage, false); 12 | window.parent.postMessage({}, "*"); 13 | function receiveMessage(e) { 14 | // console.log(JSON.stringify(e.data)); 15 | if (e.data == 'undefined' || e.data == null || JSON.stringify(e.data).indexOf('{}') > -1 || JSON.stringify(e.data).indexOf('webpack') > -1) return 16 | if (typeof e.data.headerHeight != "undefined") { 17 | blinker.headerHeight = e.data.headerHeight; 18 | } else { 19 | Object.assign(blinker.appData, e.data); 20 | } 21 | } -------------------------------------------------------------------------------- /examples/vue/src/components/BlinkerDevice.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /examples/vue/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App), 8 | }).$mount('#app') -------------------------------------------------------------------------------- /examples/vue/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | lintOnSave: false, 3 | devServer: { 4 | hot: true, 5 | liveReload: true 6 | }, 7 | css: { 8 | // 是否使用css分离插件 ExtractTextPlugin 9 | extract: ['production', 'test'].includes(process.env.NODE_ENV), 10 | // 开启 CSS source maps? 11 | sourceMap: false, 12 | // css预设器配置项 13 | loaderOptions: { 14 | }, 15 | // 启用 CSS modules for all css / pre-processor files. 16 | modules: false, 17 | }, 18 | } --------------------------------------------------------------------------------