├── weex ├── platforms │ ├── android │ │ ├── .weex_plugin.json │ │ ├── settings.gradle │ │ ├── app │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── drawables.xml │ │ │ │ │ │ ├── dimens.xml │ │ │ │ │ │ ├── colors.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ ├── attrs.xml │ │ │ │ │ │ ├── themes.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable-hdpi │ │ │ │ │ │ ├── ic_action_scan.png │ │ │ │ │ │ └── ic_action_refresh.png │ │ │ │ │ ├── drawable-mdpi │ │ │ │ │ │ ├── ic_action_scan.png │ │ │ │ │ │ └── ic_action_refresh.png │ │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ │ ├── ic_action_scan.png │ │ │ │ │ │ └── ic_action_refresh.png │ │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ │ ├── ic_action_scan.png │ │ │ │ │ │ └── ic_action_refresh.png │ │ │ │ │ ├── values-w820dp │ │ │ │ │ │ └── dimens.xml │ │ │ │ │ ├── values-v21 │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── menu │ │ │ │ │ │ ├── main.xml │ │ │ │ │ │ └── main_scan.xml │ │ │ │ │ ├── xml │ │ │ │ │ │ └── app_config.xml │ │ │ │ │ ├── layout │ │ │ │ │ │ ├── activity_splash.xml │ │ │ │ │ │ └── activity_wxpage.xml │ │ │ │ │ └── values-zh-rCN │ │ │ │ │ │ └── strings.xml │ │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── weex │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── util │ │ │ │ │ │ ├── Constants.java │ │ │ │ │ │ ├── AppConfig.java │ │ │ │ │ │ ├── AppConfigXmlParser.java │ │ │ │ │ │ └── AppPreferences.java │ │ │ │ │ │ ├── WXApplication.java │ │ │ │ │ │ ├── extend │ │ │ │ │ │ ├── WXEventModule.java │ │ │ │ │ │ ├── BlurTransformation.java │ │ │ │ │ │ ├── ImageAdapter.java │ │ │ │ │ │ └── BlurTool.java │ │ │ │ │ │ ├── SplashActivity.java │ │ │ │ │ │ ├── hotreload │ │ │ │ │ │ └── HotReloadManager.java │ │ │ │ │ │ └── WXPageActivity.java │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ └── assets │ │ │ │ │ └── index.js │ │ │ ├── tools │ │ │ │ └── debug.keystore │ │ │ ├── .gitignore │ │ │ ├── proguard-rules.pro │ │ │ └── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── .idea │ │ │ ├── caches │ │ │ │ └── build_file_checksums.ser │ │ │ ├── misc.xml │ │ │ ├── modules.xml │ │ │ ├── runConfigurations.xml │ │ │ └── codeStyles │ │ │ │ └── Project.xml │ │ ├── README.md │ │ ├── NOTICE │ │ ├── gradle.properties │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── gradlew.bat │ │ ├── gradlew │ │ └── LICENSE │ └── platforms.json ├── .eslintignore ├── plugins │ └── plugins.json ├── configs │ ├── logo.png │ ├── helper.js │ ├── vue-loader.conf.js │ ├── plugin.js │ ├── hotreload.js │ ├── utils.js │ ├── config.js │ ├── webpack.prod.conf.js │ ├── webpack.dev.conf.js │ ├── webpack.release.conf.js │ └── webpack.common.conf.js ├── src │ ├── components │ │ ├── HelloWorld.vue │ │ └── game.vue │ ├── entry.js │ ├── router.js │ └── index.vue ├── android.config.json ├── ios.config.json ├── .postcssrc.js ├── .babelrc ├── .temp │ ├── entry.js │ └── router.js ├── README.md ├── webpack.config.js ├── .eslintrc.js ├── web │ ├── index.html │ ├── assets │ │ └── preview.css │ └── preview.html └── package.json ├── vue ├── .browserslistrc ├── img │ ├── 2.jpg │ ├── 3.gif │ ├── 4.gif │ ├── 5.gif │ ├── 20190325.gif │ ├── 20190327.gif │ └── 20190328.gif ├── babel.config.js ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── assets │ │ └── logo.png │ ├── main.js │ ├── App.vue │ └── components │ │ ├── HelloWorld.vue │ │ └── auto.vue ├── .editorconfig ├── .gitignore ├── .eslintrc.js ├── package.json ├── puzzle2.md └── puzzle1.md ├── README.md └── LICENSE /weex/platforms/android/.weex_plugin.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /weex/.eslintignore: -------------------------------------------------------------------------------- 1 | /configs/ 2 | /dist/ 3 | /*.js 4 | -------------------------------------------------------------------------------- /weex/platforms/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /vue/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /vue/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/2.jpg -------------------------------------------------------------------------------- /vue/img/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/3.gif -------------------------------------------------------------------------------- /vue/img/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/4.gif -------------------------------------------------------------------------------- /vue/img/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/5.gif -------------------------------------------------------------------------------- /weex/platforms/platforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "ios": "1.0.0", 3 | "android": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /weex/plugins/plugins.json: -------------------------------------------------------------------------------- 1 | { 2 | "ios": [], 3 | "web": [], 4 | "android": [] 5 | } -------------------------------------------------------------------------------- /vue/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vue/img/20190325.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/20190325.gif -------------------------------------------------------------------------------- /vue/img/20190327.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/20190327.gif -------------------------------------------------------------------------------- /vue/img/20190328.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/img/20190328.gif -------------------------------------------------------------------------------- /vue/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/public/favicon.ico -------------------------------------------------------------------------------- /vue/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/vue/src/assets/logo.png -------------------------------------------------------------------------------- /weex/configs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/configs/logo.png -------------------------------------------------------------------------------- /weex/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 2 | Now, let's goooooooooooooooooooooooo. 3 | 4 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values/drawables.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /vue/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /weex/android.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "AppName":"WeexApp", 3 | "AppId":"com.weex.app", 4 | "SplashText":"Hello\nWeex", 5 | "WeexBundle":"index.js" 6 | } 7 | -------------------------------------------------------------------------------- /weex/platforms/android/app/tools/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/tools/debug.keystore -------------------------------------------------------------------------------- /weex/platforms/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /weex/platforms/android/.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-hdpi/ic_action_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-hdpi/ic_action_scan.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-mdpi/ic_action_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-mdpi/ic_action_scan.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-xhdpi/ic_action_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-xhdpi/ic_action_scan.png -------------------------------------------------------------------------------- /weex/platforms/android/README.md: -------------------------------------------------------------------------------- 1 | ### weex apps samples 2 | 3 | *Please install the weex-toolkit before use hotrefresh* 4 | 5 | [Development Tools link](https://github.com/alibaba/weex_toolchain) -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-hdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-hdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-mdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-mdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-xxhdpi/ic_action_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-xxhdpi/ic_action_scan.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-xhdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-xhdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usecodelee/Vue-auto-Puzzle/HEAD/weex/platforms/android/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /weex/ios.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "AppName":"WeexApp", 3 | "Version":"0.1", 4 | "BuildVersion":"0.1.0", 5 | "AppId":"com.alibaba.weex", 6 | "CodeSign":"", 7 | "Profile":"", 8 | "WeexBundle":"index.js" 9 | } 10 | -------------------------------------------------------------------------------- /vue/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import _ from 'lodash' 4 | 5 | Vue.config.productionTip = false 6 | Vue.prototype._ = _ 7 | 8 | new Vue({ 9 | render: h => h(App) 10 | }).$mount('#app') -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /weex/platforms/android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /weex/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "postcss-import": {}, 7 | "autoprefixer": {} 8 | } 9 | } -------------------------------------------------------------------------------- /weex/src/entry.js: -------------------------------------------------------------------------------- 1 | /* global Vue */ 2 | 3 | /* weex initialized here, please do not move this line */ 4 | const { router } = require('./router') 5 | const App = require('@/index.vue') 6 | /* eslint-disable no-new */ 7 | new Vue(Vue.util.extend({el: '#root', router}, App)) 8 | router.push('/') 9 | -------------------------------------------------------------------------------- /weex/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0"], 3 | "plugins": [ 4 | [ 5 | "component", 6 | { 7 | "libraryName": "weex-ui", 8 | "libDir": "packages", 9 | "style": false 10 | } 11 | ] 12 | ] 13 | } -------------------------------------------------------------------------------- /weex/platforms/android/NOTICE: -------------------------------------------------------------------------------- 1 | Weex android playground 2 | Copyright 2016 Alibaba Group 3 | 4 | This product includes software developed at Alibaba Group. (http://www.alibabagroup.com) 5 | 6 | This product contains software zxing(https://github.com/zxing/zxing) developed 7 | by Google Inc. , licensed under the Apache License. -------------------------------------------------------------------------------- /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 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3eb4ff 4 | #3eb4ff 5 | #FF4081 6 | 7 | #66000000 8 | 9 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /weex/.temp/entry.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import weex from 'weex-vue-render' 3 | /* global Vue */ 4 | 5 | weex.init(Vue) 6 | /* weex initialized here, please do not move this line */ 7 | const { router } = require('./router') 8 | const App = require('@/index.vue') 9 | /* eslint-disable no-new */ 10 | new Vue(Vue.util.extend({el: '#root', router}, App)) 11 | router.push('/') 12 | -------------------------------------------------------------------------------- /weex/platforms/android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | > 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /weex/configs/helper.js: -------------------------------------------------------------------------------- 1 | // Helper functions 2 | const path = require('path'); 3 | const ROOT = path.resolve(__dirname, '..'); 4 | 5 | const root = (args) => { 6 | return path.join(ROOT, 'src', args); 7 | } 8 | const rootNode = (args) => { 9 | return path.join(ROOT, args); 10 | } 11 | 12 | const resolve = (dir) => { 13 | return path.join(__dirname, '..', dir) 14 | } 15 | 16 | module.exports = { 17 | root, 18 | rootNode, 19 | resolve 20 | } -------------------------------------------------------------------------------- /weex/platforms/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Dec 15 12:24:19 CST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | #distributionUrl=http://gw.alicdn.com/bao/uploaded/LB1J5WLJVXXXXcMXpXXXXXXXXXX.zip 8 | #distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip 9 | #distributionUrl=gradle-2.10-bin.zip -------------------------------------------------------------------------------- /weex/src/router.js: -------------------------------------------------------------------------------- 1 | /* global Vue */ 2 | import Router from 'vue-router' 3 | import HelloWorld from '@/components/HelloWorld' 4 | import Game from '@/components/game' 5 | 6 | Vue.use(Router) 7 | 8 | export const router = new Router({ 9 | routes: [{ 10 | path: '/', 11 | name: 'HelloWorld', 12 | component: HelloWorld 13 | }, 14 | { 15 | path: '/game', 16 | name: 'game', 17 | component: Game 18 | } 19 | ] 20 | }) -------------------------------------------------------------------------------- /weex/.temp/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | /* global Vue */ 3 | import Router from 'vue-router' 4 | import HelloWorld from '@/components/HelloWorld' 5 | import Game from '@/components/game' 6 | 7 | Vue.use(Router) 8 | 9 | export const router = new Router({ 10 | routes: [{ 11 | path: '/', 12 | name: 'HelloWorld', 13 | component: HelloWorld 14 | }, 15 | { 16 | path: '/game', 17 | name: 'game', 18 | component: Game 19 | } 20 | ] 21 | }) -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/xml/app_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | Hello 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/menu/main_scan.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /vue/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | mypuzzle 9 | 10 | 11 | 12 | We're sorry but mypuzzle doesn't work properly without JavaScript enabled. Please enable it to continue. 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /weex/platforms/android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 19 | 20 | 30 | -------------------------------------------------------------------------------- /vue/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: false, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 13 | "semi": [2, "always"], 14 | "space-before-function-paren": [0, "always"], //函数定义时括号前面要不要有空格 15 | "no-undef": 1, //不能有未定义的变量 16 | "yoda": [0], //禁止尤达条件 17 | "indent": 0, //缩进风格 18 | }, 19 | parserOptions: { 20 | parser: 'babel-eslint' 21 | } 22 | } -------------------------------------------------------------------------------- /vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mypuzzle", 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 | "lodash": "^4.17.11", 12 | "vue": "^2.6.6" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "@vue/eslint-config-standard": "^4.0.0", 19 | "babel-eslint": "^10.0.1", 20 | "eslint": "^5.8.0", 21 | "eslint-plugin-vue": "^5.0.0", 22 | "vue-template-compiler": "^2.5.21" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /weex/configs/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | const utils = require('./utils') 2 | const config = require('./config') 3 | const isProduction = process.env.NODE_ENV === 'production' 4 | const sourceMapEnabled = isProduction 5 | ? config.prod.productionSourceMap 6 | : config.dev.cssSourceMap 7 | 8 | module.exports = (options) => { 9 | return { 10 | loaders: utils.cssLoaders({ 11 | // sourceMap: use sourcemao or not. 12 | sourceMap: options && sourceMapEnabled, 13 | // useVue: use vue-style-loader or not 14 | useVue: options && options.useVue, 15 | // usePostCSS: use postcss to compile styles. 16 | usePostCSS: options && options.usePostCSS 17 | }), 18 | cssSourceMap: sourceMapEnabled, 19 | cacheBusting: config.dev.cacheBusting 20 | } 21 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue-auto-Puzzle 2 | 3 | [](https://github.com/usecodelee/Vue-auto-Puzzle) 4 | [](https://github.com/usecodelee/Vue-auto-Puzzle/fork)  5 | 6 | Jigsaw puzzle based on Vue 7 | 基于Vue的拼图小游戏 8 | 9 | 带有打乱时很炫酷的动画 10 |  11 | 12 | ## 增加自动拼图的功能 13 | 14 | ## 增加自动重新打乱开始的功能 15 | 16 | ## 增加Weex(Android & iOS) 17 | 18 | ## 使用: 19 | 20 | 1. npm install 21 | 22 | 2. npm run serve 23 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | WEEX APP 4 | WEEX\nPLAYGROUND 5 | Please put the barcode in the framing frame to scan 6 | Sorry, your current device is x86 architecture.\n We only 7 | support arm architecture devices! 8 | 9 | Network Error!\n1.Make sure you use the command "npm run serve" 10 | launched local service\n2.Make sure you modify "your_current_ip" to your local IP in 11 | "WXMainActivity" 12 | 13 | Scan 14 | Refresh 15 | 16 | -------------------------------------------------------------------------------- /weex/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This boilerplate is targeted towards large, serious projects and assumes you are somewhat familiar with Webpack and `weex-loader`. 4 | 5 | ## Quickstart 6 | 7 | To use this template, scaffold a project with [weexpack v1.1.1+](https://github.com/weexteam/weex-pack). 8 | 9 | ``` bash 10 | $ npm install -g weex-toolkit 11 | $ weex create my-project # default will create the webpack template 12 | $ cd my-project && npm start 13 | ``` 14 | 15 | ## How to use less/sass/pug 16 | 17 | Take `sass` for example: 18 | 19 | ``` 20 | $ npm i node-sass sass-loader --save 21 | ``` 22 | 23 | Then, you just need to change the `style` tag as: ` 24 | 25 | -------------------------------------------------------------------------------- /weex/platforms/android/app/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Android template 3 | # Built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | 18 | # Gradle files 19 | .gradle/ 20 | build/ 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | # Proguard folder generated by Eclipse 26 | proguard/ 27 | 28 | # Log Files 29 | *.log 30 | 31 | # Android Studio Navigation editor temp files 32 | .navigation/ 33 | 34 | # Android Studio captures folder 35 | captures/ 36 | 37 | # Intellij 38 | *.iml 39 | .idea/workspace.xml 40 | .idea/tasks.xml 41 | .idea/gradle.xml 42 | .idea/dictionaries 43 | .idea/libraries 44 | 45 | # Keystore files 46 | *.jks 47 | 48 | # External native build folder generated in Android Studio 2.2 and later 49 | .externalNativeBuild 50 | 51 | # Google Services (e.g. APIs or Firebase) 52 | google-services.json 53 | 54 | # Freeline 55 | freeline.py 56 | freeline/ 57 | freeline_project_description.json 58 | 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 leechaojiang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /weex/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // https://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parserOptions: { 6 | parser: 'babel-eslint' 7 | }, 8 | env: { 9 | browser: true 10 | }, 11 | globals: { 12 | weex: true 13 | }, 14 | extends: [ 15 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 16 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 17 | 'plugin:vue/essential', 18 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md 19 | 'standard' 20 | ], 21 | // required to lint *.vue files 22 | plugins: [ 23 | 'vue' 24 | ], 25 | // add your custom rules here 26 | rules: { 27 | 'vue/no-parsing-error': [2, { 28 | "x-invalid-end-tag": false 29 | }], 30 | // allow async-await 31 | 'generator-star-spacing': 'off', 32 | // allow debugger during development 33 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 34 | } 35 | } -------------------------------------------------------------------------------- /weex/platforms/android/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Android template 3 | # Built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | 18 | # Gradle files 19 | .gradle/ 20 | build/ 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | # Proguard folder generated by Eclipse 26 | proguard/ 27 | 28 | # Log Files 29 | *.log 30 | 31 | # Android Studio Navigation editor temp files 32 | .navigation/ 33 | 34 | # Android Studio captures folder 35 | captures/ 36 | 37 | # Intellij 38 | *.iml 39 | .idea/workspace.xml 40 | .idea/tasks.xml 41 | .idea/gradle.xml 42 | .idea/dictionaries 43 | .idea/libraries 44 | 45 | # Keystore files 46 | *.jks 47 | 48 | # External native build folder generated in Android Studio 2.2 and later 49 | .externalNativeBuild 50 | 51 | # Google Services (e.g. APIs or Firebase) 52 | google-services.json 53 | 54 | # Freeline 55 | freeline.py 56 | freeline/ 57 | freeline_project_description.json 58 | 59 | .classpath 60 | .project 61 | .settings/ 62 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | WEEX APP 19 | WEEX\nPLAYGROUND 20 | 请将条码置于取景框内扫描 21 | 对不起,您当前的设备是X86架构.\n我们只支持ARM架构的设备! 22 | 网络错误! 23 | 扫码 24 | 刷新 25 | 26 | -------------------------------------------------------------------------------- /weex/platforms/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | mavenLocal() 6 | jcenter() 7 | mavenCentral() 8 | maven { 9 | url 'https://maven.google.com/' 10 | name 'Google' 11 | } 12 | } 13 | dependencies { 14 | classpath 'com.android.tools.build:gradle:2.2.2' 15 | classpath 'com.taobao.android:weexplugin-gradle-plugin:1.3' 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | mavenLocal() 22 | jcenter() 23 | mavenCentral() 24 | maven { 25 | url 'https://maven.google.com/' 26 | name 'Google' 27 | } 28 | } 29 | } 30 | 31 | task clean(type: Delete) { 32 | delete rootProject.buildDir 33 | } 34 | 35 | subprojects { 36 | ext { 37 | compileSdkVersion=26 38 | buildToolsVersion="26.0.0" 39 | minSdkVersion=14 40 | appMinSdkVersion=15 41 | targetSdkVersion=26 42 | supportLibVersion="26.1.0" 43 | fastjsonLibVersion="1.1.46.android" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /weex/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Index 6 | 7 | 8 | 9 | 10 | 11 | 34 | 35 | 36 | 37 | 38 | <%= htmlWebpackPlugin.options.devScripts %> 39 | 40 | -------------------------------------------------------------------------------- /weex/configs/plugin.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | const webpack = require('webpack'); 4 | const config = require('./config'); 5 | const helper = require('./helper'); 6 | const pluginConfigPath = helper.rootNode(config.pluginConfigPath); 7 | const outputPath = helper.rootNode(config.pluginFilePath); 8 | 9 | const toLowerCamelCase = key => { 10 | return key.replace(/\b\-\w+\b/g, function(word){ 11 | return word.substring(1,2).toUpperCase()+word.substring(2); 12 | }); 13 | } 14 | 15 | const buildPlugins = () => { 16 | let content = ''; 17 | let keys = []; 18 | const plugins =require(pluginConfigPath).web; 19 | if (plugins && plugins.length > 0) { 20 | for(let plugin of plugins){ 21 | let camelCaseKey = toLowerCamelCase(plugin.name); 22 | content += `import ${camelCaseKey} from '${plugin.name}';\n` 23 | keys.push(camelCaseKey) 24 | } 25 | content += `export default [${keys.join(',')}];` 26 | fs.outputFileSync(outputPath, content); 27 | return true; 28 | } 29 | else { 30 | if (fs.existsSync(outputPath)) { 31 | fs.unlink(outputPath) 32 | } 33 | return false; 34 | } 35 | } 36 | 37 | module.exports = buildPlugins; 38 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /weex/platforms/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/lixinke/Tool/android-eclipse/adt-bundle-mac-x86_64-20140702/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | ##weex 19 | -keep class com.taobao.weex.bridge.**{*;} 20 | -keep class com.taobao.weex.dom.**{*;} 21 | -keep class com.taobao.weex.adapter.**{*;} 22 | -keep class com.taobao.weex.common.**{*;} 23 | -keep class * implements com.taobao.weex.IWXObject{*;} 24 | -keep class com.taobao.weex.ui.**{*;} 25 | -keep class com.taobao.weex.ui.component.**{*;} 26 | -keep class com.taobao.weex.utils.**{ 27 | public ; 28 | public ; 29 | } 30 | -keep class com.taobao.weex.view.**{*;} 31 | -keep class com.taobao.weex.module.**{*;} 32 | -keep public class * extends com.taobao.weex.common.WXModule{*;} 33 | -keep public class com.taobao.weex.WXDebugTool{*;} -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/res/layout/activity_wxpage.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | 15 | 20 | 21 | 22 | 23 | 29 | 30 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/extend/BlurTransformation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.weex.app.extend; 20 | 21 | import android.graphics.Bitmap; 22 | 23 | import com.squareup.picasso.Transformation; 24 | 25 | public class BlurTransformation implements Transformation { 26 | 27 | private int mRadius; 28 | 29 | public BlurTransformation(int radius) { 30 | mRadius = radius; 31 | } 32 | 33 | @Override public Bitmap transform(Bitmap source) { 34 | if(mRadius <= 0) { 35 | return source; 36 | } 37 | Bitmap bitmap; 38 | try { 39 | bitmap = BlurTool.blur(source, mRadius); 40 | }catch (Exception e){ 41 | bitmap = source; 42 | } 43 | if(bitmap != source) { 44 | source.recycle(); 45 | } 46 | return bitmap; 47 | } 48 | 49 | @Override public String key() { 50 | return "BlurTransformation(radius=" + mRadius + ")"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /weex/configs/hotreload.js: -------------------------------------------------------------------------------- 1 | const WebSocket = require('ws'); 2 | const clients = []; 3 | 4 | class WsServer { 5 | constructor(wsport) { 6 | this.clients = [] 7 | this.startWebSocket(wsport) 8 | } 9 | 10 | startWebSocket(wsport) { 11 | let wss = new WebSocket.Server({ 12 | port: wsport 13 | }); 14 | 15 | wss.on('connection', (ws) => { 16 | this.clients.push(ws); 17 | ws.on('message', (message) => { 18 | this.clients.forEach((client) => { 19 | if (client.readyState === WebSocket.OPEN) { 20 | client.send('websocket connected', (err) => { 21 | if (err) { 22 | console.error(err); 23 | } 24 | }); 25 | } 26 | }); 27 | }); 28 | // websocket close handle 29 | ws.on('close', () => { 30 | ws.close(); 31 | ws._socket.destroy(); 32 | this.clients.splice(this.findClient(ws.upgradeReq.url)); 33 | }); 34 | ws.on('error', (error) => { 35 | if (error) { 36 | ws.close(); 37 | ws._socket.destroy(); 38 | this.clients.splice(this.findClient(ws.upgradeReq.url), 1); 39 | } 40 | }); 41 | }); 42 | 43 | this.wss = wss; 44 | return wss; 45 | } 46 | 47 | // send web socket messsage to client 48 | sendSocketMessage(message) { 49 | this.clients.forEach((client) => { 50 | if (client.readyState === WebSocket.OPEN) { 51 | client.send(message || 'refresh', (err) => { 52 | if (err) { 53 | console.error(err); 54 | } 55 | }); 56 | } 57 | }); 58 | } 59 | 60 | findClient(url) { 61 | for (let i = 0; i < this.clients.length; i++) { 62 | if (this.clients[i].upgradeReq.url === url) { 63 | return i; 64 | } 65 | } 66 | return null; 67 | } 68 | } 69 | 70 | module.exports = WsServer -------------------------------------------------------------------------------- /weex/platforms/android/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.weex.app; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.view.animation.Animation; 9 | import android.view.animation.AnimationSet; 10 | import android.view.animation.RotateAnimation; 11 | import android.view.animation.ScaleAnimation; 12 | 13 | 14 | public class SplashActivity extends AppCompatActivity { 15 | 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_splash); 21 | 22 | View textView = findViewById(R.id.fullscreen_content); 23 | ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 24 | RotateAnimation rotateAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 25 | 26 | AnimationSet animationSet = new AnimationSet(false); 27 | animationSet.addAnimation(scaleAnimation); 28 | animationSet.addAnimation(rotateAnimation); 29 | animationSet.setDuration(1500); 30 | 31 | animationSet.setAnimationListener(new Animation.AnimationListener() { 32 | @Override 33 | public void onAnimationStart(Animation animation) { 34 | } 35 | 36 | @Override 37 | public void onAnimationEnd(Animation animation) { 38 | Intent intent = new Intent(SplashActivity.this, WXPageActivity.class); 39 | Uri data = getIntent().getData(); 40 | if (data != null) { 41 | intent.setData(data); 42 | } 43 | intent.putExtra("from", "splash"); 44 | startActivity(intent); 45 | finish(); 46 | } 47 | 48 | @Override 49 | public void onAnimationRepeat(Animation animation) { 50 | } 51 | }); 52 | textView.startAnimation(animationSet); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/assets/index.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ([ 44 | /* 0 */ 45 | /***/ function(module, exports) { 46 | 47 | ;__weex_define__("@weex-component/0f3c9ae76450de3e67cfabcbf5621bf7", [], function(__weex_require__, __weex_exports__, __weex_module__){ 48 | 49 | ;__weex_module__.exports.template = __weex_module__.exports.template || {} 50 | ;Object.assign(__weex_module__.exports.template, { 51 | "type": "div", 52 | "children": [ 53 | { 54 | "type": "text", 55 | "style": { 56 | "fontSize": 100 57 | }, 58 | "attr": { 59 | "value": "Hello World." 60 | } 61 | } 62 | ] 63 | }) 64 | }) 65 | ;__weex_bootstrap__("@weex-component/0f3c9ae76450de3e67cfabcbf5621bf7", { 66 | "transformerVersion": "0.3.1" 67 | },undefined) 68 | 69 | /***/ } 70 | /******/ ]); -------------------------------------------------------------------------------- /weex/configs/utils.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const config = require('./config') 3 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | const packageConfig = require('../package.json') 5 | 6 | exports.cssLoaders = function (options) { 7 | options = options || {} 8 | const cssLoader = { 9 | loader: 'css-loader', 10 | options: { 11 | sourceMap: options.sourceMap 12 | } 13 | } 14 | 15 | const postcssLoader = { 16 | loader: 'postcss-loader', 17 | options: { 18 | sourceMap: options.sourceMap 19 | } 20 | } 21 | 22 | // generate loader string to be used with extract text plugin 23 | const generateLoaders = (loader, loaderOptions) => { 24 | let loaders = options.useVue ? [cssLoader] : [] 25 | if (options.usePostCSS) { 26 | loaders.push(postcssLoader) 27 | } 28 | if (loader) { 29 | loaders.push({ 30 | loader: loader + '-loader', 31 | options: Object.assign({}, loaderOptions, { 32 | sourceMap: options.sourceMap 33 | }) 34 | }) 35 | } 36 | if (options.useVue) { 37 | return ['vue-style-loader'].concat(loaders) 38 | } 39 | else { 40 | return loaders 41 | } 42 | } 43 | 44 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 45 | return { 46 | less: generateLoaders('less'), 47 | sass: generateLoaders('sass', { indentedSyntax: true }), 48 | scss: generateLoaders('sass'), 49 | stylus: generateLoaders('stylus'), 50 | styl: generateLoaders('stylus') 51 | } 52 | } 53 | 54 | // Generate loaders for standalone style files (outside of .vue) 55 | exports.styleLoaders = function (options) { 56 | const output = [] 57 | const loaders = exports.cssLoaders(options) 58 | 59 | for (const extension in loaders) { 60 | const loader = loaders[extension] 61 | output.push({ 62 | test: new RegExp('\\.' + extension + '$'), 63 | use: loader 64 | }) 65 | } 66 | 67 | return output 68 | } 69 | 70 | exports.createNotifierCallback = () => { 71 | const notifier = require('node-notifier') 72 | 73 | return (severity, errors) => { 74 | if (severity !== 'error') return 75 | 76 | const error = errors[0] 77 | const filename = error.file && error.file.split('!').pop() 78 | 79 | notifier.notify({ 80 | title: packageConfig.name, 81 | message: severity + ': ' + error.name, 82 | subtitle: filename || '', 83 | icon: path.join(__dirname, 'logo.png') 84 | }) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /vue/puzzle2.md: -------------------------------------------------------------------------------- 1 | # 使用Vue做一个可自动拼图的拼图小游戏(二) 2 | 3 | ## 背景以及最终效果 4 | 5 | 在上一篇文章中我们已经写完了一个可以正常玩的拼图小游戏,但是这还没有结束,我们还要接着试一下让拼图游戏可以自己完成拼图。 6 | 最终效果如下图: 7 |  8 | 9 | 本部分是这篇文章的第二部分,主要讲的是实现自动拼图的功能实现。 10 | 11 | ## 原理 12 | 13 | 这里开始就涉及到一些算法的知识了,不过不难。拼图游戏其实就是:N数码问题,而我写的是3*3的,所以就是八数码问题的求解。 14 | 总结一下,我们需要做的事包括以下几个: 15 | 16 | 1. 判断八数码问题是否有解(其实就是判断该拼图是否可以还原) 17 | 2. 求解(寻找复原路径) 18 | 3. 渲染(根据找出来的复原路径在页面中渲染出来) 19 | 20 | ## 具体步骤 21 | 22 | 清楚了具体要做的事,那就一件一件跟着做就好了。 23 | 24 | ### 判断八数码问题是否有解 25 | 26 | 在上一篇文章我提过一点,就是我们使用数组打乱函数直接打乱的拼图是不一定可以还原的。这一点我们可以类比一下魔方,玩过魔方的应该都知道,当我们正常的将魔方转动打乱,无论多乱,都是可以复原的。但是如果我们将其中的一颗或者几颗扣下来,随意的装上去,那这个魔方就不一定可以复原了。在我们拼图中也是同样的道理。判断八数码问题是否有解可以利用**原始状态**(打乱之后的状态)和**结果状态**(即拼好时的状态)的**逆序数奇偶性是否相同**来判断。 27 | 28 | 假设我们的结果状态如下: 29 | 30 | ```html 31 | 1 2 3 32 | 4 5 6 33 | 7 8 34 | ``` 35 | 36 | 为了方便表示我们将第九个位置为空的表示为“0”,然后将结果状态表示成为一维的形式,结果如下: 37 | 38 | ```html 39 | 1 2 3 4 5 6 7 8 0 40 | ``` 41 | 42 | 可以通过实验得知:交换了前两个位置的八数码问题是无解的: 43 | 44 | ```html 45 | 2 1 3 4 5 6 7 8 0 46 | ``` 47 | 48 | 实际上八数码问题有解的结论是这样的: 49 | **若两个状态的逆序奇偶性相同,则有解,否则不可解。** 50 | 51 | 那什么是**逆序**呢? 52 | **一个状态表示成一维的形式,求出除0之外所有数字的逆序数之和,也就是每个数字前面比它大的数字的个数的和,称为这个状态的逆序。** 53 | 54 | 再去看刚刚举的例子:结果状态`1 2 3 4 5 6 7 8 0`和原始状态`2 1 3 4 5 6 7 8 0`。根据逆序的定义可以计算出来结果状态的逆序是**0**,原始状态的逆序是**1**,奇偶性不一致,因此该八数码问题不可解。 55 | 56 | 通俗的讲:我们可以想象一下现在有一个拼图,我们左右移动空格的时候,整个状态的逆序其实是不变的,所以会保持奇偶性一致。当我们上下移动的时候,转换成一维之后就相当于将一个数字向前或者向后移动两格,奇偶性还是不变的。 57 | 58 | 那怎么求逆序呢? 59 | 60 | ```javascript 61 | // 求逆序奇偶性 62 | odevity(node) { 63 | var num = 0; 64 | node.splice(node.indexOf("0"), 1); 65 | node.forEach(function(item, index) { 66 | for (var i = 0; i < index; i++) { 67 | if (node[i] != 0) { 68 | if (node[i] > item) { 69 | num++; 70 | } 71 | } 72 | } 73 | }); 74 | if (num % 2) { 75 | return 1; 76 | } else { 77 | return 0; 78 | } 79 | }, 80 | ``` 81 | 82 | ### 寻找复原的路径 83 | 84 | 寻找复原的路径其实很简单,只需要将使用广度优先算法遍历。原始状态可以设定为广度搜索中图的第一层,由原始状态通过判断0的移动方向可以得到该状态的子节点,同时需要维护一个对象来记录每个子节点的父节点是谁以此来反推出动画的运动轨迹及一个对象来负责判断当前子节点先前是否已出现过,出现过则无需再压入队。至此反复求出节点的子节点并无重复的压入队。代码比较长,就不展示在这里了,可以去[github](https://github.com/usecodelee/Vue-jigsawPuzzle)上查看。 85 | 86 | ### 优化 87 | 88 | 优化的话可以从搜索算法上使用A*算法进行优化。此外,为了提高用户体验,我做的这个小游戏里面当打乱之后不能复原的话可以自动重新打乱,直到可以复原为止。 89 | 90 | 看看最终的效果: 91 |  92 | 93 | 项目源码:[https://github.com/usecodelee/Vue-jigsawPuzzle](https://github.com/usecodelee/Vue-jigsawPuzzle) 94 | -------------------------------------------------------------------------------- /weex/platforms/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /weex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fproject", 3 | "version": "1.0.0", 4 | "description": "A weex project", 5 | "author": "", 6 | "private": true, 7 | "scripts": { 8 | "start": "npm run serve", 9 | "build": "webpack --env.NODE_ENV=common", 10 | "build:prod": "webpack --env.NODE_ENV=production", 11 | "build:prod:web": "webpack --env.NODE_ENV=release", 12 | "build:plugin": "webpack --env.NODE_ENV=plugin", 13 | "clean:web": "rimraf ./release/web", 14 | "clean:ios": "rimraf ./release/ios", 15 | "clean:android": "rimraf ./release/android", 16 | "dev": "webpack --env.NODE_ENV=common --progress --watch", 17 | "lint": "eslint --ext .js,.vue src --fix", 18 | "serve": "webpack-dev-server --env.NODE_ENV=development --progress", 19 | "ios": "weex run ios", 20 | "web": "npm run serve", 21 | "android": "weex run android", 22 | "pack:ios": "npm run clean:ios && weex build ios", 23 | "pack:android": "npm run clean:android && weex build android", 24 | "pack:web": "npm run clean:web && npm run build:prod:web" 25 | }, 26 | "keywords": [ 27 | "weex" 28 | ], 29 | "license": "MIT", 30 | "dependencies": { 31 | "phantom-limb": "0.0.1", 32 | "vue": "^2.5.11", 33 | "vue-router": "^3.0.1", 34 | "weex-ui": "^0.6.10", 35 | "weex-vue-render": "^1.0.17" 36 | }, 37 | "devDependencies": { 38 | "autoprefixer": "^8.0.0", 39 | "babel-core": "^6.26.0", 40 | "babel-eslint": "^8.2.1", 41 | "babel-loader": "^7.1.1", 42 | "babel-plugin-component": "^1.1.1", 43 | "babel-preset-stage-0": "^6.24.1", 44 | "chai": "^4.1.2", 45 | "css-loader": "^0.28.8", 46 | "eslint": "^4.15.0", 47 | "eslint-config-standard": "^10.2.1", 48 | "eslint-friendly-formatter": "^3.0.0", 49 | "eslint-loader": "^1.7.1", 50 | "eslint-plugin-import": "^2.7.0", 51 | "eslint-plugin-node": "^5.2.0", 52 | "eslint-plugin-promise": "^3.4.0", 53 | "eslint-plugin-standard": "^3.0.1", 54 | "eslint-plugin-vue": "^4.0.0", 55 | "extract-text-webpack-plugin": "^3.0.2", 56 | "friendly-errors-webpack-plugin": "^1.6.1", 57 | "fs-extra": "^5.0.0", 58 | "glob": "^7.1.2", 59 | "html-webpack-plugin": "^2.30.1", 60 | "html-webpack-plugin-for-multihtml": "^2.30.2", 61 | "ip": "^1.1.5", 62 | "node-notifier": "^5.1.2", 63 | "portfinder": "^1.0.13", 64 | "postcss-import": "^11.0.0", 65 | "postcss-loader": "^2.0.9", 66 | "postcss-plugin-weex": "^0.1.6", 67 | "raw-loader": "^0.5.1", 68 | "rimraf": "^2.6.2", 69 | "script-ext-html-webpack-plugin": "^1.8.5", 70 | "vue-loader": "^12.2.0", 71 | "vue-style-loader": "^3.0.3", 72 | "vue-template-compiler": "^2.5.11", 73 | "webpack": "^3.10.0", 74 | "webpack-dev-server": "^2.9.7", 75 | "webpack-merge": "^4.1.0", 76 | "webpack-uglify-parallel": "^0.1.4", 77 | "weex-loader": "^0.7.2", 78 | "weex-vue-precompiler": "^0.1.17", 79 | "ws": "^1.1.0" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /weex/platforms/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.taobao.android.weex.plugin.gradle' 3 | 4 | android { 5 | compileSdkVersion project.compileSdkVersion 6 | buildToolsVersion project.buildToolsVersion 7 | 8 | defaultConfig { 9 | applicationId "com.weex.app" 10 | minSdkVersion project.appMinSdkVersion 11 | targetSdkVersion project.targetSdkVersion 12 | versionCode 1 13 | versionName "1.0.0" 14 | ndk { 15 | abiFilters "x86" 16 | abiFilters "armeabi" 17 | } 18 | } 19 | applicationVariants.all { variant -> 20 | variant.outputs.each { output -> 21 | def outputFile = output.outputFile 22 | if (outputFile != null && outputFile.name.equals('app-debug.apk')) { 23 | def fileName = outputFile.name.replace("app-debug.apk", "weex-app.apk") 24 | output.outputFile = new File(outputFile.parent, fileName) 25 | } 26 | } 27 | } 28 | signingConfigs { 29 | debug { 30 | storeFile file("tools/debug.keystore") 31 | storePassword "android" 32 | keyAlias "androiddebugkey" 33 | keyPassword "android" 34 | } 35 | } 36 | buildTypes { 37 | debug { 38 | signingConfig signingConfigs.debug 39 | } 40 | } 41 | sourceSets { 42 | main { 43 | java { 44 | srcDirs = ["src/main/java", "src/main/java_zxing"]; 45 | } 46 | } 47 | } 48 | lintOptions { 49 | abortOnError false 50 | } 51 | 52 | packagingOptions { 53 | exclude 'LICENSE.txt' 54 | } 55 | 56 | compileOptions { 57 | sourceCompatibility JavaVersion.VERSION_1_7 58 | targetCompatibility JavaVersion.VERSION_1_7 59 | } 60 | } 61 | 62 | 63 | dependencies { 64 | compile fileTree(include: ['*.jar'], dir: 'libs') 65 | compile 'com.taobao.android:weex_sdk:0.20.3.0-beta' 66 | compile 'com.google.code.findbugs:jsr305:2.0.1' 67 | compile 'com.squareup.okhttp:okhttp:2.3.0' 68 | compile 'com.squareup.okhttp:okhttp-ws:2.3.0' 69 | compile 'com.squareup.okio:okio:1.0.1' 70 | compile 'com.squareup.picasso:picasso:2.5.2' 71 | compile "com.alibaba:fastjson:${project.fastjsonLibVersion}" 72 | compile "com.android.support:support-v4:${project.supportLibVersion}" 73 | compile "com.android.support:appcompat-v7:${project.supportLibVersion}" 74 | compile "com.android.support:design:${project.supportLibVersion}" 75 | compile "com.android.support:support-annotations:${project.supportLibVersion}" 76 | compile 'com.taobao.android:weex_inspector:0.20.3.0-beta' 77 | compile 'com.journeyapps:zxing-android-embedded:3.4.0' 78 | // PLUGIN GRADLE EXTENSIONS START 79 | compile 'com.taobao.android:weexplugin-loader:1.3' 80 | compile 'com.taobao.android:weexplugin-processor:1.3' 81 | compile 'com.taobao.android:weexplugin-annotation:1.3' 82 | // PLUGIN GRADLE EXTENSIONS END 83 | } 84 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/util/AppConfigXmlParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | package com.weex.app.util; 21 | 22 | import android.content.Context; 23 | import android.util.Log; 24 | 25 | import org.xmlpull.v1.XmlPullParser; 26 | import org.xmlpull.v1.XmlPullParserException; 27 | 28 | import java.io.IOException; 29 | import java.util.Locale; 30 | 31 | public class AppConfigXmlParser { 32 | private static String TAG = "AppConfigXmlParser"; 33 | 34 | private AppPreferences prefs = new AppPreferences(); 35 | 36 | public AppPreferences getPreferences() { 37 | return prefs; 38 | } 39 | 40 | public synchronized void parse(Context action) { 41 | // First checking the class namespace for config.xml 42 | int id = action.getResources().getIdentifier("app_config", "xml", action.getClass().getPackage() 43 | .getName()); 44 | if (id == 0) { 45 | // If we couldn't find config.xml there, we'll look in the namespace from AndroidManifest.xml 46 | id = action.getResources().getIdentifier("app_config", "xml", action.getPackageName()); 47 | if (id == 0) { 48 | Log.e(TAG, "res/xml/app_config.xml is missing!"); 49 | return; 50 | } 51 | } 52 | parse(action.getResources().getXml(id)); 53 | } 54 | 55 | public void parse(XmlPullParser xml) { 56 | int eventType = -1; 57 | 58 | while (eventType != XmlPullParser.END_DOCUMENT) { 59 | if (eventType == XmlPullParser.START_TAG) { 60 | handleStartTag(xml); 61 | } else if (eventType == XmlPullParser.END_TAG) { 62 | handleEndTag(xml); 63 | } 64 | try { 65 | eventType = xml.next(); 66 | } catch (XmlPullParserException e) { 67 | e.printStackTrace(); 68 | } catch (IOException e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | } 73 | 74 | private void handleStartTag(XmlPullParser xml) { 75 | String strNode = xml.getName(); 76 | if (strNode.equals("preference")) { 77 | String name = xml.getAttributeValue(null, "name").toLowerCase(Locale.ENGLISH); 78 | String value = xml.getAttributeValue(null, "value"); 79 | prefs.set(name, value); 80 | } 81 | } 82 | 83 | private void handleEndTag(XmlPullParser xml) { 84 | 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /weex/web/assets/preview.css: -------------------------------------------------------------------------------- 1 | html,body {width:100%;height:100%;margin:0;padding:0;} 2 | body { display: flex; flex-direction: column; } 3 | .center { display: flex; align-items: center; justify-content: center; } 4 | 5 | #preview { width: 750px; height: 1250px; transform: scale(0.4); transform-origin: top left; } 6 | .mock-phone { position: relative; width: 320px; min-width: 320px; height: 625px; border: 2px solid #0088fb; border-radius: 30px; } 7 | .mock-phone .inner { position: absolute; top: 50px; z-index: 26; left: 10px; width: 300px; height: 500px; border: 1px solid #0088fb; overflow: hidden; } 8 | .mock-phone .inner iframe { width: 100%; height: 100%; margin: 0; } 9 | .mock-phone .camera { position: absolute; width: 10px; height: 10px; border-radius: 10px; background: #afddff; border: 1px solid #0088fb; top: 20px; left: 96px; } 10 | .mock-phone .earpiece { position: absolute; width: 70px; height: 8px; border-radius: 8px; background: #afddff; border: 1px solid #0088fb; top: 20px; left: 120px; } 11 | .mock-phone .home-btn { position: absolute; width: 50px; height: 50px; border-radius: 50px; background: #afddff; border: 1px solid #0088fb; bottom: 10px; left: 50%; margin-left: -25px; } 12 | 13 | 14 | .header { 15 | height: 100px; 16 | flex-grow: 0; 17 | } 18 | .content { 19 | display: flex; 20 | flex-grow: 1; 21 | flex-direction: row; 22 | } 23 | .main { 24 | display: flex; 25 | flex-direction: row; 26 | justify-content: space-between; 27 | width: 55%; 28 | min-width: 750px; 29 | max-width: 800px; 30 | } 31 | .main .qrcode-box { 32 | width: 400px; 33 | display: flex; 34 | flex-direction: column; 35 | justify-content: center; 36 | align-items: stretch; 37 | } 38 | .qrcode > img { 39 | display: block; 40 | width: 250px; 41 | height: 250px; 42 | margin: 0 auto; 43 | } 44 | .qrcode-tips { 45 | text-align: center; 46 | margin-top: 20px; 47 | } 48 | .qrcode-tips a, .qrcode-tips a:link { 49 | color: #00B4FF; 50 | text-decoration: none; 51 | } 52 | .qrcode-tips a:hover, .qrcode-tips a:active { 53 | color: #238FFF; 54 | } 55 | .web-page-link { 56 | opacity: 0; 57 | cursor: pointer; 58 | z-index: 999; 59 | display: block; 60 | right: 10px; 61 | top: 10px; 62 | width: 30px; 63 | height: 30px; 64 | font-size: 14px; 65 | border-radius: 50%; 66 | background: #f5f5f5; 67 | border: 1px solid #ddd; 68 | transition: all .2s ease; 69 | position: absolute; 70 | } 71 | .web-page-link svg { 72 | margin: 5px; 73 | opacity: .5; 74 | } 75 | 76 | .inner:hover .web-page-link{ 77 | opacity: 1; 78 | transition: all .2s ease; 79 | } 80 | .pages-box { 81 | max-height: 330px; 82 | overflow-y: auto; 83 | } 84 | .pages-box .page-item{ 85 | display: inline-block; 86 | padding: 5px 8px; 87 | text-decoration: none; 88 | font-size: 14px; 89 | border-radius: 5px; 90 | margin: 10px 5px; 91 | color:#717171; 92 | border:1px solid #ddd; 93 | transition: all .2s ease; 94 | } 95 | .pages-box .page-item:hover{ 96 | border-color:#0088fb; 97 | background: #0088fb; 98 | color:#fff; 99 | } 100 | .pages-box .page-item.active { 101 | border-color:#0088fb; 102 | background: #0088fb; 103 | color:#fff; 104 | } -------------------------------------------------------------------------------- /vue/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 重置 4 | 5 | 12 | 13 | 14 | 15 | 16 | 72 | 73 | 111 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/util/AppPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed to the Apache Software Foundation (ASF) under one 3 | or more contributor license agreements. See the NOTICE file 4 | distributed with this work for additional information 5 | regarding copyright ownership. The ASF licenses this file 6 | to you under the Apache License, Version 2.0 (the 7 | "License"); you may not use this file except in compliance 8 | with the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, 13 | software distributed under the License is distributed on an 14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations 17 | under the License. 18 | */ 19 | 20 | package com.weex.app.util; 21 | 22 | import android.os.Bundle; 23 | 24 | import java.util.HashMap; 25 | import java.util.Locale; 26 | import java.util.Map; 27 | 28 | public class AppPreferences { 29 | private HashMap prefs = new HashMap(20); 30 | private Bundle preferencesBundleExtras; 31 | 32 | public void setPreferencesBundle(Bundle extras) { 33 | preferencesBundleExtras = extras; 34 | } 35 | 36 | public void set(String name, String value) { 37 | prefs.put(name.toLowerCase(Locale.ENGLISH), value); 38 | } 39 | 40 | public void set(String name, boolean value) { 41 | set(name, "" + value); 42 | } 43 | 44 | public void set(String name, int value) { 45 | set(name, "" + value); 46 | } 47 | 48 | public void set(String name, double value) { 49 | set(name, "" + value); 50 | } 51 | 52 | public Map getAll() { 53 | return prefs; 54 | } 55 | 56 | public boolean getBoolean(String name, boolean defaultValue) { 57 | name = name.toLowerCase(Locale.ENGLISH); 58 | String value = prefs.get(name); 59 | if (value != null) { 60 | return Boolean.parseBoolean(value); 61 | } 62 | return defaultValue; 63 | } 64 | 65 | // Added in 4.0.0 66 | public boolean contains(String name) { 67 | return getString(name, null) != null; 68 | } 69 | 70 | public int getInteger(String name, int defaultValue) { 71 | name = name.toLowerCase(Locale.ENGLISH); 72 | String value = prefs.get(name); 73 | if (value != null) { 74 | // Use Integer.decode() can't handle it if the highest bit is set. 75 | return (int)(long) Long.decode(value); 76 | } 77 | return defaultValue; 78 | } 79 | 80 | public double getDouble(String name, double defaultValue) { 81 | name = name.toLowerCase(Locale.ENGLISH); 82 | String value = prefs.get(name); 83 | if (value != null) { 84 | return Double.valueOf(value); 85 | } 86 | return defaultValue; 87 | } 88 | 89 | public String getString(String name, String defaultValue) { 90 | name = name.toLowerCase(Locale.ENGLISH); 91 | String value = prefs.get(name); 92 | if (value != null) { 93 | return value; 94 | } 95 | return defaultValue; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/extend/ImageAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.weex.app.extend; 20 | 21 | import android.net.Uri; 22 | import android.text.TextUtils; 23 | import android.widget.ImageView; 24 | 25 | import com.squareup.picasso.Callback; 26 | import com.squareup.picasso.Picasso; 27 | import com.taobao.weex.WXEnvironment; 28 | import com.taobao.weex.WXSDKManager; 29 | import com.taobao.weex.adapter.IWXImgLoaderAdapter; 30 | import com.taobao.weex.common.WXImageStrategy; 31 | import com.taobao.weex.dom.WXImageQuality; 32 | 33 | public class ImageAdapter implements IWXImgLoaderAdapter { 34 | 35 | public ImageAdapter() { 36 | } 37 | 38 | @Override 39 | public void setImage(final String url, final ImageView view, 40 | WXImageQuality quality, final WXImageStrategy strategy) { 41 | 42 | WXSDKManager.getInstance().postOnUiThread(new Runnable() { 43 | 44 | @Override 45 | public void run() { 46 | if(view==null||view.getLayoutParams()==null){ 47 | return; 48 | } 49 | if (TextUtils.isEmpty(url)) { 50 | view.setImageBitmap(null); 51 | return; 52 | } 53 | String temp = url; 54 | if (url.startsWith("//")) { 55 | temp = "http:" + url; 56 | } 57 | if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) { 58 | return; 59 | } 60 | 61 | 62 | if(!TextUtils.isEmpty(strategy.placeHolder)){ 63 | Picasso.Builder builder=new Picasso.Builder(WXEnvironment.getApplication()); 64 | Picasso picasso=builder.build(); 65 | picasso.load(Uri.parse(strategy.placeHolder)).into(view); 66 | 67 | view.setTag(strategy.placeHolder.hashCode(),picasso); 68 | } 69 | 70 | Picasso.with(WXEnvironment.getApplication()) 71 | .load(temp) 72 | .transform(new BlurTransformation(strategy.blurRadius)) 73 | .into(view, new Callback() { 74 | @Override 75 | public void onSuccess() { 76 | if(strategy.getImageListener()!=null){ 77 | strategy.getImageListener().onImageFinish(url,view,true,null); 78 | } 79 | 80 | if(!TextUtils.isEmpty(strategy.placeHolder)){ 81 | ((Picasso) view.getTag(strategy.placeHolder.hashCode())).cancelRequest(view); 82 | } 83 | } 84 | 85 | @Override 86 | public void onError() { 87 | if(strategy.getImageListener()!=null){ 88 | strategy.getImageListener().onImageFinish(url,view,false,null); 89 | } 90 | } 91 | }); 92 | } 93 | },0); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/hotreload/HotReloadManager.java: -------------------------------------------------------------------------------- 1 | package com.weex.app.hotreload; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.squareup.okhttp.OkHttpClient; 6 | import com.squareup.okhttp.Request; 7 | import com.squareup.okhttp.Response; 8 | import com.squareup.okhttp.ws.WebSocket; 9 | import com.squareup.okhttp.ws.WebSocketCall; 10 | import com.squareup.okhttp.ws.WebSocketListener; 11 | import com.taobao.weex.utils.WXLogUtils; 12 | 13 | import org.json.JSONException; 14 | import org.json.JSONObject; 15 | 16 | import java.io.IOException; 17 | 18 | import okio.Buffer; 19 | import okio.BufferedSource; 20 | 21 | /** 22 | * Created by moxun on 29/12/2017. 23 | */ 24 | 25 | public class HotReloadManager { 26 | private static final String TAG = "HotReloadManager"; 27 | private ActionListener listener; 28 | private WebSocket session; 29 | 30 | public HotReloadManager(String ws, final ActionListener actionListener) { 31 | if (TextUtils.isEmpty(ws) || actionListener == null) { 32 | WXLogUtils.w("HotReloadManager", "Illegal arguments"); 33 | return; 34 | } 35 | this.listener = actionListener; 36 | 37 | OkHttpClient client = new OkHttpClient(); 38 | Request.Builder builder = new Request.Builder(); 39 | builder.url(ws); 40 | Request request = builder.build(); 41 | WebSocketCall call = WebSocketCall.create(client, request); 42 | call.enqueue(new WebSocketListener() { 43 | @Override 44 | public void onOpen(WebSocket webSocket, Request request, Response response) throws IOException { 45 | WXLogUtils.w(TAG, "ws session open"); 46 | session = webSocket; 47 | } 48 | 49 | @Override 50 | public void onMessage(BufferedSource bufferedSource, WebSocket.PayloadType payloadType) throws IOException { 51 | WXLogUtils.w(TAG, "on message"); 52 | if (payloadType == WebSocket.PayloadType.TEXT) { 53 | String message = bufferedSource.readUtf8(); 54 | bufferedSource.close(); 55 | try { 56 | JSONObject rpcMessage = new JSONObject(message); 57 | String method = rpcMessage.optString("method", null); 58 | if (!TextUtils.isEmpty(method)) { 59 | if ("WXReload".equals(method)) { 60 | listener.reload(); 61 | } else if ("WXReloadBundle".equals(method)) { 62 | String bundleUrl = rpcMessage.optString("params", null); 63 | if (!TextUtils.isEmpty(bundleUrl)) { 64 | listener.render(bundleUrl); 65 | } 66 | } 67 | } 68 | } catch (JSONException e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | } 73 | 74 | @Override 75 | public void onPong(Buffer buffer) { 76 | WXLogUtils.w(TAG, "on pong"); 77 | } 78 | 79 | @Override 80 | public void onClose(int i, String s) { 81 | WXLogUtils.w("HotReloadManager", "Closed:" + i + ", " + s); 82 | } 83 | 84 | @Override 85 | public void onFailure(IOException e) { 86 | e.printStackTrace(); 87 | } 88 | }); 89 | } 90 | 91 | public void destroy() { 92 | if (session != null) { 93 | try { 94 | session.close(1001, "GOING_AWAY"); 95 | } catch (IOException e) { 96 | e.printStackTrace(); 97 | } 98 | } 99 | } 100 | 101 | public interface ActionListener { 102 | void reload(); 103 | 104 | void render(String bundleUrl); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /weex/configs/config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const ROOT = path.resolve(__dirname, '..'); 3 | const ip = require('ip').address(); 4 | const config = { 5 | root: ROOT, 6 | // webpack-dev-server 7 | pluginConfigPath: 'plugins/plugins.json', 8 | pluginFilePath: 'plugins/plugins.js', 9 | // router 10 | routerFilePath: 'router.js', 11 | // common 12 | templateDir: '.temp', 13 | entryFilePath: 'entry.js', 14 | // Module exclude from compile process 15 | excludeModuleReg: /node_modules(?!(\/|\\).*(weex).*)/, 16 | dev: { 17 | // Various Dev Server settings 18 | contentBase: ROOT, 19 | host: ip, 20 | port: 8081, 21 | historyApiFallback: true, 22 | open: true, 23 | watchContentBase: true, 24 | openPage: 'web/preview.html', 25 | watchOptions: { 26 | ignored: /node_modules/, 27 | aggregateTimeout: 300, 28 | poll: false 29 | }, 30 | // Use Eslint Loader? 31 | // If true, your code will be linted during bundling and 32 | // linting errors and warnings will be shown in the console. 33 | useEslint: true, 34 | // If true, eslint errors and warnings will also be shown in the error overlay 35 | // in the browser. 36 | showEslintErrorsInOverlay: false, 37 | /** 38 | * Source Maps 39 | */ 40 | // https://webpack.js.org/configuration/devtool/#development 41 | devtool: 'eval-source-map', 42 | env: JSON.stringify('development'), 43 | // If you have problems debugging vue-files in devtools, 44 | // set this to false - it *may* help 45 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 46 | cacheBusting: true, 47 | // CSS Sourcemaps off by default because relative paths are "buggy" 48 | // with this option, according to the CSS-Loader README 49 | // (https://github.com/webpack/css-loader#sourcemaps) 50 | // In our experience, they generally work as expected, 51 | // just be aware of this issue when enabling this option. 52 | cssSourceMap: false, 53 | proxyTable: {}, 54 | autoOpenBrowser: false, 55 | errorOverlay: true, 56 | notifyOnErrors: true, 57 | htmlOptions: { 58 | devScripts: ` 59 | 72 | ` 73 | } 74 | }, 75 | prod: { 76 | env: JSON.stringify('production'), 77 | /** 78 | * Source Maps 79 | */ 80 | productionSourceMap: true, 81 | // https://webpack.js.org/configuration/devtool/#production 82 | devtool: '#source-map', 83 | cssSourceMap: true, 84 | productionSourceMap: true 85 | }, 86 | nodeConfiguration: { 87 | global: false, 88 | Buffer: false, 89 | __filename: false, 90 | __dirname: false, 91 | setImmediate: false, 92 | clearImmediate: false, 93 | // see: https://github.com/webpack/node-libs-browser 94 | assert: false, 95 | buffer: false, 96 | child_process: false, 97 | cluster: false, 98 | console: false, 99 | constants: false, 100 | crypto: false, 101 | dgram: false, 102 | dns: false, 103 | domain: false, 104 | events: false, 105 | fs: false, 106 | http: false, 107 | https: false, 108 | module: false, 109 | net: false, 110 | os: false, 111 | path: false, 112 | process: false, 113 | punycode: false, 114 | querystring: false, 115 | readline: false, 116 | repl: false, 117 | stream: false, 118 | string_decoder: false, 119 | sys: false, 120 | timers: false, 121 | tls: false, 122 | tty: false, 123 | url: false, 124 | util: false, 125 | vm: false, 126 | zlib: false 127 | } 128 | } 129 | module.exports = config; 130 | -------------------------------------------------------------------------------- /weex/configs/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | const commonConfig = require('./webpack.common.conf'); 2 | const webpackMerge = require('webpack-merge'); // used to merge webpack configs 3 | const os = require('os'); 4 | const webpack = require('webpack'); 5 | 6 | const config = require('./config'); 7 | const helper = require('./helper'); 8 | 9 | /** 10 | * Webpack Plugins 11 | */ 12 | const UglifyJsparallelPlugin = require('webpack-uglify-parallel'); 13 | 14 | /** 15 | * Webpack configuration for weex. 16 | */ 17 | const weexConfig = webpackMerge(commonConfig[1], { 18 | /* 19 | * Add additional plugins to the compiler. 20 | * 21 | * See: http://webpack.github.io/docs/configuration.html#plugins 22 | */ 23 | plugins: [ 24 | /* 25 | * Plugin: UglifyJsparallelPlugin 26 | * Description: Identical to standard uglify webpack plugin 27 | * with an option to build multiple files in parallel 28 | * 29 | * See: https://www.npmjs.com/package/webpack-uglify-parallel 30 | */ 31 | new UglifyJsparallelPlugin({ 32 | workers: os.cpus().length, 33 | mangle: true, 34 | compressor: { 35 | warnings: false, 36 | drop_console: true, 37 | drop_debugger: true 38 | } 39 | }), 40 | // Need to run uglify first, then pipe other webpack plugins 41 | ...commonConfig[1].plugins, 42 | /** 43 | * Plugin: webpack.DefinePlugin 44 | * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. 45 | * 46 | * See: https://webpack.js.org/plugins/define-plugin/ 47 | */ 48 | new webpack.DefinePlugin({ 49 | 'process.env': { 50 | 'NODE_ENV': config.prod.env 51 | } 52 | }) 53 | ] 54 | }) 55 | 56 | /** 57 | * Webpack configuration for web. 58 | */ 59 | const webConfig = webpackMerge(commonConfig[0], { 60 | /** 61 | * Developer tool to enhance debugging 62 | * 63 | * See: http://webpack.github.io/docs/configuration.html#devtool 64 | * See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps 65 | */ 66 | devtool: config.prod.devtool, 67 | /** 68 | * Options affecting the output of the compilation. 69 | * 70 | * See: http://webpack.github.io/docs/configuration.html#output 71 | */ 72 | output: { 73 | /** 74 | * The output directory as absolute path (required). 75 | * 76 | * See: http://webpack.github.io/docs/configuration.html#output-path 77 | */ 78 | path: helper.rootNode('./dist'), 79 | /** 80 | * Specifies the name of each output file on disk. 81 | * IMPORTANT: You must not specify an absolute path here! 82 | * 83 | * See: http://webpack.github.io/docs/configuration.html#output-filename 84 | */ 85 | filename: '[name].web.js', 86 | /** 87 | * The filename of the SourceMaps for the JavaScript files. 88 | * They are inside the output.path directory. 89 | * 90 | * See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename 91 | */ 92 | sourceMapFilename: '[name].web.map' 93 | }, 94 | /* 95 | * Add additional plugins to the compiler. 96 | * 97 | * See: http://webpack.github.io/docs/configuration.html#plugins 98 | */ 99 | plugins: [ 100 | /** 101 | * Plugin: webpack.DefinePlugin 102 | * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. 103 | * 104 | * See: https://webpack.js.org/plugins/define-plugin/ 105 | */ 106 | new webpack.DefinePlugin({ 107 | 'process.env': { 108 | 'NODE_ENV': config.prod.env 109 | } 110 | }), 111 | /* 112 | * Plugin: UglifyJsparallelPlugin 113 | * Description: Identical to standard uglify webpack plugin 114 | * with an option to build multiple files in parallel 115 | * 116 | * See: https://www.npmjs.com/package/webpack-uglify-parallel 117 | */ 118 | new UglifyJsparallelPlugin({ 119 | workers: os.cpus().length, 120 | mangle: true, 121 | compressor: { 122 | warnings: false, 123 | drop_console: true, 124 | drop_debugger: true 125 | } 126 | }) 127 | ] 128 | }); 129 | 130 | module.exports = [weexConfig, webConfig] 131 | -------------------------------------------------------------------------------- /weex/web/preview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Weex Preview 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Use Weex playground app to scan it. 34 | 35 | 36 | 37 | 38 | 39 | 40 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /vue/puzzle1.md: -------------------------------------------------------------------------------- 1 | # 使用Vue做一个可自动拼图的拼图小游戏(一) 2 | 3 | ## 背景以及最终效果 4 | 5 | 随着几个项目的提测,也闲下来了,恰好玩了一把拼图游戏,于是突发奇想打算自己写一个试试。 6 | 最终效果如下图: 7 |  8 | 9 | ### 实现的功能有: 10 | 11 | 1. 普通拼图的功能 12 | 2. 自动拼图 13 | 14 | 本部分是这篇文章的第一部分,主要讲的是实现普通拼图的功能。 15 | 16 | ## 原理 17 | 18 | 相信拼图的玩法大家一点都不陌生,就是点击一个非空的块,如果它的周围有空的块,被点击的块就会往空块的方向移动。如果最后的排列是`[1,2,3,4,5,6,7,8,0]`,则过关。 19 | 于是总结一下,我们需要做的事包括以下几个: 20 | 21 | 1. 使用Vue 22 | 2. 页面布局 23 | 3. 打乱 24 | 4. 点击和移动 25 | 5. 判断有没有过关 26 | 27 | ## 具体步骤 28 | 29 | 清楚了具体要做的事,那就一件一件跟着做就好了。 30 | 31 | ### 使用Vue 32 | 33 | 直接使用vue-cli脚手架工具安装即可。 34 | 35 | - 1.安装 36 | 37 | > `npm install -g @vue/cli` 38 | 39 | - 2.创建一个项目 40 | 41 | > `vue create hello-world` 42 | 43 | ### 页面布局 44 | 45 | html 46 | 47 | ```html 48 | 49 | 50 | 51 | 58 | 59 | 60 | 61 | ``` 62 | 63 | css 64 | 65 | ```css 66 | 104 | ``` 105 | 106 | 有一点需要注意的是我在页面中是使用Vue的列表的排序过渡动画,效果看起来挺不错的。`` 组件有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 `v-move` 特性,它会在元素的改变定位的过程中应用。像之前的类名一样,可以通过 `name` 属性来自定义前缀,也可以通过 `move-class` 属性手动设置。详细使用情况请看: 107 | [https://cn.vuejs.org/v2/guide/transitions.html](https://cn.vuejs.org/v2/guide/transitions.html) 108 | 109 | js部分则需要在`data`属性中定义一个数组,`methods`中需要定义一个渲染函数,`mounted`中则是执行这个渲染函数: 110 | 111 | ```javascript 112 | data() { 113 | return { 114 | puzzles: [] 115 | }; 116 | }, 117 | rander() { 118 | this.puzzles = [1,2,3,4,5,6,7,8,''] 119 | }, 120 | mounted() { 121 | this.rander(); 122 | } 123 | ``` 124 | 125 | 现在我们来看一下效果: 126 |  127 | 128 | ### 打乱 129 | 130 | 现在给这个拼图加个打乱的按钮。 131 | 132 | ```html 133 | 重置 134 | ``` 135 | 136 | 然后在methods中定义一个‘`shuffle`’函数,负责打乱整个拼图: 137 | 138 | ```javascript 139 | shuffle() { 140 | this.puzzles = _.shuffle(this.puzzles); 141 | }, 142 | ``` 143 | 144 | 其中`_.shuffle`是`lodash`的打乱数组函数,当然不喜欢这个库的话也可以自己写一个打乱函数。 145 | 然后我们再看看效果: 146 |  147 | 148 | 有一个需要注意的点:我们写的打乱函数打乱的拼图其实不一定都是可以复原的。能不能复原需要用专门的算法计算出来,我会在下一篇文章讲到。 149 | 150 | ### 点击和移动 151 | 152 | 这个地方稍微复杂一点,具体过程就是当点击某个块的时候获取点击快上下左右的值,如果空白块在点击快的左边,并且点击快不是此列的第一个,则点击块往左侧和空白块交换位置,其实是交换值。 153 | 具体的代码如下: 154 | 155 | ```javascript 156 | // 点击方块 157 | clickBlock(index) { 158 | let curIndex = this.puzzles[index]; 159 | let leftIndex = this.puzzles[index - 1]; 160 | let rightIndex = this.puzzles[index + 1]; 161 | let topIndex = this.puzzles[index - 3]; 162 | let bottomIndex = this.puzzles[index + 3]; 163 | 164 | if (leftIndex === '' && index % 3) { 165 | this.$set(this.puzzles, index - 1, curIndex); 166 | this.$set(this.puzzles, index, ''); 167 | } else if (rightIndex === '' && 2 !== index % 3) { 168 | this.$set(this.puzzles, index + 1, curIndex); 169 | this.$set(this.puzzles, index, ''); 170 | } else if (topIndex === '') { 171 | this.$set(this.puzzles, index - 3, curIndex); 172 | this.$set(this.puzzles, index, ''); 173 | } else if (bottomIndex === '') { 174 | this.$set(this.puzzles, index + 3, curIndex); 175 | this.$set(this.puzzles, index, ''); 176 | } 177 | } 178 | ``` 179 | 180 | 可以点击之后再来看看效果: 181 | 182 |  183 | 184 | ### 判断有没有过关 185 | 186 | 判断有没有过关的条件是: 187 | 188 | 1. 最后一块是空 189 | 2. 前面8个是从1-8顺序排列 190 | 191 | ```javascript 192 | pass() { 193 | if (this.puzzles[8] === '') { 194 | const newPuzzles = this.puzzles.slice(0, 8); 195 | const isPass = newPuzzles.every((e, i) => e === i + 1); 196 | if (isPass) { 197 | alert('666!'); 198 | } 199 | } 200 | } 201 | ``` 202 | 203 | 看看最终的效果: 204 |  205 | 206 | 项目源码:[https://github.com/usecodelee/Vue-jigsawPuzzle](https://github.com/usecodelee/Vue-jigsawPuzzle) -------------------------------------------------------------------------------- /weex/platforms/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /weex/configs/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | const commonConfig = require('./webpack.common.conf'); 2 | const webpackMerge = require('webpack-merge'); // used to merge webpack configs 3 | // tools 4 | const chalk = require('chalk'); 5 | const path = require('path'); 6 | const webpack = require('webpack'); 7 | const ip = require('ip').address(); 8 | 9 | /** 10 | * Webpack Plugins 11 | */ 12 | const HtmlWebpackPlugin = require('html-webpack-plugin-for-multihtml'); 13 | const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); 14 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 15 | const portfinder = require('portfinder') 16 | 17 | const config = require('./config'); 18 | const utils = require('./utils'); 19 | const helper = require('./helper'); 20 | 21 | /** 22 | * Modify the url that will open on the browser. 23 | * @param {Array} entry 24 | */ 25 | const postMessageToOpenPage = (entry) => { 26 | let entrys = Object.keys(entry); 27 | let openpage = config.dev.openPage; 28 | // exclude vendor entry. 29 | entrys = entrys.filter(entry => entry !== 'vendor' ); 30 | if(entrys.indexOf('index') > -1) { 31 | openpage += `?page=index.js`; 32 | } 33 | else { 34 | openpage += `?page=${entrys[0]}.js`; 35 | } 36 | if(entrys.length > 1) { 37 | openpage += `&entrys=${entrys.join('|')}` 38 | } 39 | return openpage; 40 | } 41 | 42 | const openPage = postMessageToOpenPage(commonConfig[0].entry); 43 | 44 | // hotreload server for playground App 45 | const wsServer = require('./hotreload'); 46 | let wsTempServer = null 47 | 48 | /** 49 | * Generate multiple entrys 50 | * @param {Array} entry 51 | */ 52 | const generateHtmlWebpackPlugin = (entry) => { 53 | let entrys = Object.keys(entry); 54 | // exclude vendor entry. 55 | entrys = entrys.filter(entry => entry !== 'vendor' ); 56 | const htmlPlugin = entrys.map(name => { 57 | return new HtmlWebpackPlugin({ 58 | multihtmlCache: true, 59 | filename: name + '.html', 60 | template: helper.rootNode(`web/index.html`), 61 | isDevServer: true, 62 | chunksSortMode: 'dependency', 63 | inject: true, 64 | devScripts: config.dev.htmlOptions.devScripts, 65 | chunks: ['vendor', name] 66 | }) 67 | }) 68 | return htmlPlugin; 69 | } 70 | 71 | /** 72 | * Webpack configuration for browser. 73 | */ 74 | const devWebpackConfig = webpackMerge(commonConfig[0], { 75 | /* 76 | * Options affecting the resolving of modules. 77 | * 78 | * See: http://webpack.github.io/docs/configuration.html#module 79 | */ 80 | module: { 81 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 82 | }, 83 | /** 84 | * Developer tool to enhance debugging 85 | * 86 | * See: http://webpack.github.io/docs/configuration.html#devtool 87 | * See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps 88 | */ 89 | devtool: config.dev.devtool, 90 | /* 91 | * Add additional plugins to the compiler. 92 | * 93 | * See: http://webpack.github.io/docs/configuration.html#plugins 94 | */ 95 | plugins: [ 96 | /** 97 | * Plugin: webpack.DefinePlugin 98 | * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. 99 | * 100 | * See: https://webpack.js.org/plugins/define-plugin/ 101 | */ 102 | new webpack.DefinePlugin({ 103 | 'process.env': { 104 | 'NODE_ENV': config.dev.env 105 | } 106 | }), 107 | /* 108 | * Plugin: HtmlWebpackPlugin 109 | * Description: Simplifies creation of HTML files to serve your webpack bundles. 110 | * This is especially useful for webpack bundles that include a hash in the filename 111 | * which changes every compilation. 112 | * 113 | * See: https://github.com/ampedandwired/html-webpack-plugin 114 | */ 115 | ...generateHtmlWebpackPlugin(commonConfig[0].entry), 116 | /* 117 | * Plugin: ScriptExtHtmlWebpackPlugin 118 | * Description: Enhances html-webpack-plugin functionality 119 | * with different deployment options for your scripts including: 120 | * 121 | * See: https://github.com/numical/script-ext-html-webpack-plugin 122 | */ 123 | new ScriptExtHtmlWebpackPlugin({ 124 | defaultAttribute: 'defer' 125 | }) 126 | ], 127 | /** 128 | * Webpack Development Server configuration 129 | * Description: The webpack-dev-server is a little node.js Express server. 130 | * The server emits information about the compilation state to the client, 131 | * which reacts to those events. 132 | * 133 | * See: https://webpack.github.io/docs/webpack-dev-server.html 134 | */ 135 | devServer: { 136 | clientLogLevel: 'warning', 137 | compress: true, 138 | contentBase: config.dev.contentBase, 139 | host: config.dev.host, 140 | port: config.dev.port, 141 | historyApiFallback: config.dev.historyApiFallback, 142 | public: config.dev.public, 143 | open:config.dev.open, 144 | watchContentBase: config.dev.watchContentBase, 145 | overlay: config.dev.errorOverlay 146 | ? { warnings: false, errors: true } 147 | : false, 148 | proxy: config.dev.proxyTable, 149 | quiet: true, // necessary for FriendlyErrorsPlugin 150 | openPage: encodeURI(openPage), 151 | watchOptions: config.dev.watchOptions 152 | } 153 | }); 154 | 155 | /** 156 | * Webpack configuration for weex. 157 | */ 158 | const weexConfig = webpackMerge(commonConfig[1], { 159 | watch: true 160 | }) 161 | 162 | // build source to weex_bundle with watch mode. 163 | webpack(weexConfig, (err, stats) => { 164 | if (err) { 165 | console.err('COMPILE ERROR:', err.stack) 166 | } else { 167 | wsTempServer && wsTempServer.sendSocketMessage() 168 | } 169 | }) 170 | 171 | module.exports = new Promise((resolve, reject) => { 172 | portfinder.basePort = process.env.PORT || config.dev.port 173 | portfinder.getPort((err, port) => { 174 | if (err) { 175 | reject(err) 176 | } else { 177 | // publish the new Port, necessary for e2e tests 178 | process.env.PORT = port 179 | // add port to devServer config 180 | devWebpackConfig.devServer.port = port 181 | devWebpackConfig.devServer.public = `${ip}:${port}` 182 | devWebpackConfig.devServer.openPage += `&wsport=${port+1}` 183 | // Add FriendlyErrorsPlugin 184 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 185 | compilationSuccessInfo: { 186 | messages: [ 187 | `Your application is running here: ${chalk.yellow(`http://${devWebpackConfig.devServer.host}:${port}`)}.` 188 | ], 189 | }, 190 | onErrors: config.dev.notifyOnErrors 191 | ? utils.createNotifierCallback() 192 | : undefined 193 | })) 194 | wsTempServer = new wsServer(port+1) 195 | resolve(devWebpackConfig) 196 | } 197 | }) 198 | }) 199 | -------------------------------------------------------------------------------- /weex/configs/webpack.release.conf.js: -------------------------------------------------------------------------------- 1 | const commonConfig = require('./webpack.common.conf'); 2 | const webpackMerge = require('webpack-merge'); // used to merge webpack configs 3 | // tools 4 | const ip = require('ip').address(); 5 | const os = require('os'); 6 | const chalk = require('chalk'); 7 | const path = require('path'); 8 | const webpack = require('webpack'); 9 | const helper = require('./helper'); 10 | const config = require('./config'); 11 | 12 | console.log(`${chalk.green(`Package web project at ${chalk.bold(path.resolve('./release/web'))}!`)}`) 13 | /** 14 | * Webpack Plugins 15 | */ 16 | const UglifyJsparallelPlugin = require('webpack-uglify-parallel'); 17 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 18 | const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); 19 | 20 | /** 21 | * Generate multiple entrys 22 | * @param {Array} entry 23 | */ 24 | const generateMultipleEntrys = (entry) => { 25 | let entrys = Object.keys(entry); 26 | // exclude vendor entry. 27 | entrys = entrys.filter(entry => entry !== 'vendor' ); 28 | const htmlPlugin = entrys.map(name => { 29 | return new HtmlWebpackPlugin({ 30 | filename: name + '.html', 31 | template: helper.rootNode(`web/index.html`), 32 | isDevServer: true, 33 | chunksSortMode: 'dependency', 34 | inject: true, 35 | chunks: [name], 36 | // production 37 | minimize: true 38 | }) 39 | }) 40 | return htmlPlugin; 41 | } 42 | 43 | /** 44 | * Webpack configuration for web. 45 | */ 46 | const productionConfig = webpackMerge(commonConfig[0], { 47 | /** 48 | * Developer tool to enhance debugging 49 | * 50 | * See: http://webpack.github.io/docs/configuration.html#devtool 51 | * See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps 52 | */ 53 | devtool: config.prod.devtool, 54 | /** 55 | * Options affecting the output of the compilation. 56 | * 57 | * See: http://webpack.github.io/docs/configuration.html#output 58 | */ 59 | output: { 60 | /** 61 | * The output directory as absolute path (required). 62 | * 63 | * See: http://webpack.github.io/docs/configuration.html#output-path 64 | */ 65 | path: helper.rootNode('release/web'), 66 | /** 67 | * Specifies the name of each output file on disk. 68 | * IMPORTANT: You must not specify an absolute path here! 69 | * 70 | * See: http://webpack.github.io/docs/configuration.html#output-filename 71 | */ 72 | filename: '[name].[chunkhash].bundle.js', 73 | /** 74 | * The filename of the SourceMaps for the JavaScript files. 75 | * They are inside the output.path directory. 76 | * 77 | * See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename 78 | */ 79 | sourceMapFilename: '[name].[chunkhash].bundle.map', 80 | /** 81 | * The filename of non-entry chunks as relative path 82 | * inside the output.path directory. 83 | * 84 | * See: http://webpack.github.io/docs/configuration.html#output-chunkfilename 85 | */ 86 | chunkFilename: '[id].[chunkhash].chunk.js' 87 | }, 88 | /* 89 | * Add additional plugins to the compiler. 90 | * 91 | * See: http://webpack.github.io/docs/configuration.html#plugins 92 | */ 93 | plugins: [ 94 | /** 95 | * Plugin: webpack.DefinePlugin 96 | * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. 97 | * 98 | * See: https://webpack.js.org/plugins/define-plugin/ 99 | */ 100 | new webpack.DefinePlugin({ 101 | 'process.env': { 102 | 'NODE_ENV': config.prod.env 103 | } 104 | }), 105 | /* 106 | * Plugin: UglifyJsPlugin 107 | * Description: Minimize all JavaScript output of chunks. 108 | * Loaders are switched into minimizing mode. 109 | * 110 | * See: https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin 111 | */ 112 | ...generateMultipleEntrys(commonConfig[0].entry), 113 | /* 114 | * Plugin: HtmlWebpackPlugin 115 | * Description: Simplifies creation of HTML files to serve your webpack bundles. 116 | * This is especially useful for webpack bundles that include a hash in the filename 117 | * which changes every compilation. 118 | * 119 | * See: https://github.com/ampedandwired/html-webpack-plugin 120 | */ 121 | new HtmlWebpackPlugin({ 122 | template: 'web/index.html', 123 | chunksSortMode: 'dependency', 124 | inject: 'head' 125 | }), 126 | /* 127 | * Plugin: ScriptExtHtmlWebpackPlugin 128 | * Description: Enhances html-webpack-plugin functionality 129 | * with different deployment options for your scripts including: 130 | * 131 | * See: https://github.com/numical/script-ext-html-webpack-plugin 132 | */ 133 | new ScriptExtHtmlWebpackPlugin({ 134 | defaultAttribute: 'defer' 135 | }), 136 | /* 137 | * Plugin: UglifyJsparallelPlugin 138 | * Description: Identical to standard uglify webpack plugin 139 | * with an option to build multiple files in parallel 140 | * 141 | * See: https://www.npmjs.com/package/webpack-uglify-parallel 142 | */ 143 | new UglifyJsparallelPlugin({ 144 | workers: os.cpus().length, 145 | mangle: true, 146 | compressor: { 147 | warnings: false, 148 | drop_console: true, 149 | drop_debugger: true 150 | } 151 | }) 152 | ] 153 | }); 154 | 155 | /** 156 | * Webpack configuration for weex. 157 | */ 158 | const weexConfig = webpackMerge(commonConfig[1], { 159 | /** 160 | * Options affecting the output of the compilation. 161 | * 162 | * See: http://webpack.github.io/docs/configuration.html#output 163 | */ 164 | output: { 165 | /** 166 | * The output directory as absolute path (required). 167 | * 168 | * See: http://webpack.github.io/docs/configuration.html#output-path 169 | */ 170 | path: helper.rootNode('dist'), 171 | /** 172 | * Specifies the name of each output file on disk. 173 | * IMPORTANT: You must not specify an absolute path here! 174 | * 175 | * See: http://webpack.github.io/docs/configuration.html#output-filename 176 | */ 177 | filename: '[name].js' 178 | }, 179 | /* 180 | * Add additional plugins to the compiler. 181 | * 182 | * See: http://webpack.github.io/docs/configuration.html#plugins 183 | */ 184 | plugins: [ 185 | /** 186 | * Plugin: webpack.DefinePlugin 187 | * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. 188 | * 189 | * See: https://webpack.js.org/plugins/define-plugin/ 190 | */ 191 | new webpack.DefinePlugin({ 192 | 'process.env': { 193 | 'NODE_ENV': config.prod.env 194 | } 195 | }), 196 | /* 197 | * Plugin: UglifyJsparallelPlugin 198 | * Description: Identical to standard uglify webpack plugin 199 | * with an option to build multiple files in parallel 200 | * 201 | * See: https://www.npmjs.com/package/webpack-uglify-parallel 202 | */ 203 | new UglifyJsparallelPlugin({ 204 | workers: os.cpus().length, 205 | mangle: true, 206 | compressor: { 207 | warnings: false, 208 | drop_console: true, 209 | drop_debugger: true 210 | } 211 | }) 212 | ] 213 | }) 214 | 215 | module.exports = productionConfig 216 | -------------------------------------------------------------------------------- /weex/configs/webpack.common.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | const webpack = require('webpack'); 4 | const config = require('./config'); 5 | const helper = require('./helper'); 6 | const glob = require('glob'); 7 | const vueLoaderConfig = require('./vue-loader.conf'); 8 | const vueWebTemp = helper.rootNode(config.templateDir); 9 | const hasPluginInstalled = fs.existsSync(helper.rootNode(config.pluginFilePath)); 10 | const isWin = /^win/.test(process.platform); 11 | const weexEntry = { 12 | 'index': helper.root('entry.js') 13 | } 14 | 15 | const getEntryFileContent = (source, routerpath) => { 16 | let dependence = `import Vue from 'vue'\n`; 17 | dependence += `import weex from 'weex-vue-render'\n`; 18 | let relativePluginPath = helper.rootNode(config.pluginFilePath); 19 | let entryContents = fs.readFileSync(source).toString(); 20 | let contents = ''; 21 | entryContents = dependence + entryContents; 22 | entryContents = entryContents.replace(/\/\* weex initialized/, match => `weex.init(Vue)\n${match}`); 23 | if (isWin) { 24 | relativePluginPath = relativePluginPath.replace(/\\/g, '\\\\'); 25 | } 26 | if (hasPluginInstalled) { 27 | contents += `\n// If detact plugins/plugin.js is exist, import and the plugin.js\n`; 28 | contents += `import plugins from '${relativePluginPath}';\n`; 29 | contents += `plugins.forEach(function (plugin) {\n\tweex.install(plugin)\n});\n\n`; 30 | entryContents = entryContents.replace(/\.\/router/, routerpath); 31 | entryContents = entryContents.replace(/weex\.init/, match => `${contents}${match}`); 32 | } 33 | return entryContents; 34 | } 35 | 36 | const getRouterFileContent = (source) => { 37 | const dependence = `import Vue from 'vue'\n`; 38 | let routerContents = fs.readFileSync(source).toString(); 39 | routerContents = dependence + routerContents; 40 | return routerContents; 41 | } 42 | 43 | const getEntryFile = () => { 44 | const entryFile = path.join(vueWebTemp, config.entryFilePath) 45 | const routerFile = path.join(vueWebTemp, config.routerFilePath) 46 | fs.outputFileSync(entryFile, getEntryFileContent(helper.root(config.entryFilePath), routerFile)); 47 | fs.outputFileSync(routerFile, getRouterFileContent(helper.root(config.routerFilePath))); 48 | return { 49 | index: entryFile 50 | } 51 | } 52 | 53 | // The entry file for web needs to add some library. such as vue, weex-vue-render 54 | // 1. src/entry.js 55 | // import Vue from 'vue'; 56 | // import weex from 'weex-vue-render'; 57 | // weex.init(Vue); 58 | // 2. src/router/index.js 59 | // import Vue from 'vue' 60 | const webEntry = getEntryFile(); 61 | 62 | 63 | const createLintingRule = () => ({ 64 | test: /\.(js|vue)$/, 65 | loader: 'eslint-loader', 66 | enforce: 'pre', 67 | include: [helper.rootNode('src'), helper.rootNode('test')], 68 | options: { 69 | formatter: require('eslint-friendly-formatter'), 70 | emitWarning: !config.dev.showEslintErrorsInOverlay 71 | } 72 | }) 73 | const useEslint = config.dev.useEslint ? [createLintingRule()] : [] 74 | 75 | /** 76 | * Plugins for webpack configuration. 77 | */ 78 | const plugins = [ 79 | /** 80 | * Plugin: webpack.DefinePlugin 81 | * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. 82 | * 83 | * See: https://webpack.js.org/plugins/define-plugin/ 84 | */ 85 | new webpack.DefinePlugin({ 86 | 'process.env': { 87 | 'NODE_ENV': config.dev.env 88 | } 89 | }), 90 | /* 91 | * Plugin: BannerPlugin 92 | * Description: Adds a banner to the top of each generated chunk. 93 | * See: https://webpack.js.org/plugins/banner-plugin/ 94 | */ 95 | new webpack.BannerPlugin({ 96 | banner: '// { "framework": "Vue"} \n', 97 | raw: true, 98 | exclude: 'Vue' 99 | }) 100 | ]; 101 | 102 | // Config for compile jsbundle for web. 103 | const webConfig = { 104 | entry: Object.assign(webEntry, { 105 | 'vendor': [path.resolve('node_modules/phantom-limb/index.js')] 106 | }), 107 | output: { 108 | path: helper.rootNode('./dist'), 109 | filename: '[name].web.js' 110 | }, 111 | /** 112 | * Options affecting the resolving of modules. 113 | * See http://webpack.github.io/docs/configuration.html#resolve 114 | */ 115 | resolve: { 116 | extensions: ['.js', '.vue', '.json'], 117 | alias: { 118 | '@': helper.resolve('src') 119 | } 120 | }, 121 | /* 122 | * Options affecting the resolving of modules. 123 | * 124 | * See: http://webpack.github.io/docs/configuration.html#module 125 | */ 126 | module: { 127 | // webpack 2.0 128 | rules: useEslint.concat([ 129 | { 130 | test: /\.js$/, 131 | use: [{ 132 | loader: 'babel-loader' 133 | }], 134 | exclude: config.excludeModuleReg 135 | }, 136 | { 137 | test: /\.vue(\?[^?]+)?$/, 138 | use: [{ 139 | loader: 'vue-loader', 140 | options: Object.assign(vueLoaderConfig({useVue: true, usePostCSS: false}), { 141 | /** 142 | * important! should use postTransformNode to add $processStyle for 143 | * inline style prefixing. 144 | */ 145 | optimizeSSR: false, 146 | postcss: [ 147 | // to convert weex exclusive styles. 148 | require('postcss-plugin-weex')(), 149 | require('autoprefixer')({ 150 | browsers: ['> 0.1%', 'ios >= 8', 'not ie < 12'] 151 | }), 152 | require('postcss-plugin-px2rem')({ 153 | // base on 750px standard. 154 | rootValue: 75, 155 | // to leave 1px alone. 156 | minPixelValue: 1.01 157 | }) 158 | ], 159 | compilerModules: [ 160 | { 161 | postTransformNode: el => { 162 | // to convert vnode for weex components. 163 | require('weex-vue-precompiler')()(el) 164 | } 165 | } 166 | ] 167 | 168 | }) 169 | }], 170 | exclude: config.excludeModuleReg 171 | } 172 | ]) 173 | }, 174 | /* 175 | * Add additional plugins to the compiler. 176 | * 177 | * See: http://webpack.github.io/docs/configuration.html#plugins 178 | */ 179 | plugins: plugins 180 | }; 181 | // Config for compile jsbundle for native. 182 | const weexConfig = { 183 | entry: weexEntry, 184 | output: { 185 | path: path.join(__dirname, '../dist'), 186 | filename: '[name].js' 187 | }, 188 | /** 189 | * Options affecting the resolving of modules. 190 | * See http://webpack.github.io/docs/configuration.html#resolve 191 | */ 192 | resolve: { 193 | extensions: ['.js', '.vue', '.json'], 194 | alias: { 195 | '@': helper.resolve('src') 196 | } 197 | }, 198 | /* 199 | * Options affecting the resolving of modules. 200 | * 201 | * See: http://webpack.github.io/docs/configuration.html#module 202 | */ 203 | module: { 204 | rules: [ 205 | { 206 | test: /\.js$/, 207 | use: [{ 208 | loader: 'babel-loader' 209 | }], 210 | exclude: config.excludeModuleReg 211 | }, 212 | { 213 | test: /\.vue(\?[^?]+)?$/, 214 | use: [{ 215 | loader: 'weex-loader', 216 | options: vueLoaderConfig({useVue: false}) 217 | }], 218 | exclude: config.excludeModuleReg 219 | } 220 | ] 221 | }, 222 | /* 223 | * Add additional plugins to the compiler. 224 | * 225 | * See: http://webpack.github.io/docs/configuration.html#plugins 226 | */ 227 | plugins: plugins, 228 | /* 229 | * Include polyfills or mocks for various node stuff 230 | * Description: Node configuration 231 | * 232 | * See: https://webpack.github.io/docs/configuration.html#node 233 | */ 234 | node: config.nodeConfiguration 235 | }; 236 | 237 | module.exports = [webConfig, weexConfig]; 238 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/WXPageActivity.java: -------------------------------------------------------------------------------- 1 | package com.weex.app; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.v4.content.LocalBroadcastManager; 8 | import android.text.TextUtils; 9 | import android.util.Log; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | import android.widget.ProgressBar; 15 | import android.widget.TextView; 16 | import android.widget.Toast; 17 | 18 | import com.weex.app.hotreload.HotReloadManager; 19 | import com.weex.app.util.AppConfig; 20 | import com.weex.app.util.Constants; 21 | import com.google.zxing.integration.android.IntentIntegrator; 22 | import com.google.zxing.integration.android.IntentResult; 23 | import com.taobao.weex.WXEnvironment; 24 | import com.taobao.weex.WXSDKEngine; 25 | import com.taobao.weex.WXSDKInstance; 26 | import com.taobao.weex.ui.component.NestedContainer; 27 | import com.taobao.weex.utils.WXLogUtils; 28 | import com.taobao.weex.utils.WXSoInstallMgrSdk; 29 | import com.taobao.weex.common.WXErrorCode; 30 | 31 | import org.json.JSONException; 32 | import org.json.JSONObject; 33 | 34 | 35 | public class WXPageActivity extends AbsWeexActivity implements 36 | WXSDKInstance.NestedInstanceInterceptor { 37 | 38 | private static final String TAG = "WXPageActivity"; 39 | private ProgressBar mProgressBar; 40 | private TextView mTipView; 41 | private boolean mFromSplash = false; 42 | private HotReloadManager mHotReloadManager; 43 | 44 | @Override 45 | public void onCreateNestInstance(WXSDKInstance instance, NestedContainer container) { 46 | Log.d(TAG, "Nested Instance created."); 47 | } 48 | 49 | @Override 50 | protected void onCreate(Bundle savedInstanceState) { 51 | super.onCreate(savedInstanceState); 52 | setContentView(R.layout.activity_wxpage); 53 | mContainer = (ViewGroup) findViewById(R.id.container); 54 | mProgressBar = (ProgressBar) findViewById(R.id.progress); 55 | mTipView = (TextView) findViewById(R.id.index_tip); 56 | 57 | Intent intent = getIntent(); 58 | Uri uri = intent.getData(); 59 | String from = intent.getStringExtra("from"); 60 | mFromSplash = "splash".equals(from); 61 | 62 | if (uri == null) { 63 | uri = Uri.parse("{}"); 64 | } 65 | if (uri != null) { 66 | try { 67 | JSONObject initData = new JSONObject(uri.toString()); 68 | String bundleUrl = initData.optString("WeexBundle", null); 69 | if (bundleUrl != null) { 70 | mUri = Uri.parse(bundleUrl); 71 | } 72 | 73 | String ws = initData.optString("Ws", null); 74 | if (!TextUtils.isEmpty(ws)) { 75 | mHotReloadManager = new HotReloadManager(ws, new HotReloadManager.ActionListener() { 76 | @Override 77 | public void reload() { 78 | runOnUiThread(new Runnable() { 79 | @Override 80 | public void run() { 81 | Toast.makeText(WXPageActivity.this, "Hot reload", Toast.LENGTH_SHORT).show(); 82 | createWeexInstance(); 83 | renderPage(); 84 | } 85 | }); 86 | } 87 | 88 | @Override 89 | public void render(final String bundleUrl) { 90 | runOnUiThread(new Runnable() { 91 | @Override 92 | public void run() { 93 | Toast.makeText(WXPageActivity.this, "Render: " + bundleUrl, Toast.LENGTH_SHORT).show(); 94 | createWeexInstance(); 95 | loadUrl(bundleUrl); 96 | } 97 | }); 98 | } 99 | }); 100 | } else { 101 | WXLogUtils.w("Weex", "can not get hot reload config"); 102 | } 103 | } catch (JSONException e) { 104 | e.printStackTrace(); 105 | } 106 | } 107 | 108 | if (mUri == null) { 109 | mUri = Uri.parse(AppConfig.getLaunchUrl()); 110 | } 111 | 112 | if (!WXSoInstallMgrSdk.isCPUSupport()) { 113 | mProgressBar.setVisibility(View.INVISIBLE); 114 | mTipView.setText(R.string.cpu_not_support_tip); 115 | return; 116 | } 117 | 118 | String url = getUrl(mUri); 119 | if (getSupportActionBar() != null) { 120 | getSupportActionBar().setTitle(url); 121 | getSupportActionBar().hide(); 122 | } 123 | loadUrl(url); 124 | } 125 | 126 | private String getUrl(Uri uri) { 127 | String url = uri.toString(); 128 | String scheme = uri.getScheme(); 129 | if (uri.isHierarchical()) { 130 | if (TextUtils.equals(scheme, "http") || TextUtils.equals(scheme, "https")) { 131 | String weexTpl = uri.getQueryParameter(Constants.WEEX_TPL_KEY); 132 | if (!TextUtils.isEmpty(weexTpl)) { 133 | url = weexTpl; 134 | } 135 | } 136 | } 137 | return url; 138 | } 139 | 140 | protected void preRenderPage() { 141 | mProgressBar.setVisibility(View.VISIBLE); 142 | } 143 | 144 | @Override 145 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 146 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 147 | Intent intent = new Intent("requestPermission"); 148 | intent.putExtra("REQUEST_PERMISSION_CODE", requestCode); 149 | intent.putExtra("permissions", permissions); 150 | intent.putExtra("grantResults", grantResults); 151 | LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 152 | } 153 | 154 | 155 | @Override 156 | public void onRenderSuccess(WXSDKInstance instance, int width, int height) { 157 | mProgressBar.setVisibility(View.GONE); 158 | mTipView.setVisibility(View.GONE); 159 | } 160 | 161 | @Override 162 | public void onException(WXSDKInstance instance, String errCode, String msg) { 163 | mProgressBar.setVisibility(View.GONE); 164 | mTipView.setVisibility(View.VISIBLE); 165 | if (TextUtils.equals(errCode, WXErrorCode.WX_DEGRAD_ERR_NETWORK_CHECK_CONTENT_LENGTH_FAILED.getErrorCode())) { 166 | mTipView.setText(R.string.index_tip); 167 | } else { 168 | mTipView.setText("render error:" + errCode); 169 | } 170 | } 171 | 172 | @Override 173 | public boolean onCreateOptionsMenu(Menu menu) { 174 | getMenuInflater().inflate(mFromSplash ? R.menu.main_scan : R.menu.main, menu); 175 | return super.onCreateOptionsMenu(menu); 176 | } 177 | 178 | @Override 179 | public boolean onOptionsItemSelected(MenuItem item) { 180 | switch (item.getItemId()) { 181 | case R.id.action_refresh: 182 | createWeexInstance(); 183 | renderPage(); 184 | break; 185 | case R.id.action_scan: 186 | IntentIntegrator integrator = new IntentIntegrator(this); 187 | integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES); 188 | integrator.setPrompt("Scan a barcode"); 189 | //integrator.setCameraId(0); // Use a specific camera of the device 190 | integrator.setBeepEnabled(true); 191 | integrator.setOrientationLocked(false); 192 | integrator.setBarcodeImageEnabled(true); 193 | integrator.setPrompt(getString(R.string.capture_qrcode_prompt)); 194 | integrator.initiateScan(); 195 | break; 196 | case android.R.id.home: 197 | finish(); 198 | default: 199 | break; 200 | } 201 | 202 | return super.onOptionsItemSelected(item); 203 | } 204 | 205 | @Override 206 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 207 | IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); 208 | if (result != null) { 209 | if (result.getContents() == null) { 210 | Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show(); 211 | } else { 212 | handleDecodeInternally(result.getContents()); 213 | } 214 | } 215 | super.onActivityResult(requestCode, resultCode, data); 216 | } 217 | 218 | // Put up our own UI for how to handle the decoded contents. 219 | private void handleDecodeInternally(String code) { 220 | if (!TextUtils.isEmpty(code)) { 221 | Uri uri = Uri.parse(code); 222 | if (uri.getPath().contains("dynamic/replace")) { 223 | Intent intent = new Intent("weex.intent.action.dynamic", uri); 224 | intent.addCategory("weex.intent.category.dynamic"); 225 | startActivity(intent); 226 | finish(); 227 | } else if (uri.getQueryParameterNames().contains("_wx_devtool")) { 228 | WXEnvironment.sRemoteDebugProxyUrl = uri.getQueryParameter("_wx_devtool"); 229 | WXEnvironment.sDebugServerConnectable = true; 230 | WXSDKEngine.reload(); 231 | Toast.makeText(this, "devtool", Toast.LENGTH_SHORT).show(); 232 | finish(); 233 | return; 234 | } else { 235 | JSONObject data = new JSONObject(); 236 | try { 237 | data.put("WeexBundle", Uri.parse(code).toString()); 238 | Intent intent = new Intent(WXPageActivity.this, WXPageActivity.class); 239 | intent.setData(Uri.parse(data.toString())); 240 | startActivity(intent); 241 | } catch (JSONException e) { 242 | e.printStackTrace(); 243 | } 244 | } 245 | } 246 | } 247 | 248 | @Override 249 | public void onDestroy() { 250 | super.onDestroy(); 251 | if (mHotReloadManager != null) { 252 | mHotReloadManager.destroy(); 253 | } 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /weex/platforms/android/app/src/main/java/com/weex/app/extend/BlurTool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.weex.app.extend; 20 | 21 | import android.graphics.Bitmap; 22 | import android.support.annotation.NonNull; 23 | import android.support.annotation.Nullable; 24 | 25 | import com.taobao.weex.utils.WXLogUtils; 26 | 27 | import java.util.concurrent.ExecutorService; 28 | import java.util.concurrent.Executors; 29 | import java.util.concurrent.ThreadFactory; 30 | 31 | /** 32 | * Created by rowandjj(chuyi) 33 | */ 34 | 35 | public class BlurTool { 36 | 37 | public interface OnBlurCompleteListener { 38 | /** 39 | * blur complete event.(Notice:in sub thread) 40 | * 41 | * @param bitmap the blurred bitmap 42 | * */ 43 | void onBlurComplete(@NonNull Bitmap bitmap); 44 | } 45 | 46 | private static ExecutorService sExecutorService = Executors.newCachedThreadPool(new ThreadFactory() { 47 | @Override 48 | public Thread newThread(Runnable r) { 49 | return new Thread(r,"wx_blur_thread"); 50 | } 51 | }); 52 | 53 | private static final String TAG = "BlurTool"; 54 | 55 | /** 56 | * radius in [0,10] 57 | * */ 58 | @NonNull 59 | @SuppressWarnings("unused") 60 | public static Bitmap blur(@NonNull Bitmap originalImage, int radius) { 61 | long start = System.currentTimeMillis(); 62 | radius = Math.min(10, Math.max(0,radius));//[0,10] 63 | if(radius == 0) { 64 | return originalImage; 65 | } 66 | int width = originalImage.getWidth(); 67 | int height = originalImage.getHeight(); 68 | 69 | if(width <= 0 || height <= 0) { 70 | return originalImage; 71 | } 72 | 73 | double sampling = calculateSampling(radius); 74 | int retryTimes = 3; 75 | Bitmap sampledImage = Bitmap.createScaledBitmap(originalImage,(int)(sampling*width),(int)(sampling*height),true); 76 | for(int i = 0; i < retryTimes; i++) { 77 | try { 78 | if(radius == 0) { 79 | return originalImage; 80 | } 81 | double s = calculateSampling(radius); 82 | if(s != sampling) { 83 | sampling = s; 84 | sampledImage = Bitmap.createScaledBitmap(originalImage,(int)(sampling*width),(int)(sampling*height),true); 85 | } 86 | 87 | Bitmap result = stackBlur(sampledImage,radius); 88 | WXLogUtils.d(TAG, "elapsed time on blurring image(radius:"+ radius + ",sampling: " + sampling + "): " + (System.currentTimeMillis() - start) + "ms"); 89 | return result; 90 | }catch (Exception e) { 91 | WXLogUtils.e(TAG, "thrown exception when blurred image(times = " + i + "),"+ e.getMessage()); 92 | radius -= 1; 93 | radius = Math.max(0,radius); 94 | } 95 | } 96 | WXLogUtils.d(TAG, "elapsed time on blurring image(radius:"+ radius + ",sampling: " + sampling + "): " + (System.currentTimeMillis() - start) + "ms"); 97 | return originalImage; 98 | } 99 | 100 | private static double calculateSampling(int radius){ 101 | double sampling; 102 | if(radius <= 3) { 103 | sampling = 1/(double)2; 104 | }else if(radius <= 8) { 105 | sampling = 1/(double)4; 106 | }else { 107 | sampling = 1/(double)8; 108 | } 109 | 110 | return sampling; 111 | } 112 | 113 | @SuppressWarnings("unused") 114 | public static void asyncBlur(@NonNull final Bitmap originalImage, final int radius, @Nullable final OnBlurCompleteListener listener) { 115 | sExecutorService.execute(new Runnable() { 116 | @Override 117 | public void run() { 118 | if(listener != null) { 119 | listener.onBlurComplete(blur(originalImage,radius)); 120 | } 121 | } 122 | }); 123 | } 124 | 125 | private static Bitmap stackBlur(Bitmap sentBitmap, int radius) { 126 | // Stack Blur Algorithm by Mario Klingemann 127 | Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); 128 | 129 | if (radius < 1) { 130 | return (null); 131 | } 132 | 133 | int w = bitmap.getWidth(); 134 | int h = bitmap.getHeight(); 135 | 136 | int[] pix = new int[w * h]; 137 | bitmap.getPixels(pix, 0, w, 0, 0, w, h); 138 | 139 | int wm = w - 1; 140 | int hm = h - 1; 141 | int wh = w * h; 142 | int div = radius + radius + 1; 143 | 144 | int r[] = new int[wh]; 145 | int g[] = new int[wh]; 146 | int b[] = new int[wh]; 147 | int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; 148 | int vmin[] = new int[Math.max(w, h)]; 149 | 150 | int divsum = (div + 1) >> 1; 151 | divsum *= divsum; 152 | int dv[] = new int[256 * divsum]; 153 | for (i = 0; i < 256 * divsum; i++) { 154 | dv[i] = (i / divsum); 155 | } 156 | 157 | yw = yi = 0; 158 | 159 | int[][] stack = new int[div][3]; 160 | int stackpointer; 161 | int stackstart; 162 | int[] sir; 163 | int rbs; 164 | int r1 = radius + 1; 165 | int routsum, goutsum, boutsum; 166 | int rinsum, ginsum, binsum; 167 | 168 | for (y = 0; y < h; y++) { 169 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 170 | for (i = -radius; i <= radius; i++) { 171 | p = pix[yi + Math.min(wm, Math.max(i, 0))]; 172 | sir = stack[i + radius]; 173 | sir[0] = (p & 0xff0000) >> 16; 174 | sir[1] = (p & 0x00ff00) >> 8; 175 | sir[2] = (p & 0x0000ff); 176 | rbs = r1 - Math.abs(i); 177 | rsum += sir[0] * rbs; 178 | gsum += sir[1] * rbs; 179 | bsum += sir[2] * rbs; 180 | if (i > 0) { 181 | rinsum += sir[0]; 182 | ginsum += sir[1]; 183 | binsum += sir[2]; 184 | } else { 185 | routsum += sir[0]; 186 | goutsum += sir[1]; 187 | boutsum += sir[2]; 188 | } 189 | } 190 | stackpointer = radius; 191 | 192 | for (x = 0; x < w; x++) { 193 | 194 | r[yi] = dv[rsum]; 195 | g[yi] = dv[gsum]; 196 | b[yi] = dv[bsum]; 197 | 198 | rsum -= routsum; 199 | gsum -= goutsum; 200 | bsum -= boutsum; 201 | 202 | stackstart = stackpointer - radius + div; 203 | sir = stack[stackstart % div]; 204 | 205 | routsum -= sir[0]; 206 | goutsum -= sir[1]; 207 | boutsum -= sir[2]; 208 | 209 | if (y == 0) { 210 | vmin[x] = Math.min(x + radius + 1, wm); 211 | } 212 | p = pix[yw + vmin[x]]; 213 | 214 | sir[0] = (p & 0xff0000) >> 16; 215 | sir[1] = (p & 0x00ff00) >> 8; 216 | sir[2] = (p & 0x0000ff); 217 | 218 | rinsum += sir[0]; 219 | ginsum += sir[1]; 220 | binsum += sir[2]; 221 | 222 | rsum += rinsum; 223 | gsum += ginsum; 224 | bsum += binsum; 225 | 226 | stackpointer = (stackpointer + 1) % div; 227 | sir = stack[(stackpointer) % div]; 228 | 229 | routsum += sir[0]; 230 | goutsum += sir[1]; 231 | boutsum += sir[2]; 232 | 233 | rinsum -= sir[0]; 234 | ginsum -= sir[1]; 235 | binsum -= sir[2]; 236 | 237 | yi++; 238 | } 239 | yw += w; 240 | } 241 | for (x = 0; x < w; x++) { 242 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; 243 | yp = -radius * w; 244 | for (i = -radius; i <= radius; i++) { 245 | yi = Math.max(0, yp) + x; 246 | 247 | sir = stack[i + radius]; 248 | 249 | sir[0] = r[yi]; 250 | sir[1] = g[yi]; 251 | sir[2] = b[yi]; 252 | 253 | rbs = r1 - Math.abs(i); 254 | 255 | rsum += r[yi] * rbs; 256 | gsum += g[yi] * rbs; 257 | bsum += b[yi] * rbs; 258 | 259 | if (i > 0) { 260 | rinsum += sir[0]; 261 | ginsum += sir[1]; 262 | binsum += sir[2]; 263 | } else { 264 | routsum += sir[0]; 265 | goutsum += sir[1]; 266 | boutsum += sir[2]; 267 | } 268 | 269 | if (i < hm) { 270 | yp += w; 271 | } 272 | } 273 | yi = x; 274 | stackpointer = radius; 275 | for (y = 0; y < h; y++) { 276 | // Preserve alpha channel: ( 0xff000000 & pix[yi] ) 277 | pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]; 278 | 279 | rsum -= routsum; 280 | gsum -= goutsum; 281 | bsum -= boutsum; 282 | 283 | stackstart = stackpointer - radius + div; 284 | sir = stack[stackstart % div]; 285 | 286 | routsum -= sir[0]; 287 | goutsum -= sir[1]; 288 | boutsum -= sir[2]; 289 | 290 | if (x == 0) { 291 | vmin[y] = Math.min(y + r1, hm) * w; 292 | } 293 | p = x + vmin[y]; 294 | 295 | sir[0] = r[p]; 296 | sir[1] = g[p]; 297 | sir[2] = b[p]; 298 | 299 | rinsum += sir[0]; 300 | ginsum += sir[1]; 301 | binsum += sir[2]; 302 | 303 | rsum += rinsum; 304 | gsum += ginsum; 305 | bsum += binsum; 306 | 307 | stackpointer = (stackpointer + 1) % div; 308 | sir = stack[stackpointer]; 309 | 310 | routsum += sir[0]; 311 | goutsum += sir[1]; 312 | boutsum += sir[2]; 313 | 314 | rinsum -= sir[0]; 315 | ginsum -= sir[1]; 316 | binsum -= sir[2]; 317 | 318 | yi += w; 319 | } 320 | } 321 | 322 | bitmap.setPixels(pix, 0, w, 0, 0, w, h); 323 | 324 | return (bitmap); 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /weex/platforms/android/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2016 Alibaba Group 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /weex/src/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 重置 4 | 自动 5 | 10 | {{puzzle}} 17 | 18 | 19 | 20 | 21 | 302 | 303 | 334 | -------------------------------------------------------------------------------- /weex/src/components/game.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 重置 4 | 自动 5 | 10 | 17 | 18 | 19 | 20 | 21 | 297 | 298 | -------------------------------------------------------------------------------- /vue/src/components/auto.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 重置 4 | 自动 5 | 10 | 17 | 18 | 19 | 20 | 21 | 302 | 303 | 341 | --------------------------------------------------------------------------------
Use Weex playground app to scan it.