├── static ├── .gitkeep ├── iMini.html ├── iMini │ └── iMini.html └── iMini.js ├── .eslintignore ├── config ├── prod.env.js ├── test.env.js ├── dev.env.js └── index.js ├── src ├── assets │ └── logo.png ├── main.js ├── App.vue └── components │ └── Drawable.vue ├── docs ├── static │ ├── iMini.html │ ├── css │ │ ├── app.a7b3de5514b8225a660eb61806377566.css │ │ └── app.a7b3de5514b8225a660eb61806377566.css.map │ ├── iMini │ │ └── iMini.html │ ├── js │ │ ├── manifest.8fa62b3495deffb9e96e.js │ │ ├── manifest.8fa62b3495deffb9e96e.js.map │ │ ├── app.0ae67d59941939740643.js │ │ └── app.0ae67d59941939740643.js.map │ └── iMini.js └── index.html ├── .gitignore ├── test └── unit │ ├── .eslintrc │ ├── specs │ └── Hello.spec.js │ ├── index.js │ └── karma.conf.js ├── .editorconfig ├── .postcssrc.js ├── .babelrc ├── index.html ├── README.md ├── .eslintrc.js └── package.json /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /static/iMini.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanonepa/vue-draw-canvas/HEAD/static/iMini.html -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanonepa/vue-draw-canvas/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /docs/static/iMini.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanonepa/vue-draw-canvas/HEAD/docs/static/iMini.html -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | test/unit/coverage 8 | -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserlist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false, 8 | "env": { 9 | "test": { 10 | "presets": ["env", "stage-2"], 11 | "plugins": [ "istanbul" ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | 6 | Vue.config.productionTip = false 7 | 8 | /* eslint-disable no-new */ 9 | new Vue({ 10 | el: '#app', 11 | template: '', 12 | components: { App } 13 | }) 14 | -------------------------------------------------------------------------------- /test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Hello from '@/components/Hello' 3 | 4 | describe('Hello.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(Hello) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('.hello h1').textContent) 9 | .to.equal('Welcome to Your Vue.js App') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /docs/static/css/app.a7b3de5514b8225a660eb61806377566.css: -------------------------------------------------------------------------------- 1 | #app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c3e50;margin-top:20px}canvas{border:1px solid #bbb}.flex{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.flex>*{border:1px solid #eee;margin:10px;padding:10px} -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | Vue.config.productionTip = false 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | 9 | // require all src files except main.js for coverage. 10 | // you can also change this to match only the subset of files that 11 | // you want coverage for. 12 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/) 13 | srcContext.keys().forEach(srcContext) 14 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 28 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-draw-canvas 6 | 7 | 8 | 9 |
10 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-draw-canvas 2 | 3 | > A Vue.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | 20 | # run unit tests 21 | npm run unit 22 | 23 | # run all tests 24 | npm test 25 | ``` 26 | 27 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 28 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | vue-draw-canvas
-------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /static/iMini/iMini.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Applet iMini 5 | 6 | 7 | 8 |

Applet iMini

9 | 10 |
11 | 12 | 13 | 14 |
15 | 16 |
17 |
18 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/static/iMini/iMini.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Applet iMini 5 | 6 | 7 | 8 |

Applet iMini

9 | 10 |
11 | 12 | 13 | 14 |
15 | 16 |
17 |
18 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/static/css/app.a7b3de5514b8225a660eb61806377566.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/App.vue","webpack:///./src/components/Drawable.vue"],"names":[],"mappings":"AACA,KACE,8CACA,mCACA,kCACA,cACA,eAAiB,CCLnB,OACE,qBAAsB,CAExB,MACE,oBACA,oBACA,aACA,8BACA,6BACI,uBACI,kBAAoB,CAE9B,QACE,sBACA,YACA,YAAc","file":"static/css/app.a7b3de5514b8225a660eb61806377566.css","sourcesContent":["\n#app {\r\n font-family: 'Avenir', Helvetica, Arial, sans-serif;\r\n -webkit-font-smoothing: antialiased;\r\n -moz-osx-font-smoothing: grayscale;\r\n color: #2c3e50;\r\n margin-top: 20px;\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/App.vue","\ncanvas {\n border:1px solid #bbb;\n}\n.flex{\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n}\n.flex > * {\n border: 1px solid #eee;\n margin: 10px;\n padding: 10px;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/Drawable.vue"],"sourceRoot":""} -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var webpackConfig = require('../../build/webpack.test.conf') 7 | 8 | module.exports = function (config) { 9 | config.set({ 10 | // to run in additional browsers: 11 | // 1. install corresponding karma launcher 12 | // http://karma-runner.github.io/0.13/config/browsers.html 13 | // 2. add it to the `browsers` array below. 14 | browsers: ['PhantomJS'], 15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], 16 | reporters: ['spec', 'coverage'], 17 | files: ['./index.js'], 18 | preprocessors: { 19 | './index.js': ['webpack', 'sourcemap'] 20 | }, 21 | webpack: webpackConfig, 22 | webpackMiddleware: { 23 | noInfo: true 24 | }, 25 | coverageReporter: { 26 | dir: './coverage', 27 | reporters: [ 28 | { type: 'lcov', subdir: '.' }, 29 | { type: 'text-summary' } 30 | ] 31 | } 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /docs/static/js/manifest.8fa62b3495deffb9e96e.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,i){for(var u,a,f,s=0,l=[];s", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 12 | "test": "npm run unit", 13 | "lint": "eslint --ext .js,.vue src test/unit/specs" 14 | }, 15 | "dependencies": { 16 | "vue": "^2.3.3" 17 | }, 18 | "devDependencies": { 19 | "autoprefixer": "^6.7.2", 20 | "babel-core": "^6.22.1", 21 | "babel-eslint": "^7.1.1", 22 | "babel-loader": "^6.2.10", 23 | "babel-plugin-istanbul": "^4.1.1", 24 | "babel-plugin-transform-runtime": "^6.22.0", 25 | "babel-preset-env": "^1.3.2", 26 | "babel-preset-stage-2": "^6.22.0", 27 | "babel-register": "^6.22.0", 28 | "chai": "^3.5.0", 29 | "chalk": "^1.1.3", 30 | "connect-history-api-fallback": "^1.3.0", 31 | "copy-webpack-plugin": "^4.0.1", 32 | "cross-env": "^4.0.0", 33 | "css-loader": "^0.28.0", 34 | "eslint": "^3.19.0", 35 | "eslint-config-standard": "^6.2.1", 36 | "eslint-friendly-formatter": "^2.0.7", 37 | "eslint-loader": "^1.7.1", 38 | "eslint-plugin-html": "^2.0.0", 39 | "eslint-plugin-promise": "^3.4.0", 40 | "eslint-plugin-standard": "^2.0.1", 41 | "eventsource-polyfill": "^0.9.6", 42 | "express": "^4.14.1", 43 | "extract-text-webpack-plugin": "^2.0.0", 44 | "file-loader": "^0.11.1", 45 | "friendly-errors-webpack-plugin": "^1.1.3", 46 | "html-webpack-plugin": "^2.28.0", 47 | "http-proxy-middleware": "^0.17.3", 48 | "inject-loader": "^3.0.0", 49 | "karma": "^1.4.1", 50 | "karma-coverage": "^1.1.1", 51 | "karma-mocha": "^1.3.0", 52 | "karma-phantomjs-launcher": "^1.0.2", 53 | "karma-phantomjs-shim": "^1.4.0", 54 | "karma-sinon-chai": "^1.3.1", 55 | "karma-sourcemap-loader": "^0.3.7", 56 | "karma-spec-reporter": "0.0.30", 57 | "karma-webpack": "^2.0.2", 58 | "lolex": "^1.5.2", 59 | "mocha": "^3.2.0", 60 | "opn": "^4.0.2", 61 | "optimize-css-assets-webpack-plugin": "^1.3.0", 62 | "ora": "^1.2.0", 63 | "phantomjs-prebuilt": "^2.1.14", 64 | "push-dir": "0.4.1", 65 | "rimraf": "^2.6.0", 66 | "semver": "^5.3.0", 67 | "shelljs": "^0.7.6", 68 | "sinon": "^2.1.0", 69 | "sinon-chai": "^2.8.0", 70 | "url-loader": "^0.5.8", 71 | "vue-loader": "^12.1.0", 72 | "vue-style-loader": "^3.0.1", 73 | "vue-template-compiler": "^2.3.3", 74 | "webpack": "^2.6.1", 75 | "webpack-bundle-analyzer": "^2.2.1", 76 | "webpack-dev-middleware": "^1.10.0", 77 | "webpack-hot-middleware": "^2.18.0", 78 | "webpack-merge": "^4.1.0" 79 | }, 80 | "engines": { 81 | "node": ">= 4.0.0", 82 | "npm": ">= 3.0.0" 83 | }, 84 | "browserslist": [ 85 | "> 1%", 86 | "last 2 versions", 87 | "not ie <= 8" 88 | ] 89 | } 90 | -------------------------------------------------------------------------------- /src/components/Drawable.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 218 | 232 | -------------------------------------------------------------------------------- /docs/static/js/manifest.8fa62b3495deffb9e96e.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///static/js/manifest.8fa62b3495deffb9e96e.js","webpack:///webpack/bootstrap 814fded9ea6136eb2a12"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","parentJsonpFunction","window","chunkIds","moreModules","executeModules","chunkId","result","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","shift","s","2","e","onScriptComplete","script","onerror","onload","clearTimeout","timeout","chunk","Error","undefined","installedChunkData","Promise","resolve","promise","reject","head","document","getElementsByTagName","createElement","type","charset","async","nc","setAttribute","src","p","0","1","setTimeout","appendChild","m","c","value","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","oe","err","console","error"],"mappings":"CAAS,SAAUA,GCuCnB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAI,EAAAJ,EACAK,GAAA,EACAH,WAUA,OANAJ,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,GAGAI,EAAAE,GAAA,EAGAF,EAAAD,QA1DA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,GAAAX,GAAAY,EAAAC,EAAAT,EAAA,EAAAU,KACQV,EAAAK,EAAAM,OAAoBX,IAC5BQ,EAAAH,EAAAL,GACAY,EAAAJ,IACAE,EAAAG,KAAAD,EAAAJ,GAAA,IAEAI,EAAAJ,GAAA,CAEA,KAAAZ,IAAAU,GACAQ,OAAAC,UAAAC,eAAAd,KAAAI,EAAAV,KACAF,EAAAE,GAAAU,EAAAV,GAIA,KADAO,KAAAE,EAAAC,EAAAC,GACAG,EAAAC,QACAD,EAAAO,SAEA,IAAAV,EACA,IAAAP,EAAA,EAAYA,EAAAO,EAAAI,OAA2BX,IACvCS,EAAAd,IAAAuB,EAAAX,EAAAP,GAGA,OAAAS,GAIA,IAAAZ,MAGAe,GACAO,EAAA,EA6BAxB,GAAAyB,EAAA,SAAAZ,GA+BA,QAAAa,KAEAC,EAAAC,QAAAD,EAAAE,OAAA,KACAC,aAAAC,EACA,IAAAC,GAAAf,EAAAJ,EACA,KAAAmB,IACAA,GACAA,EAAA,MAAAC,OAAA,iBAAApB,EAAA,aAEAI,EAAAJ,OAAAqB,IAvCA,GAAAC,GAAAlB,EAAAJ,EACA,QAAAsB,EACA,UAAAC,SAAA,SAAAC,GAA0CA,KAI1C,IAAAF,EACA,MAAAA,GAAA,EAIA,IAAAG,GAAA,GAAAF,SAAA,SAAAC,EAAAE,GACAJ,EAAAlB,EAAAJ,IAAAwB,EAAAE,IAEAJ,GAAA,GAAAG,CAGA,IAAAE,GAAAC,SAAAC,qBAAA,WACAf,EAAAc,SAAAE,cAAA,SACAhB,GAAAiB,KAAA,kBACAjB,EAAAkB,QAAA,QACAlB,EAAAmB,OAAA,EACAnB,EAAAI,QAAA,KAEA/B,EAAA+C,IACApB,EAAAqB,aAAA,QAAAhD,EAAA+C,IAEApB,EAAAsB,IAAAjD,EAAAkD,EAAA,aAAArC,EAAA,KAAwEsC,EAAA,uBAAAC,EAAA,wBAAsDvC,GAAA,KAC9H,IAAAkB,GAAAsB,WAAA3B,EAAA,KAgBA,OAfAC,GAAAC,QAAAD,EAAAE,OAAAH,EAaAc,EAAAc,YAAA3B,GAEAW,GAIAtC,EAAAuD,EAAAxD,EAGAC,EAAAwD,EAAAtD,EAGAF,EAAAK,EAAA,SAAAoD,GAA2C,MAAAA,IAG3CzD,EAAA0D,EAAA,SAAAvD,EAAAwD,EAAAC,GACA5D,EAAA6D,EAAA1D,EAAAwD,IACAxC,OAAA2C,eAAA3D,EAAAwD,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMA5D,EAAAkE,EAAA,SAAA9D,GACA,GAAAwD,GAAAxD,KAAA+D,WACA,WAA2B,MAAA/D,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAJ,GAAA0D,EAAAE,EAAA,IAAAA,GACAA,GAIA5D,EAAA6D,EAAA,SAAAO,EAAAC,GAAsD,MAAAlD,QAAAC,UAAAC,eAAAd,KAAA6D,EAAAC,IAGtDrE,EAAAkD,EAAA,GAGAlD,EAAAsE,GAAA,SAAAC,GAA8D,KAApBC,SAAAC,MAAAF,GAAoBA","file":"static/js/manifest.8fa62b3495deffb9e96e.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId]) {\n/******/ \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n/******/ \t\t\t}\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n/******/ \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n/******/ \t\twhile(resolves.length) {\n/******/ \t\t\tresolves.shift()();\n/******/ \t\t}\n/******/ \t\tif(executeModules) {\n/******/ \t\t\tfor(i=0; i < executeModules.length; i++) {\n/******/ \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\treturn result;\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// objects to store loaded and loading chunks\n/******/ \tvar installedChunks = {\n/******/ \t\t2: 0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId) {\n/******/ \t\tvar installedChunkData = installedChunks[chunkId];\n/******/ \t\tif(installedChunkData === 0) {\n/******/ \t\t\treturn new Promise(function(resolve) { resolve(); });\n/******/ \t\t}\n/******/\n/******/ \t\t// a Promise means \"currently loading\".\n/******/ \t\tif(installedChunkData) {\n/******/ \t\t\treturn installedChunkData[2];\n/******/ \t\t}\n/******/\n/******/ \t\t// setup Promise in chunk cache\n/******/ \t\tvar promise = new Promise(function(resolve, reject) {\n/******/ \t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n/******/ \t\t});\n/******/ \t\tinstalledChunkData[2] = promise;\n/******/\n/******/ \t\t// start chunk loading\n/******/ \t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\tvar script = document.createElement('script');\n/******/ \t\tscript.type = 'text/javascript';\n/******/ \t\tscript.charset = 'utf-8';\n/******/ \t\tscript.async = true;\n/******/ \t\tscript.timeout = 120000;\n/******/\n/******/ \t\tif (__webpack_require__.nc) {\n/******/ \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n/******/ \t\t}\n/******/ \t\tscript.src = __webpack_require__.p + \"static/js/\" + chunkId + \".\" + {\"0\":\"4171f0dd695f31a4fc55\",\"1\":\"0ae67d59941939740643\"}[chunkId] + \".js\";\n/******/ \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n/******/ \t\tscript.onerror = script.onload = onScriptComplete;\n/******/ \t\tfunction onScriptComplete() {\n/******/ \t\t\t// avoid mem leaks in IE.\n/******/ \t\t\tscript.onerror = script.onload = null;\n/******/ \t\t\tclearTimeout(timeout);\n/******/ \t\t\tvar chunk = installedChunks[chunkId];\n/******/ \t\t\tif(chunk !== 0) {\n/******/ \t\t\t\tif(chunk) {\n/******/ \t\t\t\t\tchunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n/******/ \t\t\t\t}\n/******/ \t\t\t\tinstalledChunks[chunkId] = undefined;\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t\thead.appendChild(script);\n/******/\n/******/ \t\treturn promise;\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// on error function for async loading\n/******/ \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n/******/ })\n/************************************************************************/\n/******/ ([]);\n\n\n// WEBPACK FOOTER //\n// static/js/manifest.8fa62b3495deffb9e96e.js"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData === 0) {\n \t\t\treturn new Promise(function(resolve) { resolve(); });\n \t\t}\n\n \t\t// a Promise means \"currently loading\".\n \t\tif(installedChunkData) {\n \t\t\treturn installedChunkData[2];\n \t\t}\n\n \t\t// setup Promise in chunk cache\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunkData[2] = promise;\n\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"static/js/\" + chunkId + \".\" + {\"0\":\"4171f0dd695f31a4fc55\",\"1\":\"0ae67d59941939740643\"}[chunkId] + \".js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) {\n \t\t\t\t\tchunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\t}\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n \t\thead.appendChild(script);\n\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 814fded9ea6136eb2a12"],"sourceRoot":""} -------------------------------------------------------------------------------- /docs/static/js/app.0ae67d59941939740643.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{24:function(t,i,e){function n(t){e(60)}var s=e(23)(e(27),e(64),n,null,null);t.exports=s.exports},26:function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n=e(25),s=e(24),o=e.n(s);n.a.config.productionTip=!1,new n.a({el:"#app",template:"",components:{App:o.a}})},27:function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n=e(62),s=e.n(n);i.default={name:"app",components:{Drawable:s.a}}},28:function(t,i,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n=e(29),s=e.n(n);i.default={mounted:function(){this.canvas=this.$refs.canvas,this.context=this.canvas.getContext("2d"),this.drawAllNodes()},data:function(){return{canvas:{},context:{},canvasHeight:350,canvasWidth:450,overPoint:null,dragMode:!1,pointSize:7,strokeStyle:"darkgrey",fillStyle:"#fff",points:[{x:100,y:100},{x:200,y:100},{x:100,y:200},{x:200,y:200}]}},computed:{},methods:{removePoint:function(t){this.points.splice(t,1),this.clear(),this.drawAllNodes()},matchPoints:function(t,i){return!(i.x>t.x+this.pointSize)&&(!(i.xt.y+this.pointSize)&&!(i.y 10) { 296 | var echelle_new = computeScale(0, curDist, 0, curDist, mouse.startX, mouse.startX + dist, mouse.startY, mouse.startY + dist) 297 | echelle_new.ymin -= curDist 298 | echelle_new.ymax -= curDist 299 | echelle_new.yoff -= curDist 300 | 301 | myData.back_xmin = getRealX(getScreenX(myData.back_xmin), echelle_new) 302 | myData.back_xmax = getRealX(getScreenX(myData.back_xmax), echelle_new) 303 | myData.back_ymin = getRealY(getScreenY(myData.back_ymin), echelle_new) 304 | myData.back_ymax = getRealY(getScreenY(myData.back_ymax), echelle_new) 305 | 306 | for (var i = 0; i < myData.forces.length; i++) { 307 | myData.forces[i].x = getRealX(getScreenX(myData.forces[i].x), echelle_new) 308 | myData.forces[i].y = getRealY(getScreenY(myData.forces[i].y), echelle_new) 309 | } 310 | for (i = 0; i < myData.supports.length; i++) { 311 | myData.supports[i].x = getRealX(getScreenX(myData.supports[i].x), echelle_new) 312 | myData.supports[i].y = getRealY(getScreenY(myData.supports[i].y), echelle_new) 313 | } 314 | for (i = 0; i < myData.tensionLine.length; i++) { 315 | myData.tensionLine[i].x1 = getRealX(getScreenX(myData.tensionLine[i].x1), echelle_new) 316 | myData.tensionLine[i].y1 = getRealY(getScreenY(myData.tensionLine[i].y1), echelle_new) 317 | myData.tensionLine[i].x2 = getRealX(getScreenX(myData.tensionLine[i].x2), echelle_new) 318 | myData.tensionLine[i].y2 = getRealY(getScreenY(myData.tensionLine[i].y2), echelle_new) 319 | } 320 | for (i = 0; i < myData.compressionLine.length; i++) { 321 | myData.compressionLine[i].x1 = getRealX(getScreenX(myData.compressionLine[i].x1), echelle_new) 322 | myData.compressionLine[i].y1 = getRealY(getScreenY(myData.compressionLine[i].y1), echelle_new) 323 | myData.compressionLine[i].x2 = getRealX(getScreenX(myData.compressionLine[i].x2), echelle_new) 324 | myData.compressionLine[i].y2 = getRealY(getScreenY(myData.compressionLine[i].y2), echelle_new) 325 | } 326 | if (myData.subsystem != undefined) { 327 | for (i = 0; i < myData.subsystem.length; i++) { 328 | myData.subsystem[i].x = getRealX(getScreenX(myData.subsystem[i].x), echelle_new) 329 | myData.subsystem[i].y = getRealY(getScreenY(myData.subsystem[i].y), echelle_new) 330 | } 331 | } 332 | echelle = echelle_new 333 | myData.currentForces = getCurrentForces() 334 | myData.currentSupports = getCurrentSupports() 335 | var diff = hbar - hmsg 336 | myData.xmin = getRealX(wbord) 337 | myData.xmax = getRealX(wbord + ecran1.width) 338 | myData.ymin = getRealY(hmsg + ecran1.height + diff) 339 | myData.ymax = getRealY(hmsg + diff) 340 | curMessage = curTexts.getValue('distanceset', '*') + ' ' + arrondi(curDist) 341 | inputChanged = true 342 | curButtons[buttonNumber('scaleimage')].unSet() 343 | mod.mode = undefined 344 | drawAll('') 345 | } else { 346 | curButtons[buttonNumber('scaleimage')].unSet() 347 | mod.mode = undefined 348 | curMessage = curTexts.getValue('distancenotset', '*') 349 | showMessage() 350 | } 351 | break 352 | } // case scaleimage 353 | case (mod.mode == 'subsystem'): { 354 | if(mouse.inScreen1 && mouse.inNewLine) { 355 | // ajouter un nouveau sous-système 356 | num = tempLine.length 357 | tempLine[num] = [] 358 | tempLine[num].x = getRealX(mouse.x) 359 | tempLine[num].y = getRealY(mouse.y) 360 | myData.subsystem = [] 361 | for (i = 0; i <= num; i++) { 362 | myData.subsystem[i] = [] 363 | myData.subsystem[i].x = tempLine[i].x 364 | myData.subsystem[i].y = tempLine[i].y 365 | } 366 | tempLine = undefined 367 | inputChanged = true 368 | mouse.inNewLine = false 369 | } else { 370 | if (myData.subsystem != undefined) { 371 | if (wasInDrag) { 372 | movePolyLine(mouse.x - mouse.startX, mouse.y - mouse.startY, mouse.closestItem) 373 | inputChanged = true 374 | } else { 375 | if ((mouse.closestItem != undefined) && (mouse.closestItem > 0)) { myData.subsystem.selected = !myData.subsystem.selected } 376 | } 377 | } 378 | } 379 | drawAll('lines') 380 | break 381 | } // case subsystem 382 | case ((mod.mode == 'tensionline') || (mod.mode == 'compressionline')): { 383 | if ((mouse.closestItem == undefined) && mouse.inScreen1) { 384 | // ajouter une nouvelle ligne 385 | tempLine.x2 = getRealX(mouse.x) 386 | tempLine.y2 = getRealY(mouse.y) 387 | if (mod.mode == 'tensionline') { 388 | var num = myData.tensionLine.length 389 | myData.tensionLine[num] = tempLine 390 | } 391 | if (mod.mode == 'compressionline') { 392 | var num = myData.compressionLine.length 393 | myData.compressionLine[num] = tempLine 394 | } 395 | inputChanged = true 396 | } else { 397 | if (wasInDrag) { 398 | moveLine(mouse.x - mouse.startX, mouse.y - mouse.startY) 399 | inputChanged = true 400 | } else { 401 | var saveSelected = false 402 | if (mouse.closestItem != undefined) { 403 | if (mouse.closestItem > 0) { saveSelected = myData.tensionLine[mouse.closestItem - 1].selected } else { saveSelected = myData.compressionLine[-mouse.closestItem - 1].selected } 404 | } 405 | num = myData.tensionLine.length 406 | for (i = 0; i < num; i++) { myData.tensionLine[i].selected = false } 407 | num = myData.compressionLine.length 408 | for (i = 0; i < num; i++) { myData.compressionLine[i].selected = false } 409 | if (mouse.closestItem != undefined) { 410 | if (mouse.closestItem >= 0) { myData.tensionLine[mouse.closestItem - 1].selected = !saveSelected } else { myData.compressionLine[-mouse.closestItem - 1].selected = !saveSelected } 411 | } 412 | } 413 | } 414 | drawAll('lines') 415 | break 416 | } // case tensionline or compressionline 417 | } 418 | } 419 | mouse.downOn = '' 420 | mouse.inDrag = false 421 | // drawAll(); 422 | } 423 | // onMouseMove MOUSE MOVE 424 | function onMouseMove(evt) { 425 | var mousePos = getMousePos(c, evt) 426 | var i 427 | if (mousePos === undefined) { 428 | mouse.x = 0 429 | mouse.y = 0 430 | } else { 431 | mouse.delta = arrondi(Math.sqrt((mouse.lastDrawX - mousePos.x) * (mouse.lastDrawX - mousePos.x) + (mouse.lastDrawY - mousePos.y) * (mouse.lastDrawY - mousePos.y)), 2) 432 | mouse.x = mousePos.x 433 | mouse.y = mousePos.y 434 | } 435 | mouse.inMenuBar = false 436 | mouse.inScreen1 = false 437 | mouse.inScreen2 = false 438 | mouse.inCanvas = false 439 | 440 | if ((mouse.x >= 0) && (mouse.x <= wtot) && (mouse.y >= 0) && (mouse.y <= htot)) { // mouse is on the canvas 441 | mouse.inCanvas = true 442 | if ((mouse.y <= hbar)) { // mouse is on the top menu bar 443 | mouse.pos = 'menubar' 444 | mouse.inMenuBar = true 445 | } else { 446 | if (mouse.y >= htot - hmsg) // mouse is on bottom message bar 447 | { mouse.pos = 'msgbar' } else { 448 | if ((mouse.x <= wbord + ecran1.width)) { // mouse in screen 1 449 | mouse.inScreen1 = true 450 | mouse.pos = 'screen1' 451 | } else { 452 | if (mouse.x <= wtot - wbord - e2) { mouse.pos = 'intbar' } else { 453 | mouse.pos = 'screen2' 454 | mouse.inScreen2 = true 455 | } 456 | } 457 | } 458 | } 459 | } else { 460 | mouse.pos = 'outside' 461 | if (!mouse.inDrag) return // mouse is not on the canvas and not in drag mode 462 | } 463 | if (state <= 0) return // applet inactif 464 | if (mouse.down) { 465 | if (!mouse.inDrag) { 466 | if ((mouse.x != mouse.prevX) && (mouse.y != mouse.prevY)) { 467 | mouse.firstDrag = true 468 | mouse.inDrag = true 469 | } 470 | } 471 | } 472 | if (((mouse.button == 2) || ((mouse.button == 3) && evt.ctrlKey)) && mod.pan && (mouse.inScreen1)) { 473 | echelle.pxoff = echelle.pxoff + mouse.x - mouse.prevX 474 | echelle.pyoff = echelle.pyoff + mouse.y - mouse.prevY 475 | echelle.pymax = echelle.pymax + mouse.y - mouse.prevY 476 | echelle.pymin = echelle.pymin + mouse.y - mouse.prevY 477 | mouse.prevX = mouse.x 478 | mouse.prevY = mouse.y 479 | var diff = hbar - hmsg 480 | myData.xmin = getRealX(wbord) 481 | myData.xmax = getRealX(wbord + ecran1.width) 482 | myData.ymin = getRealY(hmsg + ecran1.height + diff) 483 | myData.ymax = getRealY(hmsg + diff) 484 | } 485 | if (mod.intBarMove) { 486 | var newE2 = wtot - mouse.x - wbord - 0.5 * wint 487 | var newE1 = wtot - 2 * wbord - wint - newE2 488 | if ((newE2 >= 0) && (newE1 > 10)) { 489 | if (!mouse.shift) echelle = computeScale(myData.xmin, myData.xmax, myData.ymin, myData.ymax, wbord, wbord + ecran1.width, hbar, hbar + ecran1.height) 490 | e2 = newE2 491 | ecran1.width = newE1 492 | drawAll() 493 | } 494 | return 495 | } 496 | 497 | switch (true) { 498 | case (mouse.pos == 'menubar'): { 499 | var numBtn = '' 500 | // on ne fait rien : pas de menu bar dans cette version 501 | break 502 | } 503 | case (mouse.pos == 'msgbar'): { 504 | break 505 | } 506 | case (mouse.pos == 'screen1'): { 507 | if (!mouse.inDrag && !mouse.down) { 508 | mouse.pos = rechercheElementEcran1() // <<< does a lot of work !! 509 | if (mouse.pos == '') mouse.pos = 'screen1' 510 | } else { 511 | switch (true) { // mouse is in screen1 512 | case (mod.mode == 'node'): { 513 | if ((mouse.firstDrag) && (mouse.closestItem != undefined)) { 514 | if ((!mouse.control) && (!mouse.shift)) { 515 | if (mouse.posClosest != 2) { 516 | for (i = 0; i < myData.nodes.length; i++) { 517 | myData.nodes[i].selected = false 518 | myData.nodes[i].popup = undefined 519 | } 520 | } 521 | } 522 | myData.nodes[mouse.closestItem].selected = true 523 | } 524 | break 525 | } 526 | } 527 | } 528 | } 529 | 530 | case (mouse.pos == 'intbar'): { 531 | break 532 | } 533 | case (mouse.pos == 'screen2'): { 534 | break 535 | } 536 | } 537 | 538 | if ((mouse.prevPos != mouse.pos) || mouse.inDrag) { 539 | drawAll('mouse_drag') 540 | switch (true) { 541 | case (mouse.pos == 'outside'): 542 | c.style.cursor = 'auto' 543 | break 544 | case (mouse.pos == 'intbar'): 545 | c.style.cursor = 'e-resize' 546 | break 547 | default: 548 | if (mod.mode != 'zoom') c.style.cursor = 'auto' 549 | } 550 | mouse.prevPos = mouse.pos 551 | } 552 | mouse.lastX = mouse.x 553 | mouse.lastY = mouse.y 554 | showCoordinates() 555 | return false 556 | } 557 | 558 | // highlight screen 1 objects RECHERCHE ECRAN 1 559 | function rechercheElementEcran1() { 560 | var i, res, posClosest 561 | if (mod.mode != 'undefined') { 562 | var dist, minDist = 1E10, closest, pos = -1 563 | mouse.closestPolygonItem = undefined 564 | switch (true) { 565 | case (mod.mode == 'node'): { 566 | if(mouse.inDrag) { // on ne fait probablement rien 567 | } else { 568 | var numNodes = myData.nodes.length 569 | for (i = 0; i < numNodes; i++) { // chercher le noeud le plus proche 570 | myData.nodes[i].hover = false 571 | dist = objDist(mouse.x, mouse.y, myData.nodes[i]) 572 | if (dist[0] < minDist) { 573 | minDist = dist[0] 574 | posClosest = dist[1] 575 | closest = i 576 | } 577 | } 578 | // console.log('rechercheElementEcran1: ' + 'noeud le plus proche ' + closest); 579 | if ((closest >= 0) && (minDist <= MIN_DIST)) { 580 | mouse.closestItem = closest 581 | mouse.posClosest = dist[1] 582 | myData.nodes[closest].hover = true 583 | myData.nodes[closest].pos = posClosest // indique de quoi la souris est la plus proche 584 | res = mod.mode + ' ' + (closest + 1) 585 | } else { 586 | // console.log("rechercheElementEcran1: mouse is remote, replace " + mouse.closesItem + " by undefined"); 587 | mouse.closestItem = undefined 588 | res = '' 589 | } 590 | } 591 | // if (mouse.closestItem != undefined) console.log("rechercheElementEcran1: force " + mouse.closestItem + "." + mouse.posClosest); 592 | break 593 | } 594 | default: 595 | // console.log ("ERROR : " + mod.mode + " is not a recognized mode!"); 596 | } 597 | } 598 | return res 599 | } 600 | // onWheel 601 | function onWheel(evt) { 602 | if (state <= 0) return // applet inactif 603 | if (mouse.down) return // on distingue rouler et cliquer 604 | var thisWheel = new Date().getTime() 605 | if ((thisWheel - mouse.lastWheel) > 250) { 606 | mouse.lastWheel = thisWheel 607 | } else { 608 | return 609 | } 610 | if (mouse.inScreen1) { 611 | if (!mouse.disableEvents) evt.preventDefault() // je ne comprends pas cette ligne, à revoir !!! 612 | var zf = ZOOM_FACTOR 613 | if (evt.deltaY < 0) { // roule vers le haut : zoom-in 614 | } else { // roule vers le bas : zoom-out 615 | zf = 1 / zf 616 | } 617 | var newDx = (getRealX(echelle.pxmax) - echelle.xoff) * zf 618 | var newDy = (getRealY(0) - echelle.yoff) * zf 619 | var newScale = zf * echelle.scale 620 | echelle.xoff = (newScale * echelle.xoff - getRealX(mouse.x) * (newScale - echelle.scale)) / echelle.scale 621 | echelle.yoff = (newScale * echelle.yoff - getRealY(mouse.y) * (newScale - echelle.scale)) / echelle.scale 622 | echelle.xmax = echelle.xoff + newDx 623 | echelle.ymax = echelle.yoff + newDy 624 | echelle.scale = newScale 625 | var diff = hbar - hmsg 626 | myData.xmin = getRealX(wbord) 627 | myData.xmax = getRealX(wbord + ecran1.width) 628 | myData.ymin = getRealY(hmsg + ecran1.height + diff) 629 | myData.ymax = getRealY(hmsg + diff) 630 | drawAll() 631 | } 632 | } 633 | // returns correct mouse coordinates 634 | function getMousePos(c, evt) { 635 | // necessary to take into account CSS boudaries 636 | var rect = c.getBoundingClientRect() 637 | return { 638 | x: Math.round(evt.clientX - rect.left), 639 | y: Math.round(evt.clientY - rect.top) 640 | } 641 | } 642 | // create a copy of the current nodes (including displacements under way -- mouseMove) 643 | function getCurrentNodes() { 644 | var num = myData.nodes.length 645 | var n = [] 646 | var i 647 | var dx = mouse.dispX * echelle.scale 648 | var dy = -mouse.dispY * echelle.scale 649 | 650 | var stretchFactor = mouse.stretchFactor 651 | var angle = 180 / Math.PI * mouse.deltAngle 652 | var num = myData.nodes.length 653 | for (i = 0; i < num; i++) { 654 | n[i] = [] 655 | n[i].num = myData.nodes[i].num 656 | n[i].x = myData.nodes[i].x 657 | n[i].y = myData.nodes[i].y 658 | n[i].selected = myData.nodes[i].selected 659 | n[i].hover = myData.nodes[i].hover 660 | 661 | if (!mod.passage && (mod.mode == 'node') && ((n[i].selected) || (n[i].hover))) { 662 | n[i].x += dx 663 | n[i].y += dy 664 | n[i].selected = false // jusqu'à ce qu'on ait fait passer toutes les fonctions à utiliser une copie... 665 | n[i].hover = false // jusqu'à ce qu'on ait fait passer toutes les fonctions à utiliser une copie... 666 | } 667 | 668 | // console.log ( n[i].num + " : " + n[i].x + " , " + n[i].y);¨ 669 | } 670 | return n 671 | } 672 | 673 | // draws all screen components DRAW ALL 674 | function drawAll(obj) { 675 | var thisDraw = new Date().getTime() 676 | if (((mouse.inScreen1) && ((thisDraw - lastDraw) > 10)) || !mouse.inScreen1) { 677 | mouse.lastDrawX = mouse.x 678 | mouse.lastDrawY = mouse.y 679 | draw() 680 | drawNodes() 681 | showMessage() 682 | showCoordinates() 683 | 684 | lastDraw = thisDraw 685 | doRedraw = false 686 | } 687 | } 688 | // Draw method updates the canvas with the current display 689 | function draw() { 690 | // menu bar area 691 | ctx.save() 692 | ctx.beginPath() 693 | ctx.moveTo(0, 0) 694 | ctx.lineTo(w, 0) 695 | ctx.lineTo(w, hbar) 696 | ctx.lineTo(0, hbar) 697 | ctx.closePath() 698 | setColor(col.toolbar, 0, true) 699 | ctx.fill() 700 | // message bar area 701 | ctx.beginPath() 702 | ctx.moveTo(0, htot - hmsg) 703 | ctx.lineTo(w, htot - hmsg) 704 | ctx.lineTo(w, htot) 705 | ctx.lineTo(0, htot) 706 | ctx.closePath() 707 | setColor(col.statusbar, 0, true) 708 | ctx.fill() 709 | 710 | // left border 711 | ctx.beginPath() 712 | ctx.moveTo(0, hbar) 713 | ctx.lineTo(wbord, hbar) 714 | ctx.lineTo(wbord, h - hmsg) 715 | ctx.lineTo(0, h - hmsg) 716 | ctx.closePath() 717 | setColor(col.applet, 0, true) 718 | ctx.fill() 719 | 720 | // intermediate border 721 | ctx.beginPath() 722 | ctx.moveTo(wtot - wbord - wint - e2, hbar) 723 | ctx.lineTo(wtot - wbord - e2, hbar) 724 | ctx.lineTo(wtot - wbord - e2, htot - hmsg) 725 | ctx.lineTo(wtot - wbord - wint - e2, htot - hmsg) 726 | ctx.closePath() 727 | setColor(col.separator, 0, true) 728 | ctx.fill() 729 | 730 | // right border 731 | ctx.beginPath() 732 | ctx.moveTo(wtot - wbord, hbar) 733 | ctx.lineTo(wtot, hbar) 734 | ctx.lineTo(wtot, htot - hmsg) 735 | ctx.lineTo(wtot - wbord, htot - hmsg) 736 | ctx.closePath() 737 | setColor(col.applet, 0, true) 738 | ctx.fill() 739 | 740 | // outline 741 | ctx.beginPath() 742 | ctx.moveTo(1, 1) 743 | ctx.lineTo(w - 1, 1) 744 | ctx.lineTo(w - 1, h - 1) 745 | ctx.lineTo(1, h - 1) 746 | ctx.closePath() 747 | setColor(col.screen, 1, false) 748 | ctx.stroke() 749 | 750 | // inside of left screen 751 | ctx.beginPath() 752 | ctx.moveTo(wbord + 1, hbar + 1) 753 | ctx.lineTo(wtot - wbord - e2 - wint - 1, hbar + 1) 754 | ctx.lineTo(wtot - wbord - e2 - wint - 1, htot - hmsg - 1) 755 | ctx.lineTo(wbord + 1, htot - hmsg - 1) 756 | ctx.closePath() 757 | setColor(col.screen, 0, true) 758 | ctx.fill() 759 | // drawBackground() 760 | 761 | // inside of right screen 762 | ctx.beginPath() 763 | ctx.moveTo(wtot - wbord - e2 + 2, hbar + 2) 764 | ctx.lineTo(wtot - wbord - 2, hbar + 2) 765 | ctx.lineTo(wtot - wbord - 2, htot - hmsg - 2) 766 | ctx.lineTo(wtot - wbord - e2 + 2, htot - hmsg - 2) 767 | ctx.closePath() 768 | setColor(col.screen2, 0, true) 769 | ctx.fill() 770 | // outline of left screen 771 | ctx.beginPath() 772 | ctx.moveTo(wbord, hbar) 773 | ctx.lineTo(wtot - wbord - e2 - wint, hbar) 774 | ctx.lineTo(wtot - wbord - e2 - wint, htot - hmsg) 775 | ctx.lineTo(wbord, htot - hmsg) 776 | ctx.closePath() 777 | // ctx.strokeStyle = "red"; 778 | 779 | ctx.stroke() 780 | 781 | // outline of right screen 782 | ctx.beginPath() 783 | ctx.moveTo(wtot - wbord - e2 + 1, hbar + 1) 784 | ctx.lineTo(wtot - wbord - 1, hbar + 1) 785 | ctx.lineTo(wtot - wbord - 1, htot - hmsg - 1) 786 | ctx.lineTo(wtot - wbord - e2 + 1, htot - hmsg - 1) 787 | ctx.closePath() 788 | setColor(col.screen, 1, true) 789 | ctx.stroke() 790 | 791 | // limits of extents 792 | // console.log("x : " + getScreenX(myData.xmin) + " à " + getScreenX(myData.xmax) + " y :" + getScreenY(myData.ymin) + " à " + getScreenY(myData.ymax)); 793 | ctx.beginPath() 794 | ctx.moveTo(getScreenX(myData.xmin), getScreenY(myData.ymin)) 795 | ctx.lineTo(getScreenX(myData.xmax), getScreenY(myData.ymin)) 796 | ctx.lineTo(getScreenX(myData.xmax), getScreenY(myData.ymax)) 797 | ctx.lineTo(getScreenX(myData.xmin), getScreenY(myData.ymax)) 798 | ctx.closePath() 799 | ctx.strokeStyle = 'red' 800 | // ctx.stroke(); 801 | 802 | ctx.restore() 803 | } 804 | 805 | // draw nodes 806 | function drawNodes() { 807 | var i 808 | if ((myData.nodes == undefined) || (myData.nodes == [])) { return } 809 | var numNodes = myData.nodes.length 810 | var px, py 811 | ctx.save() 812 | ctx.beginPath() 813 | ctx.rect(wbord + 1, hbar + 1, ecran1.width, ecran1.height) 814 | ctx.clip() 815 | if (numNodes > 0) { 816 | for (i = 0; i < numNodes; i++) { 817 | px = getScreenX(myData.nodes[i].x) 818 | py = getScreenY(myData.nodes[i].y) 819 | if (mouse.inDrag && myData.nodes[i].hover && mod.mode == 'node') { 820 | px += mouse.x - mouse.startX 821 | py += mouse.y - mouse.startY 822 | } 823 | var colNode = col.node.split(',') 824 | var coulFond = colNode[1] 825 | if (myData.nodes[i].hover && mod.mode == 'node') coulFond = colNode[2] 826 | if (myData.nodes[i].selected && mod.mode == 'node') coulFond = colNode[3] 827 | // console.log("drawSupports: " + col.support[1] + ", " + coulFond); 828 | drawNode(px, py, colNode[0], coulFond, 0) 829 | if (mod.numbers) { 830 | drawText(px + 1.3 * 4, py - 1.3 * 4, (i + 1)) 831 | } 832 | } 833 | } 834 | ctx.restore() 835 | } 836 | 837 | // draw a node 838 | function drawNode(px, py, couleur, couleurFond, type) { 839 | var ax = [] 840 | var ay = [] 841 | var i 842 | var taille = 4 // en fait demi-taille du noeud 843 | 844 | ctx.save() 845 | 846 | ax[0] = px + taille 847 | ay[0] = py + taille 848 | ax[1] = px + taille 849 | ay[1] = py - taille 850 | ax[2] = px - taille 851 | ay[2] = py - taille 852 | ax[3] = px - taille 853 | ay[3] = py + taille 854 | ax[4] = ax[0] 855 | ay[4] = ay[0] 856 | 857 | // ctx.fillStyle = couleurFond; 858 | // ctx.strokeStyle = couleur; 859 | ctx.beginPath() 860 | ctx.moveTo(ax[0], ay[0]) 861 | ctx.lineTo(ax[1], ay[1]) 862 | ctx.lineTo(ax[2], ay[2]) 863 | ctx.lineTo(ax[3], ay[3]) 864 | ctx.lineTo(ax[4], ay[4]) 865 | setColor(couleurFond, 0, true) 866 | ctx.fill() 867 | setColor(couleur, 0, false) 868 | ctx.stroke() 869 | 870 | ctx.restore() 871 | } 872 | // draws a text 873 | function drawText(px, py, s) { 874 | ctx.save() 875 | ctx.font = '12px Arial' 876 | ctx.fillText(s, px, py) 877 | ctx.restore() 878 | } 879 | 880 | // move selected nodes 881 | function moveNodes(px, py) { 882 | var i 883 | var dx = px * echelle.scale 884 | var dy = -py * echelle.scale 885 | var num = myData.nodes.length 886 | for (i = 0; i < num; i++) { 887 | if (myData.nodes[i].selected) { 888 | myData.nodes[i].x += dx 889 | myData.nodes[i].y += dy 890 | } 891 | } 892 | } 893 | 894 | // distance to object (mesurée en pixels écran) 895 | function objDist(mx, my, O) { 896 | var minDist = 100000 // devrait être plus petit ! 897 | var pos 898 | O.hover = false 899 | var px = getScreenX(O.x) 900 | var py = getScreenY(O.y) 901 | var minDist = Math.sqrt((mx - px) * (mx - px) + (my - py) * (my - py)) 902 | pos = 1 903 | return [Math.round(minDist), pos] 904 | } 905 | 906 | // creates output file 907 | function outData() { 908 | var s, d 909 | var sep = ',' 910 | d = new Date() 911 | s = '** Data file generated on ' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getFullYear() + ' at ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + '\n' 912 | s += '**i-Mesh\n' 913 | s += '*VERSION,' + version + '\n' 914 | // console.log("myData.backImage = " + myData.backImage); 915 | if (myData.backImage != undefined) { 916 | s += '*BACKIMAGE,' + myData.backImage + sep + arrondi(myData.back_xmin) + sep + arrondi(myData.back_xmax) + sep + arrondi(myData.back_ymin) + sep + arrondi(myData.back_ymax) + sep 917 | if (mod.backimage) { s += 'ON\n' } else { s += 'OFF\n' } 918 | } 919 | // OB/28.2.2016 : le +4 pour les coordonnées y n'est pas propre. Il faudrait comprendre d'où il provient... en rapport avec hbar en tout cas 920 | var diff = hbar - hmsg 921 | s += '*EXTENTS' + sep + arrondi(getRealX(wbord)) + sep + arrondi(getRealX(wbord + ecran1.width)) + sep + arrondi(getRealY(hmsg + ecran1.height + diff)) + sep + arrondi(getRealY(hmsg + diff)) + '\n' 922 | if ((myData.supports != null) && (myData.supports.length > 0)) { 923 | s += '*SUPPORTS\n' 924 | for (var i = 0; i < myData.supports.length; i++) { s += arrondi(myData.supports[i].x) + sep + arrondi(myData.supports[i].y) + sep + 'ux=0;uy=0' + sep + myData.supports[i].attrib + sep + '\n' } 925 | } 926 | if ((myData.echelleForces != null) && (myData.echelleForces)) { s += '*ECHELLEFORCES' + sep + arrondi(myData.echelleForces) + '\n' } 927 | if ((myData.forces != null) && (myData.forces.length > 0)) { 928 | s += '*FORCES\n' 929 | for (i = 0; i < myData.forces.length; i++) { 930 | if (!isNaN(myData.forces[i].Fx + myData.forces[i].Fy)) { s += arrondi(myData.forces[i].x) + sep + arrondi(myData.forces[i].y) + sep + arrondi(myData.forces[i].Fx) + sep + arrondi(myData.forces[i].Fy) + sep + '\n' } 931 | } 932 | } 933 | if (mod.resultant) { s += '*RESULTANT' + sep + 'ON' + '\n' } 934 | if (mod.showEp) { s += '*SHOWEP' + sep + 'ON' + '\n' } 935 | if (myData.resmat != undefined) { s += '*RESMAT' + sep + arrondi(myData.resmat) + '\n' } 936 | if (myData.epaisseur != undefined) { s += '*EPAISSEUR' + sep + arrondi(myData.epaisseur) + '\n' } 937 | if (myData.subsystem != undefined) { 938 | s += '*SUBSYSTEM\n' 939 | for (i = 0; i < myData.subsystem.length; i++) { s += arrondi(myData.subsystem[i].x) + sep + arrondi(myData.subsystem[i].y) + sep } 940 | s += '\n' 941 | } 942 | if ((myData.compressionLine != null) && (myData.compressionLine.length > 0)) { 943 | s += '*COMPRESSIONLINE\n' 944 | for (i = 0; i < myData.compressionLine.length; i++) { 945 | var tmp = myData.compressionLine[i].x1 + myData.compressionLine[i].y1 + myData.compressionLine[i].x2 + myData.compressionLine[i].y2 946 | if (!isNaN(tmp)) { s += arrondi(myData.compressionLine[i].x1) + sep + arrondi(myData.compressionLine[i].y1) + sep + arrondi(myData.compressionLine[i].x2) + sep + arrondi(myData.compressionLine[i].y2) + sep + '\n' } 947 | } 948 | } 949 | if ((myData.tensionLine != null) && (myData.tensionLine.length > 0)) { 950 | s += '*TENSIONLINE\n' 951 | for (i = 0; i < myData.tensionLine.length; i++) { 952 | var tmp = myData.tensionLine[i].x1 + myData.tensionLine[i].y1 + myData.tensionLine[i].x2 + myData.tensionLine[i].y2 953 | if (!isNaN(tmp)) { s += arrondi(myData.tensionLine[i].x1) + sep + arrondi(myData.tensionLine[i].y1) + sep + arrondi(myData.tensionLine[i].x2) + sep + arrondi(myData.tensionLine[i].y2) + sep + '\n' } 954 | } 955 | } 956 | if ((myData.polygon != undefined) && mod.polygon) { 957 | s += '*POLYGON' + sep + myData.modeConstruction + sep + sep + arrondi(myData.angle_0) + sep + arrondi(myData.angle_1) + sep + arrondi(myData.passageX) + sep + arrondi(myData.passageY) + sep + arrondi(myData.lTot) + sep + '\n' 958 | if (myData.funicular != undefined) { 959 | // console.log("effort dans tie / strut " + arrondi(myData.funicular[numForces + 1].effort)); 960 | var last = myData.forces.length 961 | if (myData.supports[1].attrib != 0) last++ 962 | s += '*FUNICULAR\n' 963 | for (i = 0; i <= last; i++) { 964 | if (myData.funicular[i] != undefined) { 965 | s += arrondi(myData.funicular[i].x1) + sep + arrondi(myData.funicular[i].y1) + sep + arrondi(myData.funicular[i].x2) + sep + arrondi(myData.funicular[i].y2) + sep + arrondi(myData.funicular[i].effort) + sep + sep 966 | if (i < last) s += '\n' 967 | } 968 | } 969 | } 970 | } 971 | s += '\n*END' 972 | var goOn = true 973 | while (goOn) { 974 | s = s.replace('\n\n', '\n') 975 | if (s.indexOf('\n\n') == -1) { goOn = false } 976 | } 977 | return s 978 | } 979 | // set or unsets options 980 | 981 | // shows current mouse coordinates on the right of the message bar 982 | function showMessage() { 983 | ctx.save() 984 | // message bar area 985 | ctx.beginPath() 986 | ctx.moveTo(wbord, htot - hmsg + 3) 987 | ctx.lineTo(wtot - 15 - wCoo, htot - hmsg + 3) 988 | ctx.lineTo(wtot - 15 - wCoo, htot - 5) 989 | ctx.lineTo(wbord, htot - 5) 990 | ctx.closePath() 991 | // console.log((wtot - 10 - wCoo) + ", " + (htot - 1)); 992 | if (inputChanged) { setColor(col.statusbar, 2, true) } else { setColor(col.statusbar, 0, true) } 993 | setColor(col.statusbar, 1, false) 994 | // ctx.fillStyle = 'yellow'; 995 | ctx.fill() 996 | // ctx.strokeStyle = 'green'; 997 | ctx.stroke() 998 | if (curMessage === undefined) { return } 999 | ctx.font = '10pt Arial' 1000 | ctx.align = 'LEFT' 1001 | setColor(col.statusinput, 1, true) 1002 | ctx.fillText(curMessage, wbord + 8, htot - hmsg / 2 + 3) 1003 | ctx.restore() 1004 | } 1005 | // shows current mouse coordinates on the right of the message bar 1006 | function showCoordinates(what) { 1007 | ctx.save() 1008 | // message bar area 1009 | ctx.beginPath() 1010 | ctx.moveTo(wtot - wbord - wCoo - 3, htot - hmsg + 3) 1011 | ctx.lineTo(wtot - wbord, htot - hmsg + 3) 1012 | ctx.lineTo(wtot - wbord, htot - 5) 1013 | ctx.lineTo(wtot - wbord - wCoo - 3, htot - 5) 1014 | ctx.closePath() 1015 | setColor(col.statusbar, 9, true) 1016 | ctx.fill() 1017 | setColor(col.statusbar, 1, false) 1018 | ctx.stroke() 1019 | ctx.font = '8pt Arial' 1020 | setColor(col.statusbar, 1, true) 1021 | switch (true) { 1022 | case (what == 'paintCount'): { 1023 | message = numPaint.n 1024 | break 1025 | } 1026 | case (what == 'mousepos'): { 1027 | message = mouse.pos 1028 | break 1029 | } 1030 | default: { 1031 | if (mouse.inScreen1) { var message = arrondi(getRealX(mouse.x), 3) + ',' + arrondi(getRealY(mouse.y), 3) } else { var message = mouse.x + ',' + mouse.y } 1032 | break 1033 | } 1034 | } 1035 | ctx.fillText(message, wtot - wbord - wCoo + (wCoo - ctx.measureText(message).width) / 2, htot - hmsg / 2 + 4) 1036 | ctx.restore() 1037 | } 1038 | // defines the scaling between screen and real world 1039 | function computeScale(xmin, xmax, ymin, ymax, pxmin, pxmax, pymin, pymax) { 1040 | var echelle = [] 1041 | echelle.xoff = xmin 1042 | echelle.xmax = xmax 1043 | echelle.yoff = ymin 1044 | echelle.ymax = ymax 1045 | echelle.pxoff = pxmin 1046 | echelle.pyoff = pymax - pymin 1047 | echelle.pymax = pymax 1048 | echelle.pymax = pymax 1049 | echelle.pxmax = pxmax 1050 | // console.log ('computeScale: " +xmin + "," + ymin + " " + xmax + "," + ymax + " -- " + pxmin + "," + pymin + " " + pxmax + "," + pymax); 1051 | var scalex = (xmax - xmin) / (pxmax - pxmin) 1052 | var scaley = (ymax - ymin) / echelle.pyoff 1053 | // console.log (scalex + " " + scaley); 1054 | if (scalex > scaley) { 1055 | echelle.scale = scalex 1056 | echelle.yoff -= (echelle.pyoff * echelle.scale - (ymax - ymin)) / 2 1057 | } else { 1058 | echelle.scale = scaley 1059 | echelle.xoff -= ((pxmax - pxmin) * echelle.scale - (xmax - xmin)) / 2 1060 | // console.log(echelle.xoff); 1061 | } 1062 | return echelle 1063 | } 1064 | // get screen x-coordinate from real location 1065 | function getScreenX(x, ech) { 1066 | if (ech == undefined) ech = echelle 1067 | return Math.round(((x - ech.xoff) / ech.scale) + ech.pxoff) 1068 | } 1069 | // get screen y-coordinate from real location 1070 | function getScreenY(y, ech) { 1071 | if (ech == undefined) ech = echelle 1072 | return Math.round(ech.pymax - (y - ech.yoff) / ech.scale) 1073 | } 1074 | // get real-world x-coordinate from screen location 1075 | function getRealX(px, ech) { 1076 | if (ech == undefined) ech = echelle 1077 | var val = (px - ech.pxoff) * ech.scale + ech.xoff 1078 | // val = arrondi(val,digitsGeom ) 1079 | return val 1080 | } 1081 | // get real-world y-coordinate from screen location 1082 | function getRealY(py, ech) { 1083 | if (ech == undefined) ech = echelle 1084 | var val = (ech.pymax - py) * ech.scale + ech.yoff, digitsGeom 1085 | return val 1086 | } 1087 | // round of to a prescribed number of significant digits 1088 | function arrondi(x, digits) { 1089 | if (digits == undefined) digits = 3 1090 | // if (isNaN(x)) return NaN; 1091 | // if (x == '') return NaN; 1092 | // var mult = Math.pow(10, digits); 1093 | // console.log(x + ", " + digits + ", " + mult + " --> " + Math.round(x * mult) + " " + (x * mult) / mult); 1094 | // return Math.round(x * mult) / mult; 1095 | return formatEng(x, digits + 1) 1096 | } 1097 | // formats a number in flexible manner, with a given number of significant digits 1098 | function formatEng(x, digits) { 1099 | if (x == 0) return '0' 1100 | if (x >= 0) { 1101 | var sign = 1 1102 | var res = '' 1103 | } else { 1104 | var sign = -1 1105 | var res = '-' 1106 | } 1107 | var exp = Math.floor(Math.log(Math.abs(x)) / Math.LN10) 1108 | var mant = Math.round(sign * x / Math.pow(10, (exp - digits + 1))) / Math.pow(10, digits - 1) 1109 | // console.log (mant.toFixed(3) + "e" + exp); 1110 | 1111 | if ((exp >= -1) && (exp < digits)) { // afichage "normal" --> tout est OK ici 1112 | res += trimZeroes((mant * Math.pow(10, exp)).toFixed(digits - exp - 1)) 1113 | } else { 1114 | var modu = Math.abs(exp) % 3 1115 | if (exp > 0) { // nombres trop grands pour l'affichage normal --> tout est OK ici 1116 | var tmp = digits - modu - 1 1117 | if (tmp < 0) tmp = 0 1118 | res += trimZeroes((mant * Math.pow(10, modu)).toFixed(tmp)) + 'e' + (exp - modu) 1119 | } else { 1120 | var tmp = digits - modu 1121 | if (tmp < 0) tmp = 0 1122 | var fact = 3 - modu 1123 | if (fact == 3) fact = 0 1124 | tmp = digits - fact - 1 1125 | if (tmp < 0) tmp = 0 1126 | // console.log(" modu = " + modu + " fact " + fact + " tmp " + tmp); 1127 | res += trimZeroes((mant * Math.pow(10, fact)).toFixed(tmp)) + 'e' + (exp - fact) // + " modu = " + modu + " fact " + fact + " tmp " + tmp; 1128 | } 1129 | } 1130 | return res 1131 | } 1132 | // removes trailing zeros after decimal point in number string. Also removes the decimal point if unnecessary 1133 | function trimZeroes(s) { 1134 | var i = s.length - 1 1135 | if (s.indexOf('.') == -1) return s // pas de point décimal 1136 | while (s.charAt(i) == '0') { i-- } 1137 | if (s.charAt(i) == '.') { i-- } 1138 | // var t = s.slice(0,i+1); 1139 | // console.log("trimZeroes: " + s + " --> " + t); 1140 | return s.slice(0, i + 1) 1141 | } 1142 | // returns the angle of a vector 1143 | function atanYX(x, y) { 1144 | var val = 0 1145 | if (Math.abs(x) < minDouble) { // quasi vertical 1146 | if (y > 0) val = Math.PI / 2 1147 | else val = -Math.PI / 2 1148 | } else { 1149 | if (x < 0) { 1150 | if (y >= 0) { val = Math.PI / 2 + Math.atan(-x / y) } else val = -Math.PI / 2 - Math.atan(x / y) 1151 | } else 1152 | if (y >= 0) val = Math.atan(y / x) 1153 | else val = -Math.atan(-y / x) 1154 | } 1155 | return val 1156 | } 1157 | // intersection de deux lignes d'action 1158 | function intersection(x1, y1, f1, x2, y2, f2) { 1159 | // retourne le paramètre "k" localisant le point d'intersection 1160 | // de deux droites définies chacune par un point et un vecteur (force) 1161 | var det = (-f1.Fx * f2.Fy + f2.Fx * f1.Fy) 1162 | var k 1163 | if (Math.abs(det) >= 1.0E-10) { k = ((x1 - x2) * f2.Fy - (y1 - y2) * f2.Fx) / det } 1164 | if (debug) { 1165 | var inter = [] 1166 | inter.x = x1 + k * f1.Fx 1167 | inter.y = y1 + k * f1.Fy 1168 | console.log('intersection à (' + arrondi(inter.x) + ',' + arrondi(inter.y) + ') k = ' + arrondi(k) + ' ' + arrondi(x1) + ',' + arrondi(y1) + ' [' + arrondi(f1.Fx) + ',' + arrondi(f1.Fy) + '] ' + arrondi(x2) + ',' + arrondi(y2) + ' [' + arrondi(f2.Fx) + ',' + arrondi(f2.Fy) + ']') 1169 | } 1170 | // k est 'undefined' si le déterminant est nul 1171 | return k 1172 | } 1173 | // sets the drawing color and transparency 1174 | function setColor(couleur, index, doFill, alpha) { 1175 | var tmp = couleur 1176 | if (couleur.indexOf(',') < 0) { 1177 | tmp = couleur 1178 | } else { 1179 | var coulMat = couleur.split(',') 1180 | tmp = coulMat[0] 1181 | } 1182 | // console.log("setColor: color is '" + tmp + "'"); 1183 | if (tmp == undefined) { 1184 | tmp = 'lightgreen' 1185 | console.log('request for undefined color') 1186 | console.trace() 1187 | } 1188 | if (doFill == undefined) { doFill = false } 1189 | var pos = tmp.indexOf(';') 1190 | if (pos < 0) { 1191 | if (alpha != undefined) ctx.globalAlpha = alpha 1192 | if (doFill) { ctx.fillStyle = tmp } else { ctx.strokeStyle = tmp } 1193 | } else { 1194 | var vals = tmp.split(';') 1195 | if (vals.length == 2) { // nom de couleur + transparence 1196 | if (alpha == undefined) alpha = 1 * vals[1] // la valeur d'alpha du fichier n'est valable que si elle n'a pas été spécifiée lors de l'appel) 1197 | if (doFill) { ctx.fillStyle = vals[0] } else { ctx.strokeStyle = vals[0] } 1198 | ctx.globalAlpha = alpha 1199 | } else { 1200 | tmp = 'rgb(' + vals[0] + ',' + vals[1] + ',' + vals[2] + ')' 1201 | // paramètres de couleur RGB 1202 | if (doFill) { ctx.fillStyle = tmp } else { ctx.strokeStyle = tmp } 1203 | if (vals.length == 4) { // RGB + transparence 1204 | if (alpha) { ctx.globalAlpha = alpha } else { ctx.globalAlpha = vals[3] } 1205 | } 1206 | } 1207 | } 1208 | } 1209 | 1210 | // Public properties and methods of the iMini object 1211 | 1212 | this.width = 300 1213 | this.height = 150 1214 | // this.maxValue; 1215 | this.margin = 5 1216 | 1217 | // initialize the iMini object 1218 | this.initialize = function () { 1219 | init() 1220 | xbarmin = wtot - wbord - e2 - wint 1221 | xbarmax = xbarmin + wint 1222 | 1223 | myData.xmin = 0 1224 | myData.xmax = 100 1225 | myData.ymin = 0 1226 | myData.ymax = 20 1227 | echelle = computeScale(myData.xmin, myData.xmax, myData.ymin, myData.ymax, wbord, wbord + ecran1.width, hbar, hbar + ecran1.height) 1228 | ecran1.realXmin = getRealX(wbord) 1229 | ecran1.realXmax = getRealX(wbord + ecran1.width) 1230 | ecran1.realYmax = getRealY(hbar) // min et max sont inversés car l'axe y de l'écran est dans l'autre sens 1231 | ecran1.realYmin = getRealY(hbar + ecran1.height) 1232 | 1233 | // couleurs 1234 | col.applet = 'LightGray' 1235 | col.screen = 'White,Black' 1236 | col.screen2 = 'Gray,Black' 1237 | col.separator = 'LightGray' 1238 | col.toolbar = 'LightGray,Black' 1239 | col.statusbar = 'LightGray,Gray,Yellow' 1240 | col.statusinput = 'LightGray,Black' 1241 | col.node = 'black,white,magenta,red,green' 1242 | } 1243 | // update method paint all screen components 1244 | this.update = function () { 1245 | drawAll('update') 1246 | } 1247 | // set active mode 1248 | this.setMod = function (mode) { 1249 | mod.mode = mode 1250 | } 1251 | // set numbering 1252 | this.setNumbers = function (num) { 1253 | mod.numbers = num 1254 | } 1255 | } 1256 | -------------------------------------------------------------------------------- /docs/static/iMini.js: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Olivier Burdet 2 | // 3 | 'use strict' 4 | var jsRep = '/dummy/' 5 | 6 | // objet iMini 7 | function iMini(c, ctx, w, h, e2, jsr) { 8 | // Private properties and methods 9 | 10 | var version = '0.0,000' 11 | 12 | var messages = 'iMini starting, version ' + version + '\n' 13 | 14 | if (jsr != undefined) jsRep = jsr 15 | var that = this 16 | var myName = c.id 17 | 18 | console.log('iMini ' + version + ' ' + jsRep + ' ' + c.id) 19 | 20 | // input data and processed data 21 | var userID 22 | var sessionID 23 | var IP 24 | var col = [] // color values 25 | var myData = [] // contains all data for easy access 26 | myData.nodes = [] 27 | 28 | var wtot = w 29 | var htot = h 30 | var hbar = 34 31 | 32 | var hmsg = 30 33 | var wbord = 8 34 | var wint = 8 35 | var xbarmin 36 | var xbarmax 37 | var wCoo = 100 38 | var hCoo = 8 39 | var curMessage = '' 40 | 41 | var curDist = 100 42 | var MIN_DIST = 10 // pixels for activating proximity 43 | 44 | var doRedraw = true 45 | var lastDraw = new Date().getTime() 46 | 47 | var ecran1 = [] 48 | ecran1.width = wtot - 2 * wbord - wint - e2 49 | ecran1.height = htot - hbar - hmsg 50 | var inputData 51 | var inputChanged 52 | var mod = [] 53 | mod.numbers = false 54 | mod.mesh = false 55 | mod.shift = false 56 | mod.alt = false 57 | mod.control = false 58 | mod.resultant = false 59 | mod.showEp = false 60 | mod.mode = '' 61 | 62 | var key = [] 63 | var map = [] // to store key codes 64 | var state 65 | 66 | var butSize = Math.round(hbar / 1.5) 67 | var butOff = Math.round(butSize / 4) 68 | var vertOff = butOff 69 | 70 | var mouse = [] 71 | mouse.pos = '' 72 | mouse.x = 0 73 | mouse.y = 0 74 | mouse.y = 0 75 | mouse.startX = 0 76 | mouse.startY = 0 77 | mouse.dispX = 0 78 | mouse.dispY = 0 79 | mouse.stretchFactor = 1 80 | mouse.deltAngle = 0 81 | mouse.inDrag = false 82 | mouse.passage = false 83 | mouse.disableEvents = false 84 | mouse.lastWheel = new Date().getTime() 85 | 86 | var echelle = [] // echelle de l'écran 1 : système réel 87 | var echelle2 = [] // echelle de l'écran 2 : diagramme de Cremona 88 | 89 | function init() { 90 | window.addEventListener('mousedown', onMouseDown, false) 91 | window.addEventListener('mousemove', onMouseMove, false) 92 | window.addEventListener('mouseup', onMouseUp, false) 93 | window.addEventListener('wheel', onWheel, false) 94 | // blocage des événements "roulette" sur le canevas 95 | document.getElementById(myName).onwheel = function (event) { 96 | event.preventDefault() 97 | } 98 | document.getElementById(myName).onmousewheel = function (event) { 99 | event.preventDefault() 100 | } 101 | } 102 | 103 | // onMouseDown MOUSE DOWN 104 | function onMouseDown(evt) { 105 | if (!mouse.inCanvas) return // la souris n'est pas dans le canevas de l'applet 106 | 107 | mouse.down = true 108 | mouse.firstDrag = false 109 | mouse.control = false 110 | if (mod.control) { 111 | mouse.control = true 112 | } else { 113 | if (evt.ctrlKey) { mouse.control = true } 114 | } 115 | 116 | (mod.alt) ? mouse.alt = true : mouse.alt = evt.altlKey; 117 | (mod.shift) ? mouse.shift = true : mouse.shift = evt.shiftKey 118 | mouse.button = evt.button + 1 119 | mouse.downOn = mouse.pos 120 | mouse.startX = mouse.x 121 | mouse.startY = mouse.y 122 | mouse.prevX = mouse.x 123 | mouse.prevY = mouse.y 124 | mouse.inNewLine = false 125 | // console.log("onMouseDown: " + mouse.button); 126 | if ((mouse.button == 2) || ((mouse.button == 3) && evt.ctrlKey)) { 127 | if (mouse.inScreen1) evt.stopPropagation() 128 | mod.pan = true 129 | return 130 | } 131 | if (mouse.pos == 'intbar') { // on commence à déplacer la barre intermédiaire 132 | mod.intBarMove = true 133 | } 134 | switch (true) { 135 | case (mod.mode == 'node'): { // on ne fait rien : les coordonnées de départ de la souris sont déjà stockées 136 | break 137 | } 138 | } 139 | } 140 | // onMouseUp MOUSE UP 141 | function onMouseUp(evt) { 142 | if (state <= 0) return // applet inactif 143 | if (!mouse.down) { // on n'a pas eu le mouse down, on ignore le mouse up 144 | mouse.inDrag = false 145 | mouse.firstDrag = false 146 | return 147 | } 148 | if (!mouse.inCanvas && !mouse.inDrag) { // en-dehors du canevas, on ne tient compte de que des fin de drag 149 | mouse.down = false 150 | return 151 | } 152 | var i, num 153 | var wasInDrag = mouse.inDrag 154 | mouse.down = false 155 | mouse.inDrag = false 156 | mouse.firstDrag = false 157 | if ((mouse.button == 2) || ((mouse.button == 3) && evt.ctrlKey)) { 158 | mod.pan = false 159 | evt.stopPropagation() 160 | return 161 | } 162 | if (mod.intBarMove) { 163 | mod.intBarMove = false 164 | return 165 | } 166 | mouse.dispX = mouse.x - mouse.startX 167 | mouse.dispY = mouse.y - mouse.startY 168 | if ((mouse.inMenuBar) && !wasInDrag) { 169 | menuBarAction(mouse) 170 | } else { 171 | // console.log("onMouseUp: " + mod.mode + " " + mouse.pos + " " + mouse.closestItem + " " + wasInDrag); 172 | switch (true) { 173 | case (mod.mode == 'node'): { 174 | if ((mouse.pos == 'msgbar') && !wasInDrag) { 175 | showDialog('node', '') 176 | break 177 | } 178 | if ((mouse.closestItem == undefined) && mouse.inScreen1) { 179 | // ajouter un nouveau noeud 180 | var num = myData.nodes.length 181 | var N = {} 182 | N.x = getRealX(mouse.x) 183 | N.y = getRealY(mouse.y) 184 | myData.nodes[num] = N 185 | inputChanged = true 186 | myData.currentNodes = getCurrentNodes() 187 | drawAll('new node') 188 | } else { 189 | if (wasInDrag) { 190 | // console.log('onMouseUp: déplacement ' + mouse.dispX + ". " + mouse.dispY); 191 | moveNodes(mouse.dispX, mouse.dispY) 192 | inputChanged = true 193 | } else { 194 | var saveSelected = false 195 | if ((mouse.closestItem != undefined) && (mouse.closestItem != '')) { saveSelected = myData.nodes[mouse.closestItem].selected } 196 | num = myData.nodes.length 197 | if (!mouse.control) { 198 | for (i = 0; i < num; i++) { myData.nodes[i].selected = false } 199 | } 200 | if (mouse.closestItem != undefined) { 201 | myData.nodes[mouse.closestItem].selected = !saveSelected 202 | showMessage() 203 | } 204 | } 205 | } 206 | drawAll() 207 | break 208 | } 209 | // case forces 210 | case (mod.mode == 'force'): { 211 | if ((mouse.pos == 'msgbar') && !wasInDrag) { 212 | showDialog('force', '') 213 | break 214 | } 215 | if ((mouse.closestItem == undefined) && mouse.inScreen1) { 216 | // ajouter une nouvelle force 217 | var F = {} 218 | F.x = getRealX(mouse.x) 219 | F.y = getRealY(mouse.y) 220 | var vals = curForce.split('<') 221 | F.mag = 1 * vals[0] 222 | F.angle = 1 * vals[1] 223 | F.Fx = F.mag * Math.cos(Math.PI / 180 * F.angle) 224 | if (Math.abs(F.Fx) < 1.E-10) F.Fx = 0 225 | F.Fy = F.mag * Math.sin(Math.PI / 180 * F.angle) 226 | if (Math.abs(F.Fy) < 1.E-10) F.Fy = 0 227 | var num = myData.forces.length 228 | myData.forces[num] = F 229 | if (num == 0) // la première force définit l'échelle 230 | { myData.echelleForces = 50 / F.mag } 231 | inputChanged = true 232 | myData.currentForces = getCurrentForces() 233 | drawAll('new force') 234 | } else { 235 | if (wasInDrag) { 236 | moveRotateStretchForces(mouse.dispX, mouse.dispY, 180 / Math.PI * mouse.deltAngle, mouse.stretchFactor) 237 | inputChanged = true 238 | } else { 239 | var saveSelected = false 240 | if ((mouse.closestItem != undefined) && (mouse.closestItem != '')) { saveSelected = myData.forces[mouse.closestItem].selected } 241 | num = myData.forces.length 242 | if (!mouse.control) { 243 | for (i = 0; i < num; i++) { myData.forces[i].selected = false } 244 | } 245 | if (mouse.closestItem != undefined) { 246 | myData.forces[mouse.closestItem].selected = !saveSelected 247 | if (!saveSelected) { 248 | curForce = arrondi(myData.forces[mouse.closestItem].mag) + '<' + myData.forces[mouse.closestItem].angle.toFixed(1) 249 | curMessage = curForce 250 | showMessage() 251 | } 252 | } 253 | } 254 | } 255 | break 256 | } // case forces 257 | case (mod.mode == 'support'): { 258 | if ((mouse.closestItem == undefined) && mouse.inScreen1) { 259 | var num = myData.supports.length 260 | // ajouter un nouveau support 261 | var F = {} 262 | F.x = getRealX(mouse.x) 263 | F.y = getRealY(mouse.y) 264 | if (mouse.control) { F.attrib = 1 } else 265 | if (mouse.shift) { F.attrib = 2 } else { F.attrib = 0 } 266 | myData.supports[num] = F 267 | num = myData.supports.length 268 | curMessage = curTexts.getValue('nosupport', '*') 269 | myData.currentSupports = getCurrentSupports() 270 | inputChanged = true 271 | drawAll('support') 272 | } else { 273 | if (wasInDrag) { 274 | moveSupports(mouse.x - mouse.startX, mouse.y - mouse.startY) 275 | inputChanged = true 276 | drawAll('support') 277 | } else { 278 | var saveSelected = false 279 | if ((mouse.closestItem != undefined) && (mouse.closestItem != '')) { saveSelected = myData.supports[mouse.closestItem].selected } 280 | num = myData.supports.length 281 | if (!mouse.control) { 282 | for (i = 0; i < num; i++) { myData.supports[i].selected = false } 283 | } 284 | if (mouse.closestItem != undefined) { 285 | myData.supports[mouse.closestItem].selected = !saveSelected 286 | } 287 | } 288 | } 289 | break 290 | } // case supports 291 | case (mod.mode == 'scaleimage'): { 292 | var dx = mouse.x - mouse.startX 293 | var dy = mouse.y - mouse.startY 294 | var dist = Math.sqrt(dx * dx + dy * dy) 295 | if (dist > 10) { 296 | var echelle_new = computeScale(0, curDist, 0, curDist, mouse.startX, mouse.startX + dist, mouse.startY, mouse.startY + dist) 297 | echelle_new.ymin -= curDist 298 | echelle_new.ymax -= curDist 299 | echelle_new.yoff -= curDist 300 | 301 | myData.back_xmin = getRealX(getScreenX(myData.back_xmin), echelle_new) 302 | myData.back_xmax = getRealX(getScreenX(myData.back_xmax), echelle_new) 303 | myData.back_ymin = getRealY(getScreenY(myData.back_ymin), echelle_new) 304 | myData.back_ymax = getRealY(getScreenY(myData.back_ymax), echelle_new) 305 | 306 | for (var i = 0; i < myData.forces.length; i++) { 307 | myData.forces[i].x = getRealX(getScreenX(myData.forces[i].x), echelle_new) 308 | myData.forces[i].y = getRealY(getScreenY(myData.forces[i].y), echelle_new) 309 | } 310 | for (i = 0; i < myData.supports.length; i++) { 311 | myData.supports[i].x = getRealX(getScreenX(myData.supports[i].x), echelle_new) 312 | myData.supports[i].y = getRealY(getScreenY(myData.supports[i].y), echelle_new) 313 | } 314 | for (i = 0; i < myData.tensionLine.length; i++) { 315 | myData.tensionLine[i].x1 = getRealX(getScreenX(myData.tensionLine[i].x1), echelle_new) 316 | myData.tensionLine[i].y1 = getRealY(getScreenY(myData.tensionLine[i].y1), echelle_new) 317 | myData.tensionLine[i].x2 = getRealX(getScreenX(myData.tensionLine[i].x2), echelle_new) 318 | myData.tensionLine[i].y2 = getRealY(getScreenY(myData.tensionLine[i].y2), echelle_new) 319 | } 320 | for (i = 0; i < myData.compressionLine.length; i++) { 321 | myData.compressionLine[i].x1 = getRealX(getScreenX(myData.compressionLine[i].x1), echelle_new) 322 | myData.compressionLine[i].y1 = getRealY(getScreenY(myData.compressionLine[i].y1), echelle_new) 323 | myData.compressionLine[i].x2 = getRealX(getScreenX(myData.compressionLine[i].x2), echelle_new) 324 | myData.compressionLine[i].y2 = getRealY(getScreenY(myData.compressionLine[i].y2), echelle_new) 325 | } 326 | if (myData.subsystem != undefined) { 327 | for (i = 0; i < myData.subsystem.length; i++) { 328 | myData.subsystem[i].x = getRealX(getScreenX(myData.subsystem[i].x), echelle_new) 329 | myData.subsystem[i].y = getRealY(getScreenY(myData.subsystem[i].y), echelle_new) 330 | } 331 | } 332 | echelle = echelle_new 333 | myData.currentForces = getCurrentForces() 334 | myData.currentSupports = getCurrentSupports() 335 | var diff = hbar - hmsg 336 | myData.xmin = getRealX(wbord) 337 | myData.xmax = getRealX(wbord + ecran1.width) 338 | myData.ymin = getRealY(hmsg + ecran1.height + diff) 339 | myData.ymax = getRealY(hmsg + diff) 340 | curMessage = curTexts.getValue('distanceset', '*') + ' ' + arrondi(curDist) 341 | inputChanged = true 342 | curButtons[buttonNumber('scaleimage')].unSet() 343 | mod.mode = undefined 344 | drawAll('') 345 | } else { 346 | curButtons[buttonNumber('scaleimage')].unSet() 347 | mod.mode = undefined 348 | curMessage = curTexts.getValue('distancenotset', '*') 349 | showMessage() 350 | } 351 | break 352 | } // case scaleimage 353 | case (mod.mode == 'subsystem'): { 354 | if(mouse.inScreen1 && mouse.inNewLine) { 355 | // ajouter un nouveau sous-système 356 | num = tempLine.length 357 | tempLine[num] = [] 358 | tempLine[num].x = getRealX(mouse.x) 359 | tempLine[num].y = getRealY(mouse.y) 360 | myData.subsystem = [] 361 | for (i = 0; i <= num; i++) { 362 | myData.subsystem[i] = [] 363 | myData.subsystem[i].x = tempLine[i].x 364 | myData.subsystem[i].y = tempLine[i].y 365 | } 366 | tempLine = undefined 367 | inputChanged = true 368 | mouse.inNewLine = false 369 | } else { 370 | if (myData.subsystem != undefined) { 371 | if (wasInDrag) { 372 | movePolyLine(mouse.x - mouse.startX, mouse.y - mouse.startY, mouse.closestItem) 373 | inputChanged = true 374 | } else { 375 | if ((mouse.closestItem != undefined) && (mouse.closestItem > 0)) { myData.subsystem.selected = !myData.subsystem.selected } 376 | } 377 | } 378 | } 379 | drawAll('lines') 380 | break 381 | } // case subsystem 382 | case ((mod.mode == 'tensionline') || (mod.mode == 'compressionline')): { 383 | if ((mouse.closestItem == undefined) && mouse.inScreen1) { 384 | // ajouter une nouvelle ligne 385 | tempLine.x2 = getRealX(mouse.x) 386 | tempLine.y2 = getRealY(mouse.y) 387 | if (mod.mode == 'tensionline') { 388 | var num = myData.tensionLine.length 389 | myData.tensionLine[num] = tempLine 390 | } 391 | if (mod.mode == 'compressionline') { 392 | var num = myData.compressionLine.length 393 | myData.compressionLine[num] = tempLine 394 | } 395 | inputChanged = true 396 | } else { 397 | if (wasInDrag) { 398 | moveLine(mouse.x - mouse.startX, mouse.y - mouse.startY) 399 | inputChanged = true 400 | } else { 401 | var saveSelected = false 402 | if (mouse.closestItem != undefined) { 403 | if (mouse.closestItem > 0) { saveSelected = myData.tensionLine[mouse.closestItem - 1].selected } else { saveSelected = myData.compressionLine[-mouse.closestItem - 1].selected } 404 | } 405 | num = myData.tensionLine.length 406 | for (i = 0; i < num; i++) { myData.tensionLine[i].selected = false } 407 | num = myData.compressionLine.length 408 | for (i = 0; i < num; i++) { myData.compressionLine[i].selected = false } 409 | if (mouse.closestItem != undefined) { 410 | if (mouse.closestItem >= 0) { myData.tensionLine[mouse.closestItem - 1].selected = !saveSelected } else { myData.compressionLine[-mouse.closestItem - 1].selected = !saveSelected } 411 | } 412 | } 413 | } 414 | drawAll('lines') 415 | break 416 | } // case tensionline or compressionline 417 | } 418 | } 419 | mouse.downOn = '' 420 | mouse.inDrag = false 421 | // drawAll(); 422 | } 423 | // onMouseMove MOUSE MOVE 424 | function onMouseMove(evt) { 425 | var mousePos = getMousePos(c, evt) 426 | var i 427 | if (mousePos === undefined) { 428 | mouse.x = 0 429 | mouse.y = 0 430 | } else { 431 | mouse.delta = arrondi(Math.sqrt((mouse.lastDrawX - mousePos.x) * (mouse.lastDrawX - mousePos.x) + (mouse.lastDrawY - mousePos.y) * (mouse.lastDrawY - mousePos.y)), 2) 432 | mouse.x = mousePos.x 433 | mouse.y = mousePos.y 434 | } 435 | mouse.inMenuBar = false 436 | mouse.inScreen1 = false 437 | mouse.inScreen2 = false 438 | mouse.inCanvas = false 439 | 440 | if ((mouse.x >= 0) && (mouse.x <= wtot) && (mouse.y >= 0) && (mouse.y <= htot)) { // mouse is on the canvas 441 | mouse.inCanvas = true 442 | if ((mouse.y <= hbar)) { // mouse is on the top menu bar 443 | mouse.pos = 'menubar' 444 | mouse.inMenuBar = true 445 | } else { 446 | if (mouse.y >= htot - hmsg) // mouse is on bottom message bar 447 | { mouse.pos = 'msgbar' } else { 448 | if ((mouse.x <= wbord + ecran1.width)) { // mouse in screen 1 449 | mouse.inScreen1 = true 450 | mouse.pos = 'screen1' 451 | } else { 452 | if (mouse.x <= wtot - wbord - e2) { mouse.pos = 'intbar' } else { 453 | mouse.pos = 'screen2' 454 | mouse.inScreen2 = true 455 | } 456 | } 457 | } 458 | } 459 | } else { 460 | mouse.pos = 'outside' 461 | if (!mouse.inDrag) return // mouse is not on the canvas and not in drag mode 462 | } 463 | if (state <= 0) return // applet inactif 464 | if (mouse.down) { 465 | if (!mouse.inDrag) { 466 | if ((mouse.x != mouse.prevX) && (mouse.y != mouse.prevY)) { 467 | mouse.firstDrag = true 468 | mouse.inDrag = true 469 | } 470 | } 471 | } 472 | if (((mouse.button == 2) || ((mouse.button == 3) && evt.ctrlKey)) && mod.pan && (mouse.inScreen1)) { 473 | echelle.pxoff = echelle.pxoff + mouse.x - mouse.prevX 474 | echelle.pyoff = echelle.pyoff + mouse.y - mouse.prevY 475 | echelle.pymax = echelle.pymax + mouse.y - mouse.prevY 476 | echelle.pymin = echelle.pymin + mouse.y - mouse.prevY 477 | mouse.prevX = mouse.x 478 | mouse.prevY = mouse.y 479 | var diff = hbar - hmsg 480 | myData.xmin = getRealX(wbord) 481 | myData.xmax = getRealX(wbord + ecran1.width) 482 | myData.ymin = getRealY(hmsg + ecran1.height + diff) 483 | myData.ymax = getRealY(hmsg + diff) 484 | } 485 | if (mod.intBarMove) { 486 | var newE2 = wtot - mouse.x - wbord - 0.5 * wint 487 | var newE1 = wtot - 2 * wbord - wint - newE2 488 | if ((newE2 >= 0) && (newE1 > 10)) { 489 | if (!mouse.shift) echelle = computeScale(myData.xmin, myData.xmax, myData.ymin, myData.ymax, wbord, wbord + ecran1.width, hbar, hbar + ecran1.height) 490 | e2 = newE2 491 | ecran1.width = newE1 492 | drawAll() 493 | } 494 | return 495 | } 496 | 497 | switch (true) { 498 | case (mouse.pos == 'menubar'): { 499 | var numBtn = '' 500 | // on ne fait rien : pas de menu bar dans cette version 501 | break 502 | } 503 | case (mouse.pos == 'msgbar'): { 504 | break 505 | } 506 | case (mouse.pos == 'screen1'): { 507 | if (!mouse.inDrag && !mouse.down) { 508 | mouse.pos = rechercheElementEcran1() // <<< does a lot of work !! 509 | if (mouse.pos == '') mouse.pos = 'screen1' 510 | } else { 511 | switch (true) { // mouse is in screen1 512 | case (mod.mode == 'node'): { 513 | if ((mouse.firstDrag) && (mouse.closestItem != undefined)) { 514 | if ((!mouse.control) && (!mouse.shift)) { 515 | if (mouse.posClosest != 2) { 516 | for (i = 0; i < myData.nodes.length; i++) { 517 | myData.nodes[i].selected = false 518 | myData.nodes[i].popup = undefined 519 | } 520 | } 521 | } 522 | myData.nodes[mouse.closestItem].selected = true 523 | } 524 | break 525 | } 526 | } 527 | } 528 | } 529 | 530 | case (mouse.pos == 'intbar'): { 531 | break 532 | } 533 | case (mouse.pos == 'screen2'): { 534 | break 535 | } 536 | } 537 | 538 | if ((mouse.prevPos != mouse.pos) || mouse.inDrag) { 539 | drawAll('mouse_drag') 540 | switch (true) { 541 | case (mouse.pos == 'outside'): 542 | c.style.cursor = 'auto' 543 | break 544 | case (mouse.pos == 'intbar'): 545 | c.style.cursor = 'e-resize' 546 | break 547 | default: 548 | if (mod.mode != 'zoom') c.style.cursor = 'auto' 549 | } 550 | mouse.prevPos = mouse.pos 551 | } 552 | mouse.lastX = mouse.x 553 | mouse.lastY = mouse.y 554 | showCoordinates() 555 | return false 556 | } 557 | 558 | // highlight screen 1 objects RECHERCHE ECRAN 1 559 | function rechercheElementEcran1() { 560 | var i, res, posClosest 561 | if (mod.mode != 'undefined') { 562 | var dist, minDist = 1E10, closest, pos = -1 563 | mouse.closestPolygonItem = undefined 564 | switch (true) { 565 | case (mod.mode == 'node'): { 566 | if(mouse.inDrag) { // on ne fait probablement rien 567 | } else { 568 | var numNodes = myData.nodes.length 569 | for (i = 0; i < numNodes; i++) { // chercher le noeud le plus proche 570 | myData.nodes[i].hover = false 571 | dist = objDist(mouse.x, mouse.y, myData.nodes[i]) 572 | if (dist[0] < minDist) { 573 | minDist = dist[0] 574 | posClosest = dist[1] 575 | closest = i 576 | } 577 | } 578 | // console.log('rechercheElementEcran1: ' + 'noeud le plus proche ' + closest); 579 | if ((closest >= 0) && (minDist <= MIN_DIST)) { 580 | mouse.closestItem = closest 581 | mouse.posClosest = dist[1] 582 | myData.nodes[closest].hover = true 583 | myData.nodes[closest].pos = posClosest // indique de quoi la souris est la plus proche 584 | res = mod.mode + ' ' + (closest + 1) 585 | } else { 586 | // console.log("rechercheElementEcran1: mouse is remote, replace " + mouse.closesItem + " by undefined"); 587 | mouse.closestItem = undefined 588 | res = '' 589 | } 590 | } 591 | // if (mouse.closestItem != undefined) console.log("rechercheElementEcran1: force " + mouse.closestItem + "." + mouse.posClosest); 592 | break 593 | } 594 | default: 595 | // console.log ("ERROR : " + mod.mode + " is not a recognized mode!"); 596 | } 597 | } 598 | return res 599 | } 600 | // onWheel 601 | function onWheel(evt) { 602 | if (state <= 0) return // applet inactif 603 | if (mouse.down) return // on distingue rouler et cliquer 604 | var thisWheel = new Date().getTime() 605 | if ((thisWheel - mouse.lastWheel) > 250) { 606 | mouse.lastWheel = thisWheel 607 | } else { 608 | return 609 | } 610 | if (mouse.inScreen1) { 611 | if (!mouse.disableEvents) evt.preventDefault() // je ne comprends pas cette ligne, à revoir !!! 612 | var zf = ZOOM_FACTOR 613 | if (evt.deltaY < 0) { // roule vers le haut : zoom-in 614 | } else { // roule vers le bas : zoom-out 615 | zf = 1 / zf 616 | } 617 | var newDx = (getRealX(echelle.pxmax) - echelle.xoff) * zf 618 | var newDy = (getRealY(0) - echelle.yoff) * zf 619 | var newScale = zf * echelle.scale 620 | echelle.xoff = (newScale * echelle.xoff - getRealX(mouse.x) * (newScale - echelle.scale)) / echelle.scale 621 | echelle.yoff = (newScale * echelle.yoff - getRealY(mouse.y) * (newScale - echelle.scale)) / echelle.scale 622 | echelle.xmax = echelle.xoff + newDx 623 | echelle.ymax = echelle.yoff + newDy 624 | echelle.scale = newScale 625 | var diff = hbar - hmsg 626 | myData.xmin = getRealX(wbord) 627 | myData.xmax = getRealX(wbord + ecran1.width) 628 | myData.ymin = getRealY(hmsg + ecran1.height + diff) 629 | myData.ymax = getRealY(hmsg + diff) 630 | drawAll() 631 | } 632 | } 633 | // returns correct mouse coordinates 634 | function getMousePos(c, evt) { 635 | // necessary to take into account CSS boudaries 636 | var rect = c.getBoundingClientRect() 637 | return { 638 | x: Math.round(evt.clientX - rect.left), 639 | y: Math.round(evt.clientY - rect.top) 640 | } 641 | } 642 | // create a copy of the current nodes (including displacements under way -- mouseMove) 643 | function getCurrentNodes() { 644 | var num = myData.nodes.length 645 | var n = [] 646 | var i 647 | var dx = mouse.dispX * echelle.scale 648 | var dy = -mouse.dispY * echelle.scale 649 | 650 | var stretchFactor = mouse.stretchFactor 651 | var angle = 180 / Math.PI * mouse.deltAngle 652 | var num = myData.nodes.length 653 | for (i = 0; i < num; i++) { 654 | n[i] = [] 655 | n[i].num = myData.nodes[i].num 656 | n[i].x = myData.nodes[i].x 657 | n[i].y = myData.nodes[i].y 658 | n[i].selected = myData.nodes[i].selected 659 | n[i].hover = myData.nodes[i].hover 660 | 661 | if (!mod.passage && (mod.mode == 'node') && ((n[i].selected) || (n[i].hover))) { 662 | n[i].x += dx 663 | n[i].y += dy 664 | n[i].selected = false // jusqu'à ce qu'on ait fait passer toutes les fonctions à utiliser une copie... 665 | n[i].hover = false // jusqu'à ce qu'on ait fait passer toutes les fonctions à utiliser une copie... 666 | } 667 | 668 | // console.log ( n[i].num + " : " + n[i].x + " , " + n[i].y);¨ 669 | } 670 | return n 671 | } 672 | 673 | // draws all screen components DRAW ALL 674 | function drawAll(obj) { 675 | var thisDraw = new Date().getTime() 676 | if (((mouse.inScreen1) && ((thisDraw - lastDraw) > 10)) || !mouse.inScreen1) { 677 | mouse.lastDrawX = mouse.x 678 | mouse.lastDrawY = mouse.y 679 | draw() 680 | drawNodes() 681 | showMessage() 682 | showCoordinates() 683 | 684 | lastDraw = thisDraw 685 | doRedraw = false 686 | } 687 | } 688 | // Draw method updates the canvas with the current display 689 | function draw() { 690 | // menu bar area 691 | ctx.save() 692 | ctx.beginPath() 693 | ctx.moveTo(0, 0) 694 | ctx.lineTo(w, 0) 695 | ctx.lineTo(w, hbar) 696 | ctx.lineTo(0, hbar) 697 | ctx.closePath() 698 | setColor(col.toolbar, 0, true) 699 | ctx.fill() 700 | // message bar area 701 | ctx.beginPath() 702 | ctx.moveTo(0, htot - hmsg) 703 | ctx.lineTo(w, htot - hmsg) 704 | ctx.lineTo(w, htot) 705 | ctx.lineTo(0, htot) 706 | ctx.closePath() 707 | setColor(col.statusbar, 0, true) 708 | ctx.fill() 709 | 710 | // left border 711 | ctx.beginPath() 712 | ctx.moveTo(0, hbar) 713 | ctx.lineTo(wbord, hbar) 714 | ctx.lineTo(wbord, h - hmsg) 715 | ctx.lineTo(0, h - hmsg) 716 | ctx.closePath() 717 | setColor(col.applet, 0, true) 718 | ctx.fill() 719 | 720 | // intermediate border 721 | ctx.beginPath() 722 | ctx.moveTo(wtot - wbord - wint - e2, hbar) 723 | ctx.lineTo(wtot - wbord - e2, hbar) 724 | ctx.lineTo(wtot - wbord - e2, htot - hmsg) 725 | ctx.lineTo(wtot - wbord - wint - e2, htot - hmsg) 726 | ctx.closePath() 727 | setColor(col.separator, 0, true) 728 | ctx.fill() 729 | 730 | // right border 731 | ctx.beginPath() 732 | ctx.moveTo(wtot - wbord, hbar) 733 | ctx.lineTo(wtot, hbar) 734 | ctx.lineTo(wtot, htot - hmsg) 735 | ctx.lineTo(wtot - wbord, htot - hmsg) 736 | ctx.closePath() 737 | setColor(col.applet, 0, true) 738 | ctx.fill() 739 | 740 | // outline 741 | ctx.beginPath() 742 | ctx.moveTo(1, 1) 743 | ctx.lineTo(w - 1, 1) 744 | ctx.lineTo(w - 1, h - 1) 745 | ctx.lineTo(1, h - 1) 746 | ctx.closePath() 747 | setColor(col.screen, 1, false) 748 | ctx.stroke() 749 | 750 | // inside of left screen 751 | ctx.beginPath() 752 | ctx.moveTo(wbord + 1, hbar + 1) 753 | ctx.lineTo(wtot - wbord - e2 - wint - 1, hbar + 1) 754 | ctx.lineTo(wtot - wbord - e2 - wint - 1, htot - hmsg - 1) 755 | ctx.lineTo(wbord + 1, htot - hmsg - 1) 756 | ctx.closePath() 757 | setColor(col.screen, 0, true) 758 | ctx.fill() 759 | // drawBackground() 760 | 761 | // inside of right screen 762 | ctx.beginPath() 763 | ctx.moveTo(wtot - wbord - e2 + 2, hbar + 2) 764 | ctx.lineTo(wtot - wbord - 2, hbar + 2) 765 | ctx.lineTo(wtot - wbord - 2, htot - hmsg - 2) 766 | ctx.lineTo(wtot - wbord - e2 + 2, htot - hmsg - 2) 767 | ctx.closePath() 768 | setColor(col.screen2, 0, true) 769 | ctx.fill() 770 | // outline of left screen 771 | ctx.beginPath() 772 | ctx.moveTo(wbord, hbar) 773 | ctx.lineTo(wtot - wbord - e2 - wint, hbar) 774 | ctx.lineTo(wtot - wbord - e2 - wint, htot - hmsg) 775 | ctx.lineTo(wbord, htot - hmsg) 776 | ctx.closePath() 777 | // ctx.strokeStyle = "red"; 778 | 779 | ctx.stroke() 780 | 781 | // outline of right screen 782 | ctx.beginPath() 783 | ctx.moveTo(wtot - wbord - e2 + 1, hbar + 1) 784 | ctx.lineTo(wtot - wbord - 1, hbar + 1) 785 | ctx.lineTo(wtot - wbord - 1, htot - hmsg - 1) 786 | ctx.lineTo(wtot - wbord - e2 + 1, htot - hmsg - 1) 787 | ctx.closePath() 788 | setColor(col.screen, 1, true) 789 | ctx.stroke() 790 | 791 | // limits of extents 792 | // console.log("x : " + getScreenX(myData.xmin) + " à " + getScreenX(myData.xmax) + " y :" + getScreenY(myData.ymin) + " à " + getScreenY(myData.ymax)); 793 | ctx.beginPath() 794 | ctx.moveTo(getScreenX(myData.xmin), getScreenY(myData.ymin)) 795 | ctx.lineTo(getScreenX(myData.xmax), getScreenY(myData.ymin)) 796 | ctx.lineTo(getScreenX(myData.xmax), getScreenY(myData.ymax)) 797 | ctx.lineTo(getScreenX(myData.xmin), getScreenY(myData.ymax)) 798 | ctx.closePath() 799 | ctx.strokeStyle = 'red' 800 | // ctx.stroke(); 801 | 802 | ctx.restore() 803 | } 804 | 805 | // draw nodes 806 | function drawNodes() { 807 | var i 808 | if ((myData.nodes == undefined) || (myData.nodes == [])) { return } 809 | var numNodes = myData.nodes.length 810 | var px, py 811 | ctx.save() 812 | ctx.beginPath() 813 | ctx.rect(wbord + 1, hbar + 1, ecran1.width, ecran1.height) 814 | ctx.clip() 815 | if (numNodes > 0) { 816 | for (i = 0; i < numNodes; i++) { 817 | px = getScreenX(myData.nodes[i].x) 818 | py = getScreenY(myData.nodes[i].y) 819 | if (mouse.inDrag && myData.nodes[i].hover && mod.mode == 'node') { 820 | px += mouse.x - mouse.startX 821 | py += mouse.y - mouse.startY 822 | } 823 | var colNode = col.node.split(',') 824 | var coulFond = colNode[1] 825 | if (myData.nodes[i].hover && mod.mode == 'node') coulFond = colNode[2] 826 | if (myData.nodes[i].selected && mod.mode == 'node') coulFond = colNode[3] 827 | // console.log("drawSupports: " + col.support[1] + ", " + coulFond); 828 | drawNode(px, py, colNode[0], coulFond, 0) 829 | if (mod.numbers) { 830 | drawText(px + 1.3 * 4, py - 1.3 * 4, (i + 1)) 831 | } 832 | } 833 | } 834 | ctx.restore() 835 | } 836 | 837 | // draw a node 838 | function drawNode(px, py, couleur, couleurFond, type) { 839 | var ax = [] 840 | var ay = [] 841 | var i 842 | var taille = 4 // en fait demi-taille du noeud 843 | 844 | ctx.save() 845 | 846 | ax[0] = px + taille 847 | ay[0] = py + taille 848 | ax[1] = px + taille 849 | ay[1] = py - taille 850 | ax[2] = px - taille 851 | ay[2] = py - taille 852 | ax[3] = px - taille 853 | ay[3] = py + taille 854 | ax[4] = ax[0] 855 | ay[4] = ay[0] 856 | 857 | // ctx.fillStyle = couleurFond; 858 | // ctx.strokeStyle = couleur; 859 | ctx.beginPath() 860 | ctx.moveTo(ax[0], ay[0]) 861 | ctx.lineTo(ax[1], ay[1]) 862 | ctx.lineTo(ax[2], ay[2]) 863 | ctx.lineTo(ax[3], ay[3]) 864 | ctx.lineTo(ax[4], ay[4]) 865 | setColor(couleurFond, 0, true) 866 | ctx.fill() 867 | setColor(couleur, 0, false) 868 | ctx.stroke() 869 | 870 | ctx.restore() 871 | } 872 | // draws a text 873 | function drawText(px, py, s) { 874 | ctx.save() 875 | ctx.font = '12px Arial' 876 | ctx.fillText(s, px, py) 877 | ctx.restore() 878 | } 879 | 880 | // move selected nodes 881 | function moveNodes(px, py) { 882 | var i 883 | var dx = px * echelle.scale 884 | var dy = -py * echelle.scale 885 | var num = myData.nodes.length 886 | for (i = 0; i < num; i++) { 887 | if (myData.nodes[i].selected) { 888 | myData.nodes[i].x += dx 889 | myData.nodes[i].y += dy 890 | } 891 | } 892 | } 893 | 894 | // distance to object (mesurée en pixels écran) 895 | function objDist(mx, my, O) { 896 | var minDist = 100000 // devrait être plus petit ! 897 | var pos 898 | O.hover = false 899 | var px = getScreenX(O.x) 900 | var py = getScreenY(O.y) 901 | var minDist = Math.sqrt((mx - px) * (mx - px) + (my - py) * (my - py)) 902 | pos = 1 903 | return [Math.round(minDist), pos] 904 | } 905 | 906 | // creates output file 907 | function outData() { 908 | var s, d 909 | var sep = ',' 910 | d = new Date() 911 | s = '** Data file generated on ' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getFullYear() + ' at ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + '\n' 912 | s += '**i-Mesh\n' 913 | s += '*VERSION,' + version + '\n' 914 | // console.log("myData.backImage = " + myData.backImage); 915 | if (myData.backImage != undefined) { 916 | s += '*BACKIMAGE,' + myData.backImage + sep + arrondi(myData.back_xmin) + sep + arrondi(myData.back_xmax) + sep + arrondi(myData.back_ymin) + sep + arrondi(myData.back_ymax) + sep 917 | if (mod.backimage) { s += 'ON\n' } else { s += 'OFF\n' } 918 | } 919 | // OB/28.2.2016 : le +4 pour les coordonnées y n'est pas propre. Il faudrait comprendre d'où il provient... en rapport avec hbar en tout cas 920 | var diff = hbar - hmsg 921 | s += '*EXTENTS' + sep + arrondi(getRealX(wbord)) + sep + arrondi(getRealX(wbord + ecran1.width)) + sep + arrondi(getRealY(hmsg + ecran1.height + diff)) + sep + arrondi(getRealY(hmsg + diff)) + '\n' 922 | if ((myData.supports != null) && (myData.supports.length > 0)) { 923 | s += '*SUPPORTS\n' 924 | for (var i = 0; i < myData.supports.length; i++) { s += arrondi(myData.supports[i].x) + sep + arrondi(myData.supports[i].y) + sep + 'ux=0;uy=0' + sep + myData.supports[i].attrib + sep + '\n' } 925 | } 926 | if ((myData.echelleForces != null) && (myData.echelleForces)) { s += '*ECHELLEFORCES' + sep + arrondi(myData.echelleForces) + '\n' } 927 | if ((myData.forces != null) && (myData.forces.length > 0)) { 928 | s += '*FORCES\n' 929 | for (i = 0; i < myData.forces.length; i++) { 930 | if (!isNaN(myData.forces[i].Fx + myData.forces[i].Fy)) { s += arrondi(myData.forces[i].x) + sep + arrondi(myData.forces[i].y) + sep + arrondi(myData.forces[i].Fx) + sep + arrondi(myData.forces[i].Fy) + sep + '\n' } 931 | } 932 | } 933 | if (mod.resultant) { s += '*RESULTANT' + sep + 'ON' + '\n' } 934 | if (mod.showEp) { s += '*SHOWEP' + sep + 'ON' + '\n' } 935 | if (myData.resmat != undefined) { s += '*RESMAT' + sep + arrondi(myData.resmat) + '\n' } 936 | if (myData.epaisseur != undefined) { s += '*EPAISSEUR' + sep + arrondi(myData.epaisseur) + '\n' } 937 | if (myData.subsystem != undefined) { 938 | s += '*SUBSYSTEM\n' 939 | for (i = 0; i < myData.subsystem.length; i++) { s += arrondi(myData.subsystem[i].x) + sep + arrondi(myData.subsystem[i].y) + sep } 940 | s += '\n' 941 | } 942 | if ((myData.compressionLine != null) && (myData.compressionLine.length > 0)) { 943 | s += '*COMPRESSIONLINE\n' 944 | for (i = 0; i < myData.compressionLine.length; i++) { 945 | var tmp = myData.compressionLine[i].x1 + myData.compressionLine[i].y1 + myData.compressionLine[i].x2 + myData.compressionLine[i].y2 946 | if (!isNaN(tmp)) { s += arrondi(myData.compressionLine[i].x1) + sep + arrondi(myData.compressionLine[i].y1) + sep + arrondi(myData.compressionLine[i].x2) + sep + arrondi(myData.compressionLine[i].y2) + sep + '\n' } 947 | } 948 | } 949 | if ((myData.tensionLine != null) && (myData.tensionLine.length > 0)) { 950 | s += '*TENSIONLINE\n' 951 | for (i = 0; i < myData.tensionLine.length; i++) { 952 | var tmp = myData.tensionLine[i].x1 + myData.tensionLine[i].y1 + myData.tensionLine[i].x2 + myData.tensionLine[i].y2 953 | if (!isNaN(tmp)) { s += arrondi(myData.tensionLine[i].x1) + sep + arrondi(myData.tensionLine[i].y1) + sep + arrondi(myData.tensionLine[i].x2) + sep + arrondi(myData.tensionLine[i].y2) + sep + '\n' } 954 | } 955 | } 956 | if ((myData.polygon != undefined) && mod.polygon) { 957 | s += '*POLYGON' + sep + myData.modeConstruction + sep + sep + arrondi(myData.angle_0) + sep + arrondi(myData.angle_1) + sep + arrondi(myData.passageX) + sep + arrondi(myData.passageY) + sep + arrondi(myData.lTot) + sep + '\n' 958 | if (myData.funicular != undefined) { 959 | // console.log("effort dans tie / strut " + arrondi(myData.funicular[numForces + 1].effort)); 960 | var last = myData.forces.length 961 | if (myData.supports[1].attrib != 0) last++ 962 | s += '*FUNICULAR\n' 963 | for (i = 0; i <= last; i++) { 964 | if (myData.funicular[i] != undefined) { 965 | s += arrondi(myData.funicular[i].x1) + sep + arrondi(myData.funicular[i].y1) + sep + arrondi(myData.funicular[i].x2) + sep + arrondi(myData.funicular[i].y2) + sep + arrondi(myData.funicular[i].effort) + sep + sep 966 | if (i < last) s += '\n' 967 | } 968 | } 969 | } 970 | } 971 | s += '\n*END' 972 | var goOn = true 973 | while (goOn) { 974 | s = s.replace('\n\n', '\n') 975 | if (s.indexOf('\n\n') == -1) { goOn = false } 976 | } 977 | return s 978 | } 979 | // set or unsets options 980 | 981 | // shows current mouse coordinates on the right of the message bar 982 | function showMessage() { 983 | ctx.save() 984 | // message bar area 985 | ctx.beginPath() 986 | ctx.moveTo(wbord, htot - hmsg + 3) 987 | ctx.lineTo(wtot - 15 - wCoo, htot - hmsg + 3) 988 | ctx.lineTo(wtot - 15 - wCoo, htot - 5) 989 | ctx.lineTo(wbord, htot - 5) 990 | ctx.closePath() 991 | // console.log((wtot - 10 - wCoo) + ", " + (htot - 1)); 992 | if (inputChanged) { setColor(col.statusbar, 2, true) } else { setColor(col.statusbar, 0, true) } 993 | setColor(col.statusbar, 1, false) 994 | // ctx.fillStyle = 'yellow'; 995 | ctx.fill() 996 | // ctx.strokeStyle = 'green'; 997 | ctx.stroke() 998 | if (curMessage === undefined) { return } 999 | ctx.font = '10pt Arial' 1000 | ctx.align = 'LEFT' 1001 | setColor(col.statusinput, 1, true) 1002 | ctx.fillText(curMessage, wbord + 8, htot - hmsg / 2 + 3) 1003 | ctx.restore() 1004 | } 1005 | // shows current mouse coordinates on the right of the message bar 1006 | function showCoordinates(what) { 1007 | ctx.save() 1008 | // message bar area 1009 | ctx.beginPath() 1010 | ctx.moveTo(wtot - wbord - wCoo - 3, htot - hmsg + 3) 1011 | ctx.lineTo(wtot - wbord, htot - hmsg + 3) 1012 | ctx.lineTo(wtot - wbord, htot - 5) 1013 | ctx.lineTo(wtot - wbord - wCoo - 3, htot - 5) 1014 | ctx.closePath() 1015 | setColor(col.statusbar, 9, true) 1016 | ctx.fill() 1017 | setColor(col.statusbar, 1, false) 1018 | ctx.stroke() 1019 | ctx.font = '8pt Arial' 1020 | setColor(col.statusbar, 1, true) 1021 | switch (true) { 1022 | case (what == 'paintCount'): { 1023 | message = numPaint.n 1024 | break 1025 | } 1026 | case (what == 'mousepos'): { 1027 | message = mouse.pos 1028 | break 1029 | } 1030 | default: { 1031 | if (mouse.inScreen1) { var message = arrondi(getRealX(mouse.x), 3) + ',' + arrondi(getRealY(mouse.y), 3) } else { var message = mouse.x + ',' + mouse.y } 1032 | break 1033 | } 1034 | } 1035 | ctx.fillText(message, wtot - wbord - wCoo + (wCoo - ctx.measureText(message).width) / 2, htot - hmsg / 2 + 4) 1036 | ctx.restore() 1037 | } 1038 | // defines the scaling between screen and real world 1039 | function computeScale(xmin, xmax, ymin, ymax, pxmin, pxmax, pymin, pymax) { 1040 | var echelle = [] 1041 | echelle.xoff = xmin 1042 | echelle.xmax = xmax 1043 | echelle.yoff = ymin 1044 | echelle.ymax = ymax 1045 | echelle.pxoff = pxmin 1046 | echelle.pyoff = pymax - pymin 1047 | echelle.pymax = pymax 1048 | echelle.pymax = pymax 1049 | echelle.pxmax = pxmax 1050 | // console.log ('computeScale: " +xmin + "," + ymin + " " + xmax + "," + ymax + " -- " + pxmin + "," + pymin + " " + pxmax + "," + pymax); 1051 | var scalex = (xmax - xmin) / (pxmax - pxmin) 1052 | var scaley = (ymax - ymin) / echelle.pyoff 1053 | // console.log (scalex + " " + scaley); 1054 | if (scalex > scaley) { 1055 | echelle.scale = scalex 1056 | echelle.yoff -= (echelle.pyoff * echelle.scale - (ymax - ymin)) / 2 1057 | } else { 1058 | echelle.scale = scaley 1059 | echelle.xoff -= ((pxmax - pxmin) * echelle.scale - (xmax - xmin)) / 2 1060 | // console.log(echelle.xoff); 1061 | } 1062 | return echelle 1063 | } 1064 | // get screen x-coordinate from real location 1065 | function getScreenX(x, ech) { 1066 | if (ech == undefined) ech = echelle 1067 | return Math.round(((x - ech.xoff) / ech.scale) + ech.pxoff) 1068 | } 1069 | // get screen y-coordinate from real location 1070 | function getScreenY(y, ech) { 1071 | if (ech == undefined) ech = echelle 1072 | return Math.round(ech.pymax - (y - ech.yoff) / ech.scale) 1073 | } 1074 | // get real-world x-coordinate from screen location 1075 | function getRealX(px, ech) { 1076 | if (ech == undefined) ech = echelle 1077 | var val = (px - ech.pxoff) * ech.scale + ech.xoff 1078 | // val = arrondi(val,digitsGeom ) 1079 | return val 1080 | } 1081 | // get real-world y-coordinate from screen location 1082 | function getRealY(py, ech) { 1083 | if (ech == undefined) ech = echelle 1084 | var val = (ech.pymax - py) * ech.scale + ech.yoff, digitsGeom 1085 | return val 1086 | } 1087 | // round of to a prescribed number of significant digits 1088 | function arrondi(x, digits) { 1089 | if (digits == undefined) digits = 3 1090 | // if (isNaN(x)) return NaN; 1091 | // if (x == '') return NaN; 1092 | // var mult = Math.pow(10, digits); 1093 | // console.log(x + ", " + digits + ", " + mult + " --> " + Math.round(x * mult) + " " + (x * mult) / mult); 1094 | // return Math.round(x * mult) / mult; 1095 | return formatEng(x, digits + 1) 1096 | } 1097 | // formats a number in flexible manner, with a given number of significant digits 1098 | function formatEng(x, digits) { 1099 | if (x == 0) return '0' 1100 | if (x >= 0) { 1101 | var sign = 1 1102 | var res = '' 1103 | } else { 1104 | var sign = -1 1105 | var res = '-' 1106 | } 1107 | var exp = Math.floor(Math.log(Math.abs(x)) / Math.LN10) 1108 | var mant = Math.round(sign * x / Math.pow(10, (exp - digits + 1))) / Math.pow(10, digits - 1) 1109 | // console.log (mant.toFixed(3) + "e" + exp); 1110 | 1111 | if ((exp >= -1) && (exp < digits)) { // afichage "normal" --> tout est OK ici 1112 | res += trimZeroes((mant * Math.pow(10, exp)).toFixed(digits - exp - 1)) 1113 | } else { 1114 | var modu = Math.abs(exp) % 3 1115 | if (exp > 0) { // nombres trop grands pour l'affichage normal --> tout est OK ici 1116 | var tmp = digits - modu - 1 1117 | if (tmp < 0) tmp = 0 1118 | res += trimZeroes((mant * Math.pow(10, modu)).toFixed(tmp)) + 'e' + (exp - modu) 1119 | } else { 1120 | var tmp = digits - modu 1121 | if (tmp < 0) tmp = 0 1122 | var fact = 3 - modu 1123 | if (fact == 3) fact = 0 1124 | tmp = digits - fact - 1 1125 | if (tmp < 0) tmp = 0 1126 | // console.log(" modu = " + modu + " fact " + fact + " tmp " + tmp); 1127 | res += trimZeroes((mant * Math.pow(10, fact)).toFixed(tmp)) + 'e' + (exp - fact) // + " modu = " + modu + " fact " + fact + " tmp " + tmp; 1128 | } 1129 | } 1130 | return res 1131 | } 1132 | // removes trailing zeros after decimal point in number string. Also removes the decimal point if unnecessary 1133 | function trimZeroes(s) { 1134 | var i = s.length - 1 1135 | if (s.indexOf('.') == -1) return s // pas de point décimal 1136 | while (s.charAt(i) == '0') { i-- } 1137 | if (s.charAt(i) == '.') { i-- } 1138 | // var t = s.slice(0,i+1); 1139 | // console.log("trimZeroes: " + s + " --> " + t); 1140 | return s.slice(0, i + 1) 1141 | } 1142 | // returns the angle of a vector 1143 | function atanYX(x, y) { 1144 | var val = 0 1145 | if (Math.abs(x) < minDouble) { // quasi vertical 1146 | if (y > 0) val = Math.PI / 2 1147 | else val = -Math.PI / 2 1148 | } else { 1149 | if (x < 0) { 1150 | if (y >= 0) { val = Math.PI / 2 + Math.atan(-x / y) } else val = -Math.PI / 2 - Math.atan(x / y) 1151 | } else 1152 | if (y >= 0) val = Math.atan(y / x) 1153 | else val = -Math.atan(-y / x) 1154 | } 1155 | return val 1156 | } 1157 | // intersection de deux lignes d'action 1158 | function intersection(x1, y1, f1, x2, y2, f2) { 1159 | // retourne le paramètre "k" localisant le point d'intersection 1160 | // de deux droites définies chacune par un point et un vecteur (force) 1161 | var det = (-f1.Fx * f2.Fy + f2.Fx * f1.Fy) 1162 | var k 1163 | if (Math.abs(det) >= 1.0E-10) { k = ((x1 - x2) * f2.Fy - (y1 - y2) * f2.Fx) / det } 1164 | if (debug) { 1165 | var inter = [] 1166 | inter.x = x1 + k * f1.Fx 1167 | inter.y = y1 + k * f1.Fy 1168 | console.log('intersection à (' + arrondi(inter.x) + ',' + arrondi(inter.y) + ') k = ' + arrondi(k) + ' ' + arrondi(x1) + ',' + arrondi(y1) + ' [' + arrondi(f1.Fx) + ',' + arrondi(f1.Fy) + '] ' + arrondi(x2) + ',' + arrondi(y2) + ' [' + arrondi(f2.Fx) + ',' + arrondi(f2.Fy) + ']') 1169 | } 1170 | // k est 'undefined' si le déterminant est nul 1171 | return k 1172 | } 1173 | // sets the drawing color and transparency 1174 | function setColor(couleur, index, doFill, alpha) { 1175 | var tmp = couleur 1176 | if (couleur.indexOf(',') < 0) { 1177 | tmp = couleur 1178 | } else { 1179 | var coulMat = couleur.split(',') 1180 | tmp = coulMat[0] 1181 | } 1182 | // console.log("setColor: color is '" + tmp + "'"); 1183 | if (tmp == undefined) { 1184 | tmp = 'lightgreen' 1185 | console.log('request for undefined color') 1186 | console.trace() 1187 | } 1188 | if (doFill == undefined) { doFill = false } 1189 | var pos = tmp.indexOf(';') 1190 | if (pos < 0) { 1191 | if (alpha != undefined) ctx.globalAlpha = alpha 1192 | if (doFill) { ctx.fillStyle = tmp } else { ctx.strokeStyle = tmp } 1193 | } else { 1194 | var vals = tmp.split(';') 1195 | if (vals.length == 2) { // nom de couleur + transparence 1196 | if (alpha == undefined) alpha = 1 * vals[1] // la valeur d'alpha du fichier n'est valable que si elle n'a pas été spécifiée lors de l'appel) 1197 | if (doFill) { ctx.fillStyle = vals[0] } else { ctx.strokeStyle = vals[0] } 1198 | ctx.globalAlpha = alpha 1199 | } else { 1200 | tmp = 'rgb(' + vals[0] + ',' + vals[1] + ',' + vals[2] + ')' 1201 | // paramètres de couleur RGB 1202 | if (doFill) { ctx.fillStyle = tmp } else { ctx.strokeStyle = tmp } 1203 | if (vals.length == 4) { // RGB + transparence 1204 | if (alpha) { ctx.globalAlpha = alpha } else { ctx.globalAlpha = vals[3] } 1205 | } 1206 | } 1207 | } 1208 | } 1209 | 1210 | // Public properties and methods of the iMini object 1211 | 1212 | this.width = 300 1213 | this.height = 150 1214 | // this.maxValue; 1215 | this.margin = 5 1216 | 1217 | // initialize the iMini object 1218 | this.initialize = function () { 1219 | init() 1220 | xbarmin = wtot - wbord - e2 - wint 1221 | xbarmax = xbarmin + wint 1222 | 1223 | myData.xmin = 0 1224 | myData.xmax = 100 1225 | myData.ymin = 0 1226 | myData.ymax = 20 1227 | echelle = computeScale(myData.xmin, myData.xmax, myData.ymin, myData.ymax, wbord, wbord + ecran1.width, hbar, hbar + ecran1.height) 1228 | ecran1.realXmin = getRealX(wbord) 1229 | ecran1.realXmax = getRealX(wbord + ecran1.width) 1230 | ecran1.realYmax = getRealY(hbar) // min et max sont inversés car l'axe y de l'écran est dans l'autre sens 1231 | ecran1.realYmin = getRealY(hbar + ecran1.height) 1232 | 1233 | // couleurs 1234 | col.applet = 'LightGray' 1235 | col.screen = 'White,Black' 1236 | col.screen2 = 'Gray,Black' 1237 | col.separator = 'LightGray' 1238 | col.toolbar = 'LightGray,Black' 1239 | col.statusbar = 'LightGray,Gray,Yellow' 1240 | col.statusinput = 'LightGray,Black' 1241 | col.node = 'black,white,magenta,red,green' 1242 | } 1243 | // update method paint all screen components 1244 | this.update = function () { 1245 | drawAll('update') 1246 | } 1247 | // set active mode 1248 | this.setMod = function (mode) { 1249 | mod.mode = mode 1250 | } 1251 | // set numbering 1252 | this.setNumbers = function (num) { 1253 | mod.numbers = num 1254 | } 1255 | } 1256 | -------------------------------------------------------------------------------- /docs/static/js/app.0ae67d59941939740643.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///static/js/app.0ae67d59941939740643.js","webpack:///./src/App.vue?fc6a","webpack:///./src/main.js","webpack:///App.vue","webpack:///Drawable.vue","webpack:///./src/assets/logo.png","webpack:///./src/components/Drawable.vue?d2eb","webpack:///./src/components/Drawable.vue?b6a7","webpack:///./src/App.vue?844d"],"names":["webpackJsonp","24","module","exports","__webpack_require__","injectStyle","ssrContext","Component","26","__webpack_exports__","Object","defineProperty","value","__WEBPACK_IMPORTED_MODULE_0_vue__","__WEBPACK_IMPORTED_MODULE_1__App__","__WEBPACK_IMPORTED_MODULE_1__App___default","n","config","productionTip","el","template","components","App","a","27","__WEBPACK_IMPORTED_MODULE_0__components_Drawable__","__WEBPACK_IMPORTED_MODULE_0__components_Drawable___default","name","Drawable","28","__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator__","__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator___default","mounted","this","canvas","$refs","context","getContext","drawAllNodes","data","canvasHeight","canvasWidth","overPoint","dragMode","pointSize","strokeStyle","fillStyle","points","x","y","computed","methods","removePoint","index","splice","clear","matchPoints","checkPoint","mousePoint","clearRect","clearPoints","getMousePos","evt","rect","getBoundingClientRect","parseInt","clientX","left","right","clientY","top","bottom","mouseup","event","mouseUpPoint","dragPoint","addNode","selectedPoint","newPoint","_this","map","pointToMove","mousemove","point","mousedown","isMouseOnNode","_iteratorNormalCompletion","_didIteratorError","_iteratorError","undefined","_step","_iterator","next","done","iteratedPoint","err","return","save","drawNode","restore","push","beginPath","moveTo","lineTo","fill","stroke","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_iterator2","59","60","61","62","63","render","_vm","_h","$createElement","_c","_self","staticClass","_v","on","click","directives","rawName","expression","attrs","type","domProps","input","$event","target","composing","modifiers","number","_n","blur","$forceUpdate","ref","width","height","_m","_l","key","_s","staticRenderFns","64","id","src"],"mappings":"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","file":"static/js/app.0ae67d59941939740643.js","sourcesContent":["webpackJsonp([1],{\n\n/***/ 24:\n/***/ (function(module, exports, __webpack_require__) {\n\nfunction injectStyle (ssrContext) {\n __webpack_require__(60)\n}\nvar Component = __webpack_require__(23)(\n /* script */\n __webpack_require__(27),\n /* template */\n __webpack_require__(64),\n /* styles */\n injectStyle,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n\n/***/ 26:\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(25);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App__ = __webpack_require__(24);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__App__);\n\n\n\n\n__WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */].config.productionTip = false;\n\nnew __WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */]({\n el: '#app',\n template: '',\n components: { App: __WEBPACK_IMPORTED_MODULE_1__App___default.a }\n});\n\n/***/ }),\n\n/***/ 27:\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_Drawable__ = __webpack_require__(62);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_Drawable___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__components_Drawable__);\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'app',\n components: {\n Drawable: __WEBPACK_IMPORTED_MODULE_0__components_Drawable___default.a\n }\n});\n\n/***/ }),\n\n/***/ 28:\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator__ = __webpack_require__(29);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator__);\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n mounted: function mounted() {\n this.canvas = this.$refs.canvas;\n this.context = this.canvas.getContext('2d');\n this.drawAllNodes();\n },\n data: function data() {\n return {\n canvas: {},\n context: {},\n canvasHeight: 350,\n canvasWidth: 450,\n\n overPoint: null,\n dragMode: false,\n\n pointSize: 7,\n strokeStyle: 'darkgrey',\n fillStyle: '#fff',\n points: [{ x: 100, y: 100 }, { x: 200, y: 100 }, { x: 100, y: 200 }, { x: 200, y: 200 }]\n };\n },\n\n computed: {},\n methods: {\n removePoint: function removePoint(index) {\n this.points.splice(index, 1);\n this.clear();\n this.drawAllNodes();\n },\n matchPoints: function matchPoints(checkPoint, mousePoint) {\n if (mousePoint.x > checkPoint.x + this.pointSize) {\n return false;\n }\n\n if (mousePoint.x < checkPoint.x - this.pointSize) {\n return false;\n }\n\n if (mousePoint.y > checkPoint.y + this.pointSize) {\n return false;\n }\n\n if (mousePoint.y < checkPoint.y - this.pointSize) {\n return false;\n }\n return true;\n },\n clear: function clear() {\n this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);\n },\n clearPoints: function clearPoints() {\n this.points = [];\n this.clear();\n },\n getMousePos: function getMousePos(evt) {\n var rect = this.context.canvas.getBoundingClientRect();\n return {\n x: parseInt((evt.clientX - rect.left) / (rect.right - rect.left) * this.canvasWidth),\n y: parseInt((evt.clientY - rect.top) / (rect.bottom - rect.top) * this.canvasHeight)\n };\n },\n mouseup: function mouseup(event) {\n var mouseUpPoint = this.getMousePos(event);\n if (this.dragMode && this.overPoint) {\n this.dragPoint(this.overPoint, mouseUpPoint);\n this.dragMode = false;\n } else {\n this.addNode(mouseUpPoint);\n }\n },\n dragPoint: function dragPoint(selectedPoint, newPoint) {\n var _this = this;\n\n this.points.map(function (pointToMove) {\n if (pointToMove.x === selectedPoint.x && pointToMove.y === selectedPoint.y) {\n pointToMove.x = newPoint.x;\n pointToMove.y = newPoint.y;\n\n _this.clear();\n _this.drawAllNodes();\n }\n });\n },\n mousemove: function mousemove(event) {\n var point = this.getMousePos(event);\n\n if (this.dragMode && this.overPoint) {\n this.dragPoint(this.overPoint, point);\n }\n },\n mousedown: function mousedown(event) {\n var point = this.getMousePos(event);\n if (this.isMouseOnNode(point)) {\n this.dragMode = true;\n } else {\n this.dragMode = false;\n }\n },\n isMouseOnNode: function isMouseOnNode(point) {\n return this.selectedPoint(point) !== null;\n },\n selectedPoint: function selectedPoint(point) {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator___default()(this.points), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var iteratedPoint = _step.value;\n\n if (this.matchPoints(iteratedPoint, point)) {\n this.overPoint = iteratedPoint;\n return iteratedPoint;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n this.overPoint = null;\n return null;\n },\n addNode: function addNode(point) {\n this.context.save();\n this.drawNode(point);\n this.context.restore();\n this.points.push(point);\n },\n drawNode: function drawNode(point) {\n this.context.beginPath();\n this.context.moveTo(point.x - this.pointSize, point.y - this.pointSize);\n this.context.lineTo(point.x - this.pointSize, point.y + this.pointSize);\n this.context.lineTo(point.x + this.pointSize, point.y + this.pointSize);\n this.context.lineTo(point.x + this.pointSize, point.y - this.pointSize);\n this.context.lineTo(point.x - this.pointSize, point.y - this.pointSize);\n this.context.fillStyle = this.fillStyle;\n this.context.fill();\n this.context.strokeStyle = this.strokeStyle;\n this.context.stroke();\n },\n drawAllNodes: function drawAllNodes() {\n this.context.save();\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_get_iterator___default()(this.points), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var point = _step2.value;\n\n this.drawNode(point);\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n this.context.restore();\n }\n }\n});\n\n/***/ }),\n\n/***/ 59:\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n\n/***/ 60:\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n\n/***/ 61:\n/***/ (function(module, exports) {\n\nmodule.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd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\"\n\n/***/ }),\n\n/***/ 62:\n/***/ (function(module, exports, __webpack_require__) {\n\nfunction injectStyle (ssrContext) {\n __webpack_require__(59)\n}\nvar Component = __webpack_require__(23)(\n /* script */\n __webpack_require__(28),\n /* template */\n __webpack_require__(63),\n /* styles */\n injectStyle,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n/***/ }),\n\n/***/ 63:\n/***/ (function(module, exports) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"flex\"\n }, [_c('div', [_c('h2', [_vm._v(\"Canavas properties\")]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Actions:\")]), _vm._v(\" \"), _c('button', {\n on: {\n \"click\": _vm.drawAllNodes\n }\n }, [_vm._v(\"drawAllNodes\")]), _vm._v(\" \"), _c('button', {\n on: {\n \"click\": _vm.clear\n }\n }, [_vm._v(\"clear canvas (not points)\")]), _vm._v(\" \"), _c('button', {\n on: {\n \"click\": _vm.clearPoints\n }\n }, [_vm._v(\"clear points\")])]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Size:\")]), _vm._v(\" \"), _c('ul', [_c('li', [_c('label', [_vm._v(\"Width: \")]), _vm._v(\" \"), _c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.canvasWidth),\n expression: \"canvasWidth\"\n }],\n attrs: {\n \"type\": \"text\"\n },\n domProps: {\n \"value\": (_vm.canvasWidth)\n },\n on: {\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.canvasWidth = $event.target.value\n }\n }\n })]), _vm._v(\" \"), _c('li', [_c('label', [_vm._v(\"Height: \")]), _vm._v(\" \"), _c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.canvasHeight),\n expression: \"canvasHeight\"\n }],\n attrs: {\n \"type\": \"text\"\n },\n domProps: {\n \"value\": (_vm.canvasHeight)\n },\n on: {\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.canvasHeight = $event.target.value\n }\n }\n })])])]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Points properties:\")]), _vm._v(\" \"), _c('label', [_vm._v(\"Point Size\")]), _vm._v(\" \"), _c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model.number\",\n value: (_vm.pointSize),\n expression: \"pointSize\",\n modifiers: {\n \"number\": true\n }\n }],\n attrs: {\n \"type\": \"number\"\n },\n domProps: {\n \"value\": (_vm.pointSize)\n },\n on: {\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.pointSize = _vm._n($event.target.value)\n },\n \"blur\": function($event) {\n _vm.$forceUpdate()\n }\n }\n })])]), _vm._v(\" \"), _c('div', [_c('canvas', {\n ref: \"canvas\",\n attrs: {\n \"width\": _vm.canvasWidth,\n \"height\": _vm.canvasHeight\n },\n on: {\n \"mousedown\": _vm.mousedown,\n \"mouseup\": _vm.mouseup,\n \"mousemove\": _vm.mousemove\n }\n })]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Points (data)\")]), _vm._v(\" \"), _c('table', {\n staticClass: \"ui selectable table\"\n }, [_vm._m(0), _vm._v(\" \"), _c('tbody', _vm._l((_vm.points), function(point, index) {\n return _c('tr', {\n key: point\n }, [_c('td', [_vm._v(_vm._s(index + 1))]), _vm._v(\" \"), _c('td', [_vm._v(_vm._s(point.x))]), _vm._v(\" \"), _c('td', [_vm._v(_vm._s(point.y))]), _vm._v(\" \"), _c('td', [_c('button', {\n on: {\n \"click\": function($event) {\n _vm.removePoint(index)\n }\n }\n }, [_vm._v(\"X\")])])])\n }))])]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Test data\")]), _vm._v(\" \"), _c('label', [_vm._v(\"OverPoint:\")]), _vm._v(\" \"), _c('pre', [_vm._v(_vm._s(_vm.overPoint))])])])\n},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('thead', [_c('tr', [_c('th', [_vm._v(\"N°\")]), _c('th', [_vm._v(\"X\")]), _c('th', [_vm._v(\"Y\")]), _c('th', [_vm._v(\"Remove\")])])])\n}]}\n\n/***/ }),\n\n/***/ 64:\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"ui\",\n attrs: {\n \"id\": \"app\"\n }\n }, [_vm._m(0), _vm._v(\" \"), _c('drawable')], 1)\n},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('h1', [_vm._v(\"This is a drawable canvas with \"), _c('img', {\n attrs: {\n \"src\": __webpack_require__(61),\n \"width\": \"30px\"\n }\n })])\n}]}\n\n/***/ })\n\n},[26]);\n\n\n// WEBPACK FOOTER //\n// static/js/app.0ae67d59941939740643.js","function injectStyle (ssrContext) {\n require(\"!!../node_modules/extract-text-webpack-plugin/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-c08a3a3a\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../node_modules/vue-loader/lib/selector?type=styles&index=0!./App.vue\")\n}\nvar Component = require(\"!../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../node_modules/vue-loader/lib/selector?type=script&index=0!./App.vue\"),\n /* template */\n require(\"!!../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-c08a3a3a\\\"}!../node_modules/vue-loader/lib/selector?type=template&index=0!./App.vue\"),\n /* styles */\n injectStyle,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/App.vue\n// module id = 24\n// module chunks = 1","// The Vue build version to load with the `import` command\r\n// (runtime-only or standalone) has been set in webpack.base.conf with an alias.\r\nimport Vue from 'vue'\r\nimport App from './App'\r\n\r\nVue.config.productionTip = false\r\n\r\n/* eslint-disable no-new */\r\nnew Vue({\r\n el: '#app',\r\n template: '',\r\n components: { App }\r\n})\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","\r\n\r\n\r\n\r\n\r\n\n\n\n// WEBPACK FOOTER //\n// App.vue?56ff5a76","\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// Drawable.vue?16721f1e","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd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\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/logo.png\n// module id = 61\n// module chunks = 1","function injectStyle (ssrContext) {\n require(\"!!../../node_modules/extract-text-webpack-plugin/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-628a2d79\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./Drawable.vue\")\n}\nvar Component = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")(\n /* script */\n require(\"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./Drawable.vue\"),\n /* template */\n require(\"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-628a2d79\\\"}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./Drawable.vue\"),\n /* styles */\n injectStyle,\n /* scopeId */\n null,\n /* moduleIdentifier (server only) */\n null\n)\n\nmodule.exports = Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/Drawable.vue\n// module id = 62\n// module chunks = 1","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"flex\"\n }, [_c('div', [_c('h2', [_vm._v(\"Canavas properties\")]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Actions:\")]), _vm._v(\" \"), _c('button', {\n on: {\n \"click\": _vm.drawAllNodes\n }\n }, [_vm._v(\"drawAllNodes\")]), _vm._v(\" \"), _c('button', {\n on: {\n \"click\": _vm.clear\n }\n }, [_vm._v(\"clear canvas (not points)\")]), _vm._v(\" \"), _c('button', {\n on: {\n \"click\": _vm.clearPoints\n }\n }, [_vm._v(\"clear points\")])]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Size:\")]), _vm._v(\" \"), _c('ul', [_c('li', [_c('label', [_vm._v(\"Width: \")]), _vm._v(\" \"), _c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.canvasWidth),\n expression: \"canvasWidth\"\n }],\n attrs: {\n \"type\": \"text\"\n },\n domProps: {\n \"value\": (_vm.canvasWidth)\n },\n on: {\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.canvasWidth = $event.target.value\n }\n }\n })]), _vm._v(\" \"), _c('li', [_c('label', [_vm._v(\"Height: \")]), _vm._v(\" \"), _c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model\",\n value: (_vm.canvasHeight),\n expression: \"canvasHeight\"\n }],\n attrs: {\n \"type\": \"text\"\n },\n domProps: {\n \"value\": (_vm.canvasHeight)\n },\n on: {\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.canvasHeight = $event.target.value\n }\n }\n })])])]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Points properties:\")]), _vm._v(\" \"), _c('label', [_vm._v(\"Point Size\")]), _vm._v(\" \"), _c('input', {\n directives: [{\n name: \"model\",\n rawName: \"v-model.number\",\n value: (_vm.pointSize),\n expression: \"pointSize\",\n modifiers: {\n \"number\": true\n }\n }],\n attrs: {\n \"type\": \"number\"\n },\n domProps: {\n \"value\": (_vm.pointSize)\n },\n on: {\n \"input\": function($event) {\n if ($event.target.composing) { return; }\n _vm.pointSize = _vm._n($event.target.value)\n },\n \"blur\": function($event) {\n _vm.$forceUpdate()\n }\n }\n })])]), _vm._v(\" \"), _c('div', [_c('canvas', {\n ref: \"canvas\",\n attrs: {\n \"width\": _vm.canvasWidth,\n \"height\": _vm.canvasHeight\n },\n on: {\n \"mousedown\": _vm.mousedown,\n \"mouseup\": _vm.mouseup,\n \"mousemove\": _vm.mousemove\n }\n })]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Points (data)\")]), _vm._v(\" \"), _c('table', {\n staticClass: \"ui selectable table\"\n }, [_vm._m(0), _vm._v(\" \"), _c('tbody', _vm._l((_vm.points), function(point, index) {\n return _c('tr', {\n key: point\n }, [_c('td', [_vm._v(_vm._s(index + 1))]), _vm._v(\" \"), _c('td', [_vm._v(_vm._s(point.x))]), _vm._v(\" \"), _c('td', [_vm._v(_vm._s(point.y))]), _vm._v(\" \"), _c('td', [_c('button', {\n on: {\n \"click\": function($event) {\n _vm.removePoint(index)\n }\n }\n }, [_vm._v(\"X\")])])])\n }))])]), _vm._v(\" \"), _c('div', [_c('h3', [_vm._v(\"Test data\")]), _vm._v(\" \"), _c('label', [_vm._v(\"OverPoint:\")]), _vm._v(\" \"), _c('pre', [_vm._v(_vm._s(_vm.overPoint))])])])\n},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('thead', [_c('tr', [_c('th', [_vm._v(\"N°\")]), _c('th', [_vm._v(\"X\")]), _c('th', [_vm._v(\"Y\")]), _c('th', [_vm._v(\"Remove\")])])])\n}]}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-628a2d79\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/Drawable.vue\n// module id = 63\n// module chunks = 1","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"ui\",\n attrs: {\n \"id\": \"app\"\n }\n }, [_vm._m(0), _vm._v(\" \"), _c('drawable')], 1)\n},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('h1', [_vm._v(\"This is a drawable canvas with \"), _c('img', {\n attrs: {\n \"src\": require(\"./assets/logo.png\"),\n \"width\": \"30px\"\n }\n })])\n}]}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-c08a3a3a\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/App.vue\n// module id = 64\n// module chunks = 1"],"sourceRoot":""} --------------------------------------------------------------------------------