Integrated eslint and reformatted all of the JS/TS
This commit is contained in:
82
.eslintrc.yml
Normal file
82
.eslintrc.yml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
env:
|
||||||
|
es2021: true
|
||||||
|
node: true
|
||||||
|
browser: true
|
||||||
|
extends:
|
||||||
|
- eslint:recommended
|
||||||
|
- plugin:@typescript-eslint/recommended
|
||||||
|
overrides: []
|
||||||
|
parser: "@typescript-eslint/parser"
|
||||||
|
parserOptions:
|
||||||
|
ecmaVersion: latest
|
||||||
|
sourceType: module
|
||||||
|
plugins:
|
||||||
|
- "@typescript-eslint"
|
||||||
|
globals:
|
||||||
|
Vue: readonly
|
||||||
|
THREE: readonly
|
||||||
|
SvelteComponents: readonly
|
||||||
|
$: readonly
|
||||||
|
Clusterize: readonly
|
||||||
|
SockJS: readonly
|
||||||
|
rules:
|
||||||
|
indent:
|
||||||
|
- off
|
||||||
|
"@typescript-eslint/indent":
|
||||||
|
- error
|
||||||
|
- 4
|
||||||
|
linebreak-style:
|
||||||
|
- error
|
||||||
|
- unix
|
||||||
|
quotes:
|
||||||
|
- error
|
||||||
|
- double
|
||||||
|
- allowTemplateLiterals: true
|
||||||
|
avoidEscape: true
|
||||||
|
semi:
|
||||||
|
- error
|
||||||
|
- always
|
||||||
|
"@typescript-eslint/no-explicit-any":
|
||||||
|
- off
|
||||||
|
"@typescript-eslint/no-unused-vars":
|
||||||
|
- error
|
||||||
|
- argsIgnorePattern: _.*
|
||||||
|
no-unused-vars:
|
||||||
|
- error
|
||||||
|
no-trailing-spaces:
|
||||||
|
- error
|
||||||
|
key-spacing:
|
||||||
|
- error
|
||||||
|
space-before-blocks:
|
||||||
|
- error
|
||||||
|
block-spacing:
|
||||||
|
- error
|
||||||
|
brace-style:
|
||||||
|
- error
|
||||||
|
curly:
|
||||||
|
- error
|
||||||
|
keyword-spacing:
|
||||||
|
- error
|
||||||
|
"@typescript-eslint/no-var-requires":
|
||||||
|
- off
|
||||||
|
no-multiple-empty-lines:
|
||||||
|
- error
|
||||||
|
- max: 1
|
||||||
|
func-call-spacing:
|
||||||
|
- error
|
||||||
|
- never
|
||||||
|
padding-line-between-statements:
|
||||||
|
- error
|
||||||
|
- blankLine: always
|
||||||
|
prev: function
|
||||||
|
next: function
|
||||||
|
no-var:
|
||||||
|
- error
|
||||||
|
no-unused-expressions:
|
||||||
|
- error
|
||||||
|
prefer-const:
|
||||||
|
- error
|
||||||
|
prefer-template:
|
||||||
|
- error
|
||||||
|
template-curly-spacing:
|
||||||
|
- error
|
||||||
2914
package-lock.json
generated
2914
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,14 @@
|
|||||||
"postinstall": "cd src/svelte-components && npm i"
|
"postinstall": "cd src/svelte-components && npm i"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||||
|
"@typescript-eslint/parser": "^5.36.1",
|
||||||
"browserify": "^17.0.0",
|
"browserify": "^17.0.0",
|
||||||
|
"eslint": "^8.23.0",
|
||||||
|
"eslint-config-standard-with-typescript": "^22.0.0",
|
||||||
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
"eslint-plugin-n": "^15.2.5",
|
||||||
|
"eslint-plugin-promise": "^6.0.1",
|
||||||
"jshint": "^2.13.4",
|
"jshint": "^2.13.4",
|
||||||
"jstransformer-escape-html": "^1.1.0",
|
"jstransformer-escape-html": "^1.1.0",
|
||||||
"jstransformer-scss": "^2.0.0",
|
"jstransformer-scss": "^2.0.0",
|
||||||
|
|||||||
@@ -1,32 +1,6 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
const api = require("./api");
|
||||||
const merge = require("lodash.merge");
|
const merge = require("lodash.merge");
|
||||||
|
|
||||||
const config_defaults = require("../resources/onefinity_defaults.json");
|
const config_defaults = require("../resources/onefinity_defaults.json");
|
||||||
@@ -38,34 +12,32 @@ const variant_defaults = {
|
|||||||
journeyman_x50: require("../resources/onefinity_journeyman_x50_defaults.json")
|
journeyman_x50: require("../resources/onefinity_journeyman_x50_defaults.json")
|
||||||
};
|
};
|
||||||
|
|
||||||
const api = require('./api');
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#admin-general-view-template',
|
template: "#admin-general-view-template",
|
||||||
props: ['config', 'state'],
|
props: ["config", "state"],
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
confirmReset: false,
|
confirmReset: false,
|
||||||
autoCheckUpgrade: true,
|
autoCheckUpgrade: true,
|
||||||
reset_variant: ''
|
reset_variant: ""
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
ready: function () {
|
ready: function () {
|
||||||
this.autoCheckUpgrade = this.config.admin['auto-check-upgrade']
|
this.autoCheckUpgrade = this.config.admin["auto-check-upgrade"];
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
backup: function () {
|
backup: function () {
|
||||||
document.getElementById('download-target').src = '/api/config/download';
|
document.getElementById("download-target").src = "/api/config/download";
|
||||||
},
|
},
|
||||||
|
|
||||||
restore_config: function () {
|
restore_config: function () {
|
||||||
// If we don't reset the form the browser may cache file if name is same
|
// If we don't reset the form the browser may cache file if name is same
|
||||||
// even if contents have changed
|
// even if contents have changed
|
||||||
$('.restore-config')[0].reset();
|
$(".restore-config")[0].reset();
|
||||||
$('.restore-config input').click();
|
$(".restore-config input").click();
|
||||||
},
|
},
|
||||||
|
|
||||||
restore: function (e) {
|
restore: function (e) {
|
||||||
@@ -85,13 +57,16 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.put('config/save', config);
|
await api.put("config/save", config);
|
||||||
this.$dispatch('update');
|
this.$dispatch("update");
|
||||||
SvelteComponents.showDialog("Message", { title: "Success", message: "Configuration restored" })
|
SvelteComponents.showDialog("Message", {
|
||||||
|
title: "Success",
|
||||||
|
message: "Configuration restored"
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
api.alert('Restore failed', error);
|
api.alert("Restore failed", error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fileReader.readAsText(files[0]);
|
fileReader.readAsText(files[0]);
|
||||||
},
|
},
|
||||||
@@ -104,40 +79,45 @@ module.exports = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.put('config/save', config)
|
await api.put("config/save", config);
|
||||||
this.confirmReset = false;
|
this.confirmReset = false;
|
||||||
this.$dispatch('update');
|
this.$dispatch("update");
|
||||||
SvelteComponents.showDialog("Message", { title: "Success", message: "Configuration restored" })
|
SvelteComponents.showDialog("Message", {
|
||||||
|
title: "Success",
|
||||||
|
message: "Configuration restored"
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
api.alert('Restore failed');
|
api.alert("Restore failed");
|
||||||
console.error('Restore failed', err);
|
console.error("Restore failed", err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
check: function () {
|
check: function () {
|
||||||
this.$dispatch('check')
|
this.$dispatch("check");
|
||||||
},
|
},
|
||||||
|
|
||||||
upgrade: function () {
|
upgrade: function () {
|
||||||
this.$dispatch('upgrade')
|
this.$dispatch("upgrade");
|
||||||
},
|
},
|
||||||
|
|
||||||
upload_firmware: function () {
|
upload_firmware: function () {
|
||||||
// If we don't reset the form the browser may cache file if name is same
|
// If we don't reset the form the browser may cache file if name is same
|
||||||
// even if contents have changed
|
// even if contents have changed
|
||||||
$('.upload-firmware')[0].reset();
|
$(".upload-firmware")[0].reset();
|
||||||
$('.upload-firmware input').click();
|
$(".upload-firmware input").click();
|
||||||
},
|
},
|
||||||
|
|
||||||
upload: function (e) {
|
upload: function (e) {
|
||||||
var files = e.target.files || e.dataTransfer.files;
|
const files = e.target.files || e.dataTransfer.files;
|
||||||
if (!files.length) return;
|
if (!files.length) {
|
||||||
this.$dispatch('upload', files[0]);
|
return;
|
||||||
|
}
|
||||||
|
this.$dispatch("upload", files[0]);
|
||||||
},
|
},
|
||||||
|
|
||||||
change_auto_check_upgrade: function () {
|
change_auto_check_upgrade: function () {
|
||||||
this.config.admin['auto-check-upgrade'] = this.autoCheckUpgrade;
|
this.config.admin["auto-check-upgrade"] = this.autoCheckUpgrade;
|
||||||
this.$dispatch('config-changed');
|
this.$dispatch("config-changed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,77 +1,37 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
|
async function callApi(method, url, body) {
|
||||||
function api_cb(method, url, data, config) {
|
try {
|
||||||
config = $.extend({
|
const response = await fetch(`/api/${url}`, {
|
||||||
type: method,
|
method,
|
||||||
url: '/api/' + url,
|
headers: {
|
||||||
dataType: 'json',
|
"Content-Type": "application/json"
|
||||||
cache: false
|
},
|
||||||
}, config);
|
body
|
||||||
|
|
||||||
if (typeof data == 'object') {
|
|
||||||
config.data = JSON.stringify(data);
|
|
||||||
config.contentType = 'application/json; charset=utf-8';
|
|
||||||
}
|
|
||||||
|
|
||||||
var d = $.Deferred();
|
|
||||||
|
|
||||||
$.ajax(config).success(function (data, status, xhr) {
|
|
||||||
d.resolve(data, status, xhr);
|
|
||||||
|
|
||||||
}).error(function (xhr, status, error) {
|
|
||||||
var text = xhr.responseText;
|
|
||||||
try {text = $.parseJSON(xhr.responseText)} catch(e) {}
|
|
||||||
if (!text) text = error;
|
|
||||||
|
|
||||||
d.reject(text, xhr, status, error);
|
|
||||||
console.debug('API Error: ' + url + ': ' + text);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return d.promise();
|
if (response.ok) {
|
||||||
}
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(await response.text());
|
||||||
|
} catch (error) {
|
||||||
|
console.debug(`API Error: ${url}: ${error}`);
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get: function (url, config) {
|
get: function (url) {
|
||||||
return api_cb('GET', url, undefined, config);
|
return callApi("GET", url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
put: function(url, body = undefined) {
|
||||||
put: function(url, data, config) {
|
return callApi("PUT", url, body);
|
||||||
return api_cb('PUT', url, data, config);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
delete: function (url) {
|
||||||
post: function(url, data, config) {
|
return callApi("DELETE", url);
|
||||||
return api_cb('POST', url, data, config);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
upload: function(url, data, config) {
|
|
||||||
config = $.extend({
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
cache: false,
|
|
||||||
data: data
|
|
||||||
}, config);
|
|
||||||
|
|
||||||
return api_cb('PUT', url, undefined, config);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
'delete': function (url, config) {
|
|
||||||
return api_cb('DELETE', url, undefined, config);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
alert: function (msg, error) {
|
|
||||||
if (typeof error != 'undefined') {
|
|
||||||
if (typeof error.message != 'undefined')
|
|
||||||
msg += '\n' + error.message;
|
|
||||||
else msg += '\n' + JSON.stringify(error);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
alert(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ function is_newer_version(current, latest) {
|
|||||||
const patch = latestParts[3] - currentParts[3];
|
const patch = latestParts[3] - currentParts[3];
|
||||||
|
|
||||||
// If current is a pre-release, and latest is a release
|
// If current is a pre-release, and latest is a release
|
||||||
const betaToRelease =
|
const betaToRelease = latestParts[4].length === 0 && currentParts[4].length > 0;
|
||||||
latestParts[4].length === 0 && currentParts[4].length > 0;
|
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case major > 0:
|
case major > 0:
|
||||||
@@ -41,24 +40,36 @@ function is_newer_version(current, latest) {
|
|||||||
function is_object(o) {
|
function is_object(o) {
|
||||||
return o !== null && typeof o == "object";
|
return o !== null && typeof o == "object";
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_array(o) {
|
function is_array(o) {
|
||||||
return Array.isArray(o);
|
return Array.isArray(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_array(dst, src) {
|
function update_array(dst, src) {
|
||||||
while (dst.length) dst.pop();
|
while (dst.length) {
|
||||||
for (var i = 0; i < src.length; i++) Vue.set(dst, i, src[i]);
|
dst.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < src.length; i++) {
|
||||||
|
Vue.set(dst, i, src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasOwnProperty(obj, key) {
|
||||||
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_object(dst, src, remove) {
|
function update_object(dst, src, remove) {
|
||||||
var props, index, key, value;
|
let props, index, key, value;
|
||||||
|
|
||||||
if (remove) {
|
if (remove) {
|
||||||
props = Object.getOwnPropertyNames(dst);
|
props = Object.getOwnPropertyNames(dst);
|
||||||
|
|
||||||
for (index in props) {
|
for (index in props) {
|
||||||
key = props[index];
|
key = props[index];
|
||||||
if (!src.hasOwnProperty(key)) Vue.delete(dst, key);
|
if (!hasOwnProperty(src, key)) {
|
||||||
|
Vue.delete(dst, key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,11 +78,13 @@ function update_object(dst, src, remove) {
|
|||||||
key = props[index];
|
key = props[index];
|
||||||
value = src[key];
|
value = src[key];
|
||||||
|
|
||||||
if (is_array(value) && dst.hasOwnProperty(key) && is_array(dst[key]))
|
if (is_array(value) && hasOwnProperty(dst, key) && is_array(dst[key])) {
|
||||||
update_array(dst[key], value);
|
update_array(dst[key], value);
|
||||||
else if (is_object(value) && dst.hasOwnProperty(key) && is_object(dst[key]))
|
} else if (is_object(value) && hasOwnProperty(dst, key) && is_object(dst[key])) {
|
||||||
update_object(dst[key], value, remove);
|
update_object(dst[key], value, remove);
|
||||||
else Vue.set(dst, key, value);
|
} else {
|
||||||
|
Vue.set(dst, key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +194,9 @@ module.exports = new Vue({
|
|||||||
|
|
||||||
error: function (msg) {
|
error: function (msg) {
|
||||||
// Honor user error blocking
|
// Honor user error blocking
|
||||||
if (Date.now() - this.errorTimeoutStart < this.errorTimeout * 1000)
|
if (Date.now() - this.errorTimeoutStart < this.errorTimeout * 1000) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait at least 1 sec to pop up repeated errors
|
// Wait at least 1 sec to pop up repeated errors
|
||||||
if (1 < msg.repeat && Date.now() - msg.ts < 1000) {
|
if (1 < msg.repeat && Date.now() - msg.ts < 1000) {
|
||||||
@@ -225,9 +239,12 @@ module.exports = new Vue({
|
|||||||
this.errorShow = false;
|
this.errorShow = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle_video: function (e) {
|
toggle_video: function () {
|
||||||
if (this.video_size == "small") this.video_size = "large";
|
if (this.video_size == "small") {
|
||||||
else if (this.video_size == "large") this.video_size = "small";
|
this.video_size = "large";
|
||||||
|
} else if (this.video_size == "large") {
|
||||||
|
this.video_size = "small";
|
||||||
|
}
|
||||||
cookie.set("video-size", this.video_size);
|
cookie.set("video-size", this.video_size);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -238,8 +255,11 @@ module.exports = new Vue({
|
|||||||
},
|
},
|
||||||
|
|
||||||
estop: function () {
|
estop: function () {
|
||||||
if (this.state.xx == "ESTOPPED") api.put("clear");
|
if (this.state.xx == "ESTOPPED") {
|
||||||
else api.put("estop");
|
api.put("clear");
|
||||||
|
} else {
|
||||||
|
api.put("estop");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
upgrade_confirmed: async function () {
|
upgrade_confirmed: async function () {
|
||||||
@@ -302,8 +322,10 @@ module.exports = new Vue({
|
|||||||
if (!this.checkedUpgrade) {
|
if (!this.checkedUpgrade) {
|
||||||
this.checkedUpgrade = true;
|
this.checkedUpgrade = true;
|
||||||
|
|
||||||
var check = this.config.admin["auto-check-upgrade"];
|
const check = this.config.admin["auto-check-upgrade"];
|
||||||
if (typeof check == "undefined" || check) this.$emit("check");
|
if (typeof check == "undefined" || check) {
|
||||||
|
this.$emit("check");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SvelteComponents.handleConfigUpdate(this.config);
|
SvelteComponents.handleConfigUpdate(this.config);
|
||||||
@@ -328,10 +350,7 @@ module.exports = new Vue({
|
|||||||
if (typeof this.sid == "undefined") {
|
if (typeof this.sid == "undefined") {
|
||||||
this.sid = e.data.sid;
|
this.sid = e.data.sid;
|
||||||
} else if (this.sid != e.data.sid) {
|
} else if (this.sid != e.data.sid) {
|
||||||
if (
|
if (this.hostname && location.hostname !== "localhost") {
|
||||||
typeof this.hostname !== "undefined" &&
|
|
||||||
location.hostname !== "localhost"
|
|
||||||
) {
|
|
||||||
location.hostname = this.hostname;
|
location.hostname = this.hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,16 +381,18 @@ module.exports = new Vue({
|
|||||||
},
|
},
|
||||||
|
|
||||||
parse_hash: function () {
|
parse_hash: function () {
|
||||||
var hash = location.hash.substr(1);
|
const hash = location.hash.substr(1);
|
||||||
|
|
||||||
if (!hash.trim().length) {
|
if (!hash.trim().length) {
|
||||||
location.hash = "control";
|
location.hash = "control";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parts = hash.split(":");
|
const parts = hash.split(":");
|
||||||
|
|
||||||
if (parts.length == 2) this.index = parts[1];
|
if (parts.length == 2) {
|
||||||
|
this.index = parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
this.currentView = parts[0];
|
this.currentView = parts[0];
|
||||||
},
|
},
|
||||||
@@ -402,12 +423,17 @@ module.exports = new Vue({
|
|||||||
},
|
},
|
||||||
|
|
||||||
close_messages: function (action) {
|
close_messages: function (action) {
|
||||||
if (action == "stop") api.put("stop");
|
if (action == "stop") {
|
||||||
if (action == "continue") api.put("unpause");
|
api.put("stop");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == "continue") {
|
||||||
|
api.put("unpause");
|
||||||
|
}
|
||||||
|
|
||||||
// Acknowledge messages
|
// Acknowledge messages
|
||||||
if (this.state.messages.length) {
|
if (this.state.messages.length) {
|
||||||
var id = this.state.messages.slice(-1)[0].id;
|
const id = this.state.messages.slice(-1)[0].id;
|
||||||
api.put("message/" + id + "/ack");
|
api.put("message/" + id + "/ack");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,65 +1,37 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#axis-control-template',
|
template: "#axis-control-template",
|
||||||
props: ['axes', 'colors', 'enabled', 'adjust', 'step'],
|
props: ["axes", "colors", "enabled", "adjust", "step"],
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
jog: function (axis, ring, direction) {
|
jog: function (axis, ring, direction) {
|
||||||
var value = direction * this.value(ring);
|
const value = direction * this.value(ring);
|
||||||
this.$dispatch(this.step ? 'step' : 'jog', this.axes[axis], value);
|
this.$dispatch(this.step ? "step" : "jog", this.axes[axis], value);
|
||||||
},
|
},
|
||||||
|
|
||||||
back2zero: function(axis0,axis1) {
|
back2zero: function(axis0,axis1) {
|
||||||
this.$dispatch('back2zero',this.axes[axis0],this.axes[axis1])
|
this.$dispatch("back2zero",this.axes[axis0],this.axes[axis1]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
release: function (axis) {
|
release: function (axis) {
|
||||||
if (!this.step) this.$dispatch('jog', this.axes[axis], 0)
|
if (!this.step) {
|
||||||
|
this.$dispatch("jog", this.axes[axis], 0);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
value: function (ring) {
|
value: function (ring) {
|
||||||
var adjust = [0.01, 0.1, 1][this.adjust];
|
const adjust = [0.01, 0.1, 1][this.adjust];
|
||||||
if (this.step) return adjust * [0.1, 1, 10, 100][ring];
|
if (this.step) {
|
||||||
|
return adjust * [0.1, 1, 10, 100][ring];
|
||||||
|
}
|
||||||
return adjust * [0.1, 0.25, 0.5, 1][ring];
|
return adjust * [0.1, 0.25, 0.5, 1][ring];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
text: function (ring) {
|
text: function (ring) {
|
||||||
var value = this.value(ring) * (this.step ? 1 : 100);
|
let value = this.value(ring) * (this.step ? 1 : 100);
|
||||||
value = parseFloat(value.toFixed(3));
|
value = parseFloat(value.toFixed(3));
|
||||||
return value + (this.step ? '' : '%');
|
return value + (this.step ? "" : "%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,17 +1,40 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
props: ['state', 'config'],
|
props: ["state", "config"],
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
metric: function () { this.$root.display_units === "METRIC" },
|
metric: function () {
|
||||||
x: function () { return this._compute_axis('x') },
|
return this.$root.display_units === "METRIC";
|
||||||
y: function () { return this._compute_axis('y') },
|
},
|
||||||
z: function () { return this._compute_axis('z') },
|
|
||||||
a: function () { return this._compute_axis('a') },
|
x: function () {
|
||||||
b: function () { return this._compute_axis('b') },
|
return this._compute_axis("x");
|
||||||
c: function () { return this._compute_axis('c') },
|
},
|
||||||
axes: function () { return this._compute_axes() }
|
|
||||||
|
y: function () {
|
||||||
|
return this._compute_axis("y");
|
||||||
|
},
|
||||||
|
|
||||||
|
z: function () {
|
||||||
|
return this._compute_axis("z");
|
||||||
|
},
|
||||||
|
|
||||||
|
a: function () {
|
||||||
|
return this._compute_axis("a");
|
||||||
|
},
|
||||||
|
|
||||||
|
b: function () {
|
||||||
|
return this._compute_axis("b");
|
||||||
|
},
|
||||||
|
|
||||||
|
c: function () {
|
||||||
|
return this._compute_axis("c");
|
||||||
|
},
|
||||||
|
|
||||||
|
axes: function () {
|
||||||
|
return this._compute_axes();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -22,98 +45,115 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_length_str: function (value) {
|
_length_str: function (value) {
|
||||||
return this._convert_length(value).toLocaleString() +
|
return this._convert_length(value).toLocaleString() + (this.metric ? " mm" : " in");
|
||||||
(this.metric ? ' mm' : ' in');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_compute_axis: function (axis) {
|
_compute_axis: function (axis) {
|
||||||
var abs = this.state[axis + 'p'] || 0;
|
const abs = this.state[`${axis}p`] || 0;
|
||||||
var off = this.state['offset_' + axis];
|
const off = this.state[`offset_${axis}`];
|
||||||
var motor_id = this._get_motor_id(axis);
|
const motor_id = this._get_motor_id(axis);
|
||||||
var motor = motor_id == -1 ? {} : this.config.motors[motor_id];
|
const motor = motor_id == -1 ? {} : this.config.motors[motor_id];
|
||||||
var enabled = typeof motor.enabled != 'undefined' && motor.enabled;
|
const enabled = typeof motor.enabled != "undefined" && motor.enabled;
|
||||||
var homingMode = motor['homing-mode']
|
const homingMode = motor["homing-mode"];
|
||||||
var homed = this.state[motor_id + 'homed'];
|
const homed = this.state[`${motor_id}homed`];
|
||||||
var min = this.state[motor_id + 'tn'];
|
const min = this.state[`${motor_id}tn`];
|
||||||
var max = this.state[motor_id + 'tm'];
|
const max = this.state[`${motor_id}tm`];
|
||||||
var dim = max - min;
|
const dim = max - min;
|
||||||
var pathMin = this.state['path_min_' + axis];
|
const pathMin = this.state[`path_min_${axis}`];
|
||||||
var pathMax = this.state['path_max_' + axis];
|
const pathMax = this.state[`path_max_${axis}`];
|
||||||
var pathDim = pathMax - pathMin;
|
const pathDim = pathMax - pathMin;
|
||||||
var under = pathMin + off < min;
|
const under = pathMin + off < min;
|
||||||
var over = max < pathMax + off;
|
const over = max < pathMax + off;
|
||||||
var klass = (homed ? 'homed' : 'unhomed') + ' axis-' + axis;
|
let klass = `${homed ? "homed" : "unhomed"} axis-${axis}`;
|
||||||
var state = 'UNHOMED';
|
let state = "UNHOMED";
|
||||||
var icon = 'question-circle';
|
let icon = "question-circle";
|
||||||
var fault = this.state[motor_id + 'df'] & 0x1f;
|
const fault = this.state[`${motor_id}df`] & 0x1f;
|
||||||
var shutdown = this.state.power_shutdown;
|
const shutdown = this.state.power_shutdown;
|
||||||
var title;
|
let title;
|
||||||
var ticon = 'question-circle';
|
let ticon = "question-circle";
|
||||||
var tstate = 'NO FILE';
|
let tstate = "NO FILE";
|
||||||
var toolmsg;
|
let toolmsg;
|
||||||
var tklass = (homed ? 'homed' : 'unhomed') + ' axis-' + axis;
|
let tklass = `${homed ? "homed" : "unhomed"} axis-${axis}`;
|
||||||
|
|
||||||
if (fault || shutdown) {
|
if (fault || shutdown) {
|
||||||
state = shutdown ? 'SHUTDOWN' : 'FAULT';
|
state = shutdown ? "SHUTDOWN" : "FAULT";
|
||||||
klass += ' error';
|
klass += " error";
|
||||||
icon = 'exclamation-circle';
|
icon = "exclamation-circle";
|
||||||
} else if (homed) {
|
} else if (homed) {
|
||||||
state = 'HOMED';
|
state = "HOMED";
|
||||||
icon = 'check-circle';
|
icon = "check-circle";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 < dim && dim < pathDim) {
|
if (0 < dim && dim < pathDim) {
|
||||||
tstate = 'NO FIT';
|
tstate = "NO FIT";
|
||||||
tklass += ' error';
|
tklass += " error";
|
||||||
ticon = 'ban';
|
ticon = "ban";
|
||||||
} else {
|
} else {
|
||||||
if (over || under) {
|
if (over || under) {
|
||||||
tstate = over ? 'OVER' : 'UNDER';
|
tstate = over ? "OVER" : "UNDER";
|
||||||
tklass += ' warn';
|
tklass += " warn";
|
||||||
ticon = 'exclamation-circle';
|
ticon = "exclamation-circle";
|
||||||
} else {
|
} else {
|
||||||
tstate = 'OK';
|
tstate = "OK";
|
||||||
ticon = 'check-circle';
|
ticon = "check-circle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'UNHOMED': title = 'Click the home button to home axis.'; break;
|
case "UNHOMED":
|
||||||
case 'HOMED': title = 'Axis successfuly homed.'; break;
|
title = "Click the home button to home axis.";
|
||||||
case 'FAULT':
|
|
||||||
title = 'Motor driver fault. A potentially damaging electrical ' +
|
|
||||||
'condition was detected and the motor driver was shutdown. ' +
|
|
||||||
'Please power down the controller and check your motor cabling. ' +
|
|
||||||
'See the "Motor Faults" table on the "Indicators" tab for more ' +
|
|
||||||
'information.';
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SHUTDOWN':
|
case "HOMED":
|
||||||
title = 'Motor power fault. All motors in shutdown. ' +
|
title = "Axis successfuly homed.";
|
||||||
'See the "Power Faults" table on the "Indicators" tab for more ' +
|
break;
|
||||||
'information. Reboot controller to reset.';
|
|
||||||
|
case "FAULT":
|
||||||
|
title = [
|
||||||
|
`Motor driver fault. A potentially damaging electrical`,
|
||||||
|
`condition was detected and the motor driver was shutdown.`,
|
||||||
|
`Please power down the controller and check your motor cabling.`,
|
||||||
|
`See the "Motor Faults" table on the "Indicators" tab for more`,
|
||||||
|
`information.`,
|
||||||
|
].join(" ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "SHUTDOWN":
|
||||||
|
title = [
|
||||||
|
`Motor power fault. All motors in shutdown.`,
|
||||||
|
`See the "Power Faults" table on the "Indicators" tab for more`,
|
||||||
|
`information. Reboot controller to reset.`
|
||||||
|
].join(" ");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tstate) {
|
switch (tstate) {
|
||||||
case 'OVER':
|
case "OVER":
|
||||||
toolmsg = 'Caution: The current tool path file would move ' +
|
toolmsg = [
|
||||||
this._length_str(pathMax + off - max) + ' above axis limit with the current offset.';
|
`Caution: The current tool path file would move`,
|
||||||
|
`${this._length_str(pathMax + off - max)}`,
|
||||||
|
`above axis limit with the current offset.`
|
||||||
|
].join(" ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'UNDER':
|
case "UNDER":
|
||||||
toolmsg = 'Caution: The current tool path file would move ' +
|
toolmsg = [
|
||||||
this._length_str(min - pathMin - off) + ' below limit with the current offset.';
|
`Caution: The current tool path file would move`,
|
||||||
|
`${this._length_str(min - pathMin - off)}`,
|
||||||
|
`below limit with the current offset.`
|
||||||
|
].join(" ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'NO FIT':
|
case "NO FIT":
|
||||||
toolmsg = 'Warning: The current tool path dimensions (' +
|
toolmsg = [
|
||||||
this._length_str(pathDim) + ') exceed axis dimensions (' +
|
`Warning: The current tool path dimensions`,
|
||||||
this._length_str(dim) + ') by ' +
|
`(${this._length_str(pathDim)}) exceed axis dimensions`,
|
||||||
this._length_str(pathDim - dim) + '.';
|
`(${this._length_str(dim)}) by ${this._length_str(pathDim - dim)}.`
|
||||||
|
].join(" ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
toolmsg = 'Tool path ' + axis + ' dimensions OK.';
|
toolmsg = `Tool path ${axis} dimensions OK.`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,44 +179,64 @@ module.exports = {
|
|||||||
tstate: tstate,
|
tstate: tstate,
|
||||||
toolmsg: toolmsg,
|
toolmsg: toolmsg,
|
||||||
tklass: tklass
|
tklass: tklass
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_get_motor_id: function (axis) {
|
_get_motor_id: function (axis) {
|
||||||
for (var i = 0; i < this.config.motors.length; i++) {
|
for (let i = 0; i < this.config.motors.length; i++) {
|
||||||
var motor = this.config.motors[i];
|
const motor = this.config.motors[i];
|
||||||
if (motor.axis.toLowerCase() == axis) return i;
|
if (motor.axis.toLowerCase() == axis) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
_compute_axes: function () {
|
_compute_axes: function () {
|
||||||
var homed = false;
|
let homed = false;
|
||||||
|
|
||||||
for (var name of 'xyzabc') {
|
for (const name of "xyzabc") {
|
||||||
var axis = this[name];
|
const axis = this[name];
|
||||||
|
|
||||||
|
if (!axis.enabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!axis.homed) {
|
||||||
|
homed = false; break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!axis.enabled) continue
|
|
||||||
if (!axis.homed) { homed = false; break }
|
|
||||||
homed = true;
|
homed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var error = false;
|
let error = false;
|
||||||
var warn = false;
|
let warn = false;
|
||||||
|
|
||||||
if (homed)
|
if (homed) {
|
||||||
for (name of 'xyzabc') {
|
for (const name of "xyzabc") {
|
||||||
axis = this[name];
|
const axis = this[name];
|
||||||
|
|
||||||
if (!axis.enabled) continue;
|
if (!axis.enabled) {
|
||||||
if (axis.klass.indexOf('error') != -1) error = true;
|
continue;
|
||||||
if (axis.klass.indexOf('warn') != -1) warn = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var klass = homed ? 'homed' : 'unhomed';
|
if (axis.klass.indexOf("error") != -1) {
|
||||||
if (error) klass += ' error';
|
error = true;
|
||||||
else if (warn) klass += ' warn';
|
}
|
||||||
|
|
||||||
|
if (axis.klass.indexOf("warn") != -1) {
|
||||||
|
warn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let klass = homed ? "homed" : "unhomed";
|
||||||
|
if (error) {
|
||||||
|
klass += " error";
|
||||||
|
} else if (warn) {
|
||||||
|
klass += " warn";
|
||||||
|
}
|
||||||
|
|
||||||
if (!homed && this.ask_home) {
|
if (!homed && this.ask_home) {
|
||||||
this.ask_home = false;
|
this.ask_home = false;
|
||||||
@@ -188,7 +248,7 @@ module.exports = {
|
|||||||
return {
|
return {
|
||||||
homed: homed,
|
homed: homed,
|
||||||
klass: klass
|
klass: klass
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,87 +1,72 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
function _msg_equal(a, b) {
|
function _msg_equal(a, b) {
|
||||||
return a.level == b.level && a.source == b.source && a.where == b.where &&
|
return a.level == b.level
|
||||||
a.msg == b.msg;
|
&& a.source == b.source
|
||||||
|
&& a.where == b.where
|
||||||
|
&&a.msg == b.msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Shared among all instances
|
// Shared among all instances
|
||||||
var messages = [];
|
const messages = [];
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#console-template',
|
template: "#console-template",
|
||||||
|
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {messages: messages}
|
return {
|
||||||
|
messages
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
log: function (msg) {
|
log: function (msg) {
|
||||||
// There may be multiple instances of this module so ignore messages
|
// There may be multiple instances of this module so ignore messages
|
||||||
// that have already been processed.
|
// that have already been processed.
|
||||||
if (msg.logged) return;
|
if (msg.logged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
msg.logged = true;
|
msg.logged = true;
|
||||||
|
|
||||||
// Make sure we have a message level
|
// Make sure we have a message level
|
||||||
msg.level = msg.level || 'info';
|
msg.level = msg.level || "info";
|
||||||
|
|
||||||
// Add to message log and count and collapse repeats
|
// Add to message log and count and collapse repeats
|
||||||
var repeat = messages.length && _msg_equal(msg, messages[0]);
|
const repeat = messages.length && _msg_equal(msg, messages[0]);
|
||||||
if (repeat) messages[0].repeat++;
|
if (repeat) {
|
||||||
else {
|
messages[0].repeat++;
|
||||||
|
} else {
|
||||||
msg.repeat = msg.repeat || 1;
|
msg.repeat = msg.repeat || 1;
|
||||||
messages.unshift(msg);
|
messages.unshift(msg);
|
||||||
while (256 < messages.length) messages.pop();
|
while (256 < messages.length) {
|
||||||
|
messages.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msg.ts = Date.now();
|
msg.ts = Date.now();
|
||||||
|
|
||||||
// Write message to browser console for debugging
|
// Write message to browser console for debugging
|
||||||
var text = JSON.stringify(msg);
|
const text = JSON.stringify(msg);
|
||||||
if (msg.level == 'error' || msg.level == 'critical') console.error(text);
|
if (msg.level == "error" || msg.level == "critical") {
|
||||||
else if (msg.level == 'warning') console.warn(text);
|
console.error(text);
|
||||||
else if (msg.level == 'debug' && console.debug) console.debug(text);
|
} else if (msg.level == "warning") {
|
||||||
else console.log(text);
|
console.warn(text);
|
||||||
|
} else if (msg.level == "debug" && console.debug) {
|
||||||
|
console.debug(text);
|
||||||
|
} else {
|
||||||
|
console.log(text);
|
||||||
|
}
|
||||||
|
|
||||||
// Event on errors
|
// Event on errors
|
||||||
if (msg.level == 'error' || msg.level == 'critical')
|
if (msg.level == "error" || msg.level == "critical") {
|
||||||
this.$dispatch('error', msg);
|
this.$dispatch("error", msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
clear: function () {messages.splice(0, messages.length);},
|
clear: function () {
|
||||||
|
messages.splice(0, messages.length);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
var api = require('./api');
|
const api = require("./api");
|
||||||
var cookie = require('./cookie')('bbctrl-');
|
const cookie = require("./cookie")("bbctrl-");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#control-view-template',
|
template: "#control-view-template",
|
||||||
props: ['config', 'template', 'state'],
|
props: ["config", "template", "state"],
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
current_time: "",
|
current_time: "",
|
||||||
mach_units: this.$root.state.metric ? "METRIC" : "IMPERIAL",
|
mach_units: this.$root.state.metric ? "METRIC" : "IMPERIAL",
|
||||||
mdi: '',
|
mdi: "",
|
||||||
last_file: undefined,
|
last_file: undefined,
|
||||||
last_file_time: undefined,
|
last_file_time: undefined,
|
||||||
toolpath: {},
|
toolpath: {},
|
||||||
toolpath_progress: 0,
|
toolpath_progress: 0,
|
||||||
axes: 'xyzabc',
|
axes: "xyzabc",
|
||||||
history: [],
|
history: [],
|
||||||
speed_override: 1,
|
speed_override: 1,
|
||||||
feed_override: 1,
|
feed_override: 1,
|
||||||
@@ -34,20 +34,20 @@ module.exports = {
|
|||||||
large: 5,
|
large: 5,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
jog_incr: localStorage.getItem("jog_incr") || 'small',
|
jog_incr: localStorage.getItem("jog_incr") || "small",
|
||||||
jog_step: cookie.get_bool('jog-step'),
|
jog_step: cookie.get_bool("jog-step"),
|
||||||
jog_adjust: parseInt(cookie.get('jog-adjust', 2)),
|
jog_adjust: parseInt(cookie.get("jog-adjust", 2)),
|
||||||
deleteGCode: false,
|
deleteGCode: false,
|
||||||
tab: 'auto',
|
tab: "auto",
|
||||||
ask_home: true,
|
ask_home: true,
|
||||||
showGcodeMessage: false
|
showGcodeMessage: false
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
'axis-control': require('./axis-control'),
|
"axis-control": require("./axis-control"),
|
||||||
'path-viewer': require('./path-viewer'),
|
"path-viewer": require("./path-viewer"),
|
||||||
'gcode-viewer': require('./gcode-viewer')
|
"gcode-viewer": require("./gcode-viewer")
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@@ -55,31 +55,31 @@ module.exports = {
|
|||||||
localStorage.setItem("jog_incr", value);
|
localStorage.setItem("jog_incr", value);
|
||||||
},
|
},
|
||||||
|
|
||||||
'state.metric': {
|
"state.metric": {
|
||||||
handler: function (metric) {
|
handler: function (metric) {
|
||||||
this.mach_units = metric
|
this.mach_units = metric
|
||||||
? 'METRIC'
|
? "METRIC"
|
||||||
: 'IMPERIAL';
|
: "IMPERIAL";
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
|
|
||||||
'state.line': function () {
|
"state.line": function () {
|
||||||
if (this.mach_state != 'HOMING') {
|
if (this.mach_state != "HOMING") {
|
||||||
this.$broadcast('gcode-line', this.state.line);
|
this.$broadcast("gcode-line", this.state.line);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
'state.selected_time': function () {
|
"state.selected_time": function () {
|
||||||
this.load();
|
this.load();
|
||||||
},
|
},
|
||||||
|
|
||||||
jog_step: function () {
|
jog_step: function () {
|
||||||
cookie.set_bool('jog-step', this.jog_step);
|
cookie.set_bool("jog-step", this.jog_step);
|
||||||
},
|
},
|
||||||
|
|
||||||
jog_adjust: function () {
|
jog_adjust: function () {
|
||||||
cookie.set('jog-adjust', this.jog_adjust);
|
cookie.set("jog-adjust", this.jog_adjust);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -99,63 +99,61 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
mach_state: function () {
|
mach_state: function () {
|
||||||
var cycle = this.state.cycle;
|
const cycle = this.state.cycle;
|
||||||
var state = this.state.xx;
|
const state = this.state.xx;
|
||||||
|
|
||||||
if (typeof cycle != 'undefined' && state != 'ESTOPPED' &&
|
if (state != "ESTOPPED" && (cycle == "jogging" || cycle == "homing")) {
|
||||||
(cycle == 'jogging' || cycle == 'homing')) {
|
|
||||||
return cycle.toUpperCase();
|
return cycle.toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
return state || ''
|
return state || "";
|
||||||
},
|
},
|
||||||
|
|
||||||
pause_reason: function () {
|
pause_reason: function () {
|
||||||
return this.state.pr
|
return this.state.pr;
|
||||||
},
|
},
|
||||||
|
|
||||||
is_running: function () {
|
is_running: function () {
|
||||||
return this.mach_state == 'RUNNING' || this.mach_state == 'HOMING';
|
return this.mach_state == "RUNNING" || this.mach_state == "HOMING";
|
||||||
},
|
},
|
||||||
|
|
||||||
is_stopping: function () {
|
is_stopping: function () {
|
||||||
return this.mach_state == 'STOPPING'
|
return this.mach_state == "STOPPING";
|
||||||
},
|
},
|
||||||
|
|
||||||
is_holding: function () {
|
is_holding: function () {
|
||||||
return this.mach_state == 'HOLDING'
|
return this.mach_state == "HOLDING";
|
||||||
},
|
},
|
||||||
|
|
||||||
is_ready: function () {
|
is_ready: function () {
|
||||||
return this.mach_state == 'READY'
|
return this.mach_state == "READY";
|
||||||
},
|
},
|
||||||
|
|
||||||
is_idle: function () {
|
is_idle: function () {
|
||||||
return this.state.cycle == 'idle'
|
return this.state.cycle == "idle";
|
||||||
},
|
},
|
||||||
|
|
||||||
is_paused: function () {
|
is_paused: function () {
|
||||||
return this.is_holding &&
|
return this.is_holding && (this.pause_reason == "User pause" || this.pause_reason == "Program pause");
|
||||||
(this.pause_reason == 'User pause' ||
|
|
||||||
this.pause_reason == 'Program pause')
|
|
||||||
},
|
},
|
||||||
|
|
||||||
can_mdi: function () {
|
can_mdi: function () {
|
||||||
return this.is_idle || this.state.cycle == 'mdi'
|
return this.is_idle || this.state.cycle == "mdi";
|
||||||
},
|
},
|
||||||
|
|
||||||
can_set_axis: function () {
|
can_set_axis: function () {
|
||||||
return this.is_idle
|
return this.is_idle;
|
||||||
|
|
||||||
// TODO allow setting axis position during pause
|
// TODO allow setting axis position during pause
|
||||||
return this.is_idle || this.is_paused
|
// return this.is_idle || this.is_paused;
|
||||||
},
|
},
|
||||||
|
|
||||||
message: function () {
|
message: function () {
|
||||||
if (this.mach_state == 'ESTOPPED') {
|
if (this.mach_state == "ESTOPPED") {
|
||||||
return this.state.er;
|
return this.state.er;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mach_state == 'HOLDING') {
|
if (this.mach_state == "HOLDING") {
|
||||||
return this.state.pr;
|
return this.state.pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,15 +161,15 @@ module.exports = {
|
|||||||
return this.state.messages.slice(-1)[0].text;
|
return this.state.messages.slice(-1)[0].text;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return "";
|
||||||
},
|
},
|
||||||
|
|
||||||
highlight_state: function () {
|
highlight_state: function () {
|
||||||
return this.mach_state == 'ESTOPPED' || this.mach_state == 'HOLDING';
|
return this.mach_state == "ESTOPPED" || this.mach_state == "HOLDING";
|
||||||
},
|
},
|
||||||
|
|
||||||
plan_time: function () {
|
plan_time: function () {
|
||||||
return this.state.plan_time
|
return this.state.plan_time;
|
||||||
},
|
},
|
||||||
|
|
||||||
plan_time_remaining: function () {
|
plan_time_remaining: function () {
|
||||||
@@ -179,16 +177,16 @@ module.exports = {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.toolpath.time - this.plan_time
|
return this.toolpath.time - this.plan_time;
|
||||||
},
|
},
|
||||||
|
|
||||||
eta: function () {
|
eta: function () {
|
||||||
if (this.mach_state != 'RUNNING') {
|
if (this.mach_state != "RUNNING") {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
var remaining = this.plan_time_remaining;
|
const remaining = this.plan_time_remaining;
|
||||||
var d = new Date();
|
const d = new Date();
|
||||||
d.setSeconds(d.getSeconds() + remaining);
|
d.setSeconds(d.getSeconds() + remaining);
|
||||||
return d.toLocaleString();
|
return d.toLocaleString();
|
||||||
},
|
},
|
||||||
@@ -198,16 +196,16 @@ module.exports = {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var p = this.plan_time / this.toolpath.time;
|
const p = this.plan_time / this.toolpath.time;
|
||||||
return p < 1 ? p : 1;
|
return Math.max(1, p);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
jog: function (axis, power) {
|
jog: function (axis, power) {
|
||||||
var data = { ts: new Date().getTime() };
|
const data = { ts: new Date().getTime() };
|
||||||
data[axis] = power;
|
data[axis] = power;
|
||||||
api.put('jog', data);
|
api.put("jog", data);
|
||||||
},
|
},
|
||||||
|
|
||||||
back2zero: function (axis0, axis1) {
|
back2zero: function (axis0, axis1) {
|
||||||
@@ -243,19 +241,19 @@ module.exports = {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getJogIncrStyle(value) {
|
getJogIncrStyle(value) {
|
||||||
const weight = `font-weight:${this.jog_incr === value ? 'bold' : 'normal'}`;
|
const weight = `font-weight:${this.jog_incr === value ? "bold" : "normal"}`;
|
||||||
const color = this.jog_incr === value ? "color:#0078e7" : "";
|
const color = this.jog_incr === value ? "color:#0078e7" : "";
|
||||||
|
|
||||||
return [weight, color].join(';');
|
return [weight, color].join(";");
|
||||||
},
|
},
|
||||||
|
|
||||||
jog_fn: function (x_jog, y_jog, z_jog, a_jog) {
|
jog_fn: function (x_jog, y_jog, z_jog, a_jog) {
|
||||||
const amount = this.jog_incr_amounts[this.display_units][this.jog_incr];
|
const amount = this.jog_incr_amounts[this.display_units][this.jog_incr];
|
||||||
|
|
||||||
var xcmd = "X" + x_jog * amount;
|
const xcmd = `X${x_jog * amount}`;
|
||||||
var ycmd = "Y" + y_jog * amount;
|
const ycmd = `Y${y_jog * amount}`;
|
||||||
var zcmd = "Z" + z_jog * amount;
|
const zcmd = `Z${z_jog * amount}`;
|
||||||
var acmd = "A" + a_jog * amount;
|
const acmd = `A${a_jog * amount}`;
|
||||||
|
|
||||||
this.send(`
|
this.send(`
|
||||||
G91
|
G91
|
||||||
@@ -265,12 +263,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
send: function (msg) {
|
send: function (msg) {
|
||||||
this.$dispatch('send', msg)
|
this.$dispatch("send", msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function () {
|
load: function () {
|
||||||
var file_time = this.state.selected_time;
|
const file_time = this.state.selected_time;
|
||||||
var file = this.state.selected;
|
const file = this.state.selected;
|
||||||
if (this.last_file == file && this.last_file_time == file_time) {
|
if (this.last_file == file && this.last_file_time == file_time) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -278,8 +276,8 @@ module.exports = {
|
|||||||
this.last_file = file;
|
this.last_file = file;
|
||||||
this.last_file_time = file_time;
|
this.last_file_time = file_time;
|
||||||
|
|
||||||
this.$broadcast('gcode-load', file);
|
this.$broadcast("gcode-load", file);
|
||||||
this.$broadcast('gcode-line', this.state.line);
|
this.$broadcast("gcode-line", this.state.line);
|
||||||
this.toolpath_progress = 0;
|
this.toolpath_progress = 0;
|
||||||
this.load_toolpath(file, file_time);
|
this.load_toolpath(file, file_time);
|
||||||
},
|
},
|
||||||
@@ -297,8 +295,8 @@ module.exports = {
|
|||||||
const toolpath = await api.get(`path/${file}`);
|
const toolpath = await api.get(`path/${file}`);
|
||||||
this.toolpath_progress = toolpath.progress;
|
this.toolpath_progress = toolpath.progress;
|
||||||
|
|
||||||
if (toolpath.progress === 1 || typeof toolpath.progress == 'undefined') {
|
if (toolpath.progress === 1 || typeof toolpath.progress == "undefined") {
|
||||||
this.showGcodeMessage = false
|
this.showGcodeMessage = false;
|
||||||
|
|
||||||
if (toolpath.bounds) {
|
if (toolpath.bounds) {
|
||||||
toolpath.filename = file;
|
toolpath.filename = file;
|
||||||
@@ -306,9 +304,9 @@ module.exports = {
|
|||||||
this.toolpath = toolpath;
|
this.toolpath = toolpath;
|
||||||
|
|
||||||
const state = this.$root.state;
|
const state = this.$root.state;
|
||||||
for (let axis of 'xyzabc') {
|
for (const axis of "xyzabc") {
|
||||||
Vue.set(state, 'path_min_' + axis, toolpath.bounds.min[axis]);
|
Vue.set(state, `path_min_${axis}`, toolpath.bounds.min[axis]);
|
||||||
Vue.set(state, 'path_max_' + axis, toolpath.bounds.max[axis]);
|
Vue.set(state, `path_max_${axis}`, toolpath.bounds.max[axis]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,13 +320,13 @@ module.exports = {
|
|||||||
this.history.unshift(this.mdi);
|
this.history.unshift(this.mdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mdi = '';
|
this.mdi = "";
|
||||||
},
|
},
|
||||||
|
|
||||||
mdi_start_pause: function () {
|
mdi_start_pause: function () {
|
||||||
if (this.state.xx == 'RUNNING') {
|
if (this.state.xx == "RUNNING") {
|
||||||
this.pause();
|
this.pause();
|
||||||
} else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING') {
|
} else if (this.state.xx == "STOPPING" || this.state.xx == "HOLDING") {
|
||||||
this.unpause();
|
this.unpause();
|
||||||
} else {
|
} else {
|
||||||
this.submit_mdi();
|
this.submit_mdi();
|
||||||
@@ -339,11 +337,11 @@ module.exports = {
|
|||||||
this.mdi = this.history[index];
|
this.mdi = this.history[index];
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function (e) {
|
open: function () {
|
||||||
// If we don't reset the form the browser may cache file if name is same
|
// If we don't reset the form the browser may cache file if name is same
|
||||||
// even if contents have changed
|
// even if contents have changed
|
||||||
$('.gcode-file-input')[0].reset();
|
$(".gcode-file-input")[0].reset();
|
||||||
$('.gcode-file-input input').click();
|
$(".gcode-file-input input").click();
|
||||||
},
|
},
|
||||||
|
|
||||||
upload: async function (e) {
|
upload: async function (e) {
|
||||||
@@ -371,42 +369,42 @@ module.exports = {
|
|||||||
file,
|
file,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
this.last_file_time = undefined; // Force reload
|
this.last_file_time = undefined; // Force reload
|
||||||
this.$broadcast('gcode-reload', file.name);
|
this.$broadcast("gcode-reload", file.name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
delete_current: function () {
|
delete_current: function () {
|
||||||
if (this.state.selected) {
|
if (this.state.selected) {
|
||||||
api.delete('file/' + this.state.selected);
|
api.delete(`file/${this.state.selected}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.deleteGCode = false;
|
this.deleteGCode = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
delete_all: function () {
|
delete_all: function () {
|
||||||
api.delete('file');
|
api.delete("file");
|
||||||
this.deleteGCode = false;
|
this.deleteGCode = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
home: function (axis) {
|
home: function (axis) {
|
||||||
this.ask_home = false;
|
this.ask_home = false;
|
||||||
|
|
||||||
if (typeof axis == 'undefined') {
|
if (typeof axis == "undefined") {
|
||||||
api.put('home');
|
api.put("home");
|
||||||
} else if (this[axis].homingMode != 'manual') {
|
} else if (this[axis].homingMode != "manual") {
|
||||||
api.put('home/' + axis);
|
api.put(`home/${axis}`);
|
||||||
} else {
|
} else {
|
||||||
SvelteComponents.showDialog("ManualHomeAxis", { axis });
|
SvelteComponents.showDialog("ManualHomeAxis", { axis });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
set_home: function (axis, position) {
|
set_home: function (axis, position) {
|
||||||
api.put('home/' + axis + '/set', { position: parseFloat(position) });
|
api.put(`home/${axis}/set`, { position: parseFloat(position) });
|
||||||
},
|
},
|
||||||
|
|
||||||
unhome: function (axis) {
|
unhome: function (axis) {
|
||||||
api.put('home/' + axis + '/clear');
|
api.put(`home/${axis}/clear`);
|
||||||
},
|
},
|
||||||
|
|
||||||
show_set_position: function (axis) {
|
show_set_position: function (axis) {
|
||||||
@@ -422,11 +420,11 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
set_position: function (axis, position) {
|
set_position: function (axis, position) {
|
||||||
api.put('position/' + axis, { 'position': parseFloat(position) });
|
api.put(`position/${axis}`, { "position": parseFloat(position) });
|
||||||
},
|
},
|
||||||
|
|
||||||
zero_all: function () {
|
zero_all: function () {
|
||||||
for (var axis of 'xyzabc') {
|
for (const axis of "xyzabc") {
|
||||||
if (this[axis].enabled) {
|
if (this[axis].enabled) {
|
||||||
this.zero(axis);
|
this.zero(axis);
|
||||||
}
|
}
|
||||||
@@ -434,7 +432,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
zero: function (axis) {
|
zero: function (axis) {
|
||||||
if (typeof axis == 'undefined') {
|
if (typeof axis == "undefined") {
|
||||||
this.zero_all();
|
this.zero_all();
|
||||||
} else {
|
} else {
|
||||||
this.set_position(axis, 0);
|
this.set_position(axis, 0);
|
||||||
@@ -442,9 +440,9 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
start_pause: function () {
|
start_pause: function () {
|
||||||
if (this.state.xx == 'RUNNING') {
|
if (this.state.xx == "RUNNING") {
|
||||||
this.pause();
|
this.pause();
|
||||||
} else if (this.state.xx == 'STOPPING' || this.state.xx == 'HOLDING') {
|
} else if (this.state.xx == "STOPPING" || this.state.xx == "HOLDING") {
|
||||||
this.unpause();
|
this.unpause();
|
||||||
} else {
|
} else {
|
||||||
this.start();
|
this.start();
|
||||||
@@ -452,45 +450,45 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
start: function () {
|
start: function () {
|
||||||
api.put('start')
|
api.put("start");
|
||||||
},
|
},
|
||||||
|
|
||||||
pause: function () {
|
pause: function () {
|
||||||
api.put('pause')
|
api.put("pause");
|
||||||
},
|
},
|
||||||
|
|
||||||
unpause: function () {
|
unpause: function () {
|
||||||
api.put('unpause')
|
api.put("unpause");
|
||||||
},
|
},
|
||||||
|
|
||||||
optional_pause: function () {
|
optional_pause: function () {
|
||||||
api.put('pause/optional')
|
api.put("pause/optional");
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function () {
|
stop: function () {
|
||||||
api.put('stop')
|
api.put("stop");
|
||||||
},
|
},
|
||||||
|
|
||||||
step: function () {
|
step: function () {
|
||||||
api.put('step')
|
api.put("step");
|
||||||
},
|
},
|
||||||
|
|
||||||
override_feed: function () {
|
override_feed: function () {
|
||||||
api.put('override/feed/' + this.feed_override)
|
api.put(`override/feed/${this.feed_override}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
override_speed: function () {
|
override_speed: function () {
|
||||||
api.put('override/speed/' + this.speed_override)
|
api.put(`override/speed/${this.speed_override}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
current: function (axis, value) {
|
current: function (axis, value) {
|
||||||
var x = value / 32.0;
|
const x = value / 32.0;
|
||||||
if (this.state[axis + 'pl'] == x) {
|
if (this.state[`${axis}pl`] == x) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = {};
|
const data = {};
|
||||||
data[axis + 'pl'] = x;
|
data[`${axis}pl`] = x;
|
||||||
this.send(JSON.stringify(data));
|
this.send(JSON.stringify(data));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -499,5 +497,5 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [require('./axis-vars')]
|
mixins: [require("./axis-vars")]
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,69 +1,49 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
Copyright 2018. Buildbotics LLC
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
Joseph Coffland
|
|
||||||
joseph@buildbotics.com
|
|
||||||
|
|
||||||
This software is free software: you clan redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public License
|
|
||||||
as published by the Free Software Foundation, either version 2.1 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This software is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the C! library. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function (prefix) {
|
module.exports = function (prefix) {
|
||||||
if (typeof prefix == 'undefined') prefix = '';
|
if (typeof prefix == "undefined") {
|
||||||
|
prefix = "";
|
||||||
|
}
|
||||||
|
|
||||||
var cookie = {
|
const cookie = {
|
||||||
get: function (name, defaultValue) {
|
get: function (name, defaultValue) {
|
||||||
var decodedCookie = decodeURIComponent(document.cookie);
|
const decodedCookie = decodeURIComponent(document.cookie);
|
||||||
var ca = decodedCookie.split(';');
|
const ca = decodedCookie.split(";");
|
||||||
name = prefix + name + '=';
|
name = `${prefix + name}=`;
|
||||||
|
|
||||||
for (var i = 0; i < ca.length; i++) {
|
for (let i = 0; i < ca.length; i++) {
|
||||||
var c = ca[i];
|
let c = ca[i];
|
||||||
while (c.charAt(0) == ' ') c = c.substring(1);
|
while (c.charAt(0) == " ") {
|
||||||
if (!c.indexOf(name)) return c.substring(name.length, c.length);
|
c = c.substring(1);
|
||||||
|
}
|
||||||
|
if (!c.indexOf(name)) {
|
||||||
|
return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
set: function (name, value, days) {
|
set: function (name, value, days) {
|
||||||
var offset = 2147483647; // Max value
|
let offset = 2147483647; // Max value
|
||||||
if (typeof days != 'undefined') offset = days * 24 * 60 * 60 * 1000;
|
if (typeof days != "undefined") {
|
||||||
var d = new Date();
|
offset = days * 24 * 60 * 60 * 1000;
|
||||||
d.setTime(d.getTime() + offset);
|
}
|
||||||
var expires = 'expires=' + d.toUTCString();
|
|
||||||
document.cookie = prefix + name + '=' + value + ';' + expires + ';path=/';
|
|
||||||
},
|
|
||||||
|
|
||||||
|
const d = new Date();
|
||||||
|
d.setTime(d.getTime() + offset);
|
||||||
|
const expires = `expires=${d.toUTCString()}`;
|
||||||
|
document.cookie = `${prefix}${name}=${value};${expires};path=/`;
|
||||||
|
},
|
||||||
|
|
||||||
set_bool: function (name, value) {
|
set_bool: function (name, value) {
|
||||||
cookie.set(name, value ? 'true' : 'false');
|
cookie.set(name, value ? "true" : "false");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_bool: function (name, defaultValue) {
|
get_bool: function (name, defaultValue) {
|
||||||
return cookie.get(name, defaultValue ? 'true' : 'false') == 'true';
|
return cookie.get(name, defaultValue ? "true" : "false") == "true";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return cookie;
|
return cookie;
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,97 +1,76 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var api = require('./api');
|
|
||||||
|
|
||||||
|
|
||||||
var entityMap = {
|
|
||||||
'&': '&', '<': '<', '>': '>', '"': '"', "'": ''',
|
|
||||||
'/': '/', '`': '`', '=': '='}
|
|
||||||
|
|
||||||
|
const entityMap = {
|
||||||
|
"&": "&", "<": "<", ">": ">", '"': """, "'": "'",
|
||||||
|
"/": "/", "`": "`", "=": "="};
|
||||||
|
|
||||||
function escapeHTML(s) {
|
function escapeHTML(s) {
|
||||||
return s.replace(/[&<>"'`=\/]/g, function (c) {return entityMap[c]})
|
return s.replace(/[&<>"'`=\\/]/g, function (c) {
|
||||||
|
return entityMap[c];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#gcode-viewer-template',
|
template: "#gcode-viewer-template",
|
||||||
|
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
empty: true,
|
empty: true,
|
||||||
file: '',
|
file: "",
|
||||||
line: -1,
|
line: -1,
|
||||||
scrolling: false
|
scrolling: false
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'gcode-load': function (file) {this.load(file)},
|
"gcode-load": function (file) {
|
||||||
'gcode-clear': function () {this.clear()},
|
this.load(file);
|
||||||
'gcode-reload': function (file) {this.reload(file)},
|
},
|
||||||
'gcode-line': function (line) {this.update_line(line)}
|
"gcode-clear": function () {
|
||||||
|
this.clear();
|
||||||
|
},
|
||||||
|
"gcode-reload": function (file) {
|
||||||
|
this.reload(file);
|
||||||
|
},
|
||||||
|
"gcode-line": function (line) {
|
||||||
|
this.update_line(line);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
ready: function () {
|
ready: function () {
|
||||||
this.clusterize = new Clusterize({
|
this.clusterize = new Clusterize({
|
||||||
rows: [],
|
rows: [],
|
||||||
scrollElem: $(this.$el).find('.clusterize-scroll')[0],
|
scrollElem: $(this.$el).find(".clusterize-scroll")[0],
|
||||||
contentElem: $(this.$el).find('.clusterize-content')[0],
|
contentElem: $(this.$el).find(".clusterize-content")[0],
|
||||||
no_data_text: 'GCode view...',
|
no_data_text: "GCode view...",
|
||||||
callbacks: {clusterChanged: this.highlight}
|
callbacks: {clusterChanged: this.highlight}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
attached: function () {
|
attached: function () {
|
||||||
if (typeof this.clusterize != 'undefined')
|
if (typeof this.clusterize != "undefined") {
|
||||||
this.clusterize.refresh(true);
|
this.clusterize.refresh(true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
load: async function(file) {
|
load: async function(file) {
|
||||||
if (file == this.file) return;
|
if (file == this.file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
|
||||||
if (!file) return;
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(`/api/file/${file}?${Math.random()}`);
|
const response = await fetch(`/api/file/${file}?${Math.random()}`);
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
|
|
||||||
if (text.length > 20e6) {
|
if (text.length > 20e6) {
|
||||||
this.clusterize.update(['File is large - gcode view disabled']);
|
this.clusterize.update(["File is large - gcode view disabled"]);
|
||||||
} else {
|
} else {
|
||||||
const lines = escapeHTML(text.trimRight())
|
const lines = escapeHTML(text.trimRight())
|
||||||
.split(/[\r\n]/)
|
.split(/[\r\n]/)
|
||||||
@@ -105,64 +84,77 @@ module.exports = {
|
|||||||
Vue.nextTick(this.update_line);
|
Vue.nextTick(this.update_line);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
clear: function () {
|
clear: function () {
|
||||||
this.empty = true;
|
this.empty = true;
|
||||||
this.file = '';
|
this.file = "";
|
||||||
this.line = -1;
|
this.line = -1;
|
||||||
this.clusterize.clear();
|
this.clusterize.clear();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
reload: function (file) {
|
reload: function (file) {
|
||||||
if (file != this.file) return;
|
if (file != this.file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
this.load(file);
|
this.load(file);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
highlight: function () {
|
highlight: function () {
|
||||||
var e = $(this.$el).find('.highlight');
|
let e = $(this.$el).find(".highlight");
|
||||||
if (e.length) e.removeClass('highlight');
|
if (e.length) {
|
||||||
|
e.removeClass("highlight");
|
||||||
|
}
|
||||||
|
|
||||||
e = $(this.$el).find('.ln' + this.line);
|
e = $(this.$el).find(`.ln${this.line}`);
|
||||||
if (e.length) e.addClass('highlight');
|
if (e.length) {
|
||||||
|
e.addClass("highlight");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
update_line: function(line) {
|
update_line: function(line) {
|
||||||
if (typeof line != 'undefined') {
|
if (typeof line != "undefined") {
|
||||||
if (this.line == line) return;
|
if (this.line == line) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.line = line;
|
this.line = line;
|
||||||
|
} else {
|
||||||
|
line = this.line;
|
||||||
|
}
|
||||||
|
|
||||||
} else line = this.line;
|
const totalLines = this.clusterize.getRowsAmount();
|
||||||
|
|
||||||
var totalLines = this.clusterize.getRowsAmount();
|
if (line <= 0) {
|
||||||
|
line = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (line <= 0) line = 1;
|
if (totalLines < line) {
|
||||||
if (totalLines < line) line = totalLines;
|
line = totalLines;
|
||||||
|
}
|
||||||
|
|
||||||
var e = $(this.$el).find('.clusterize-scroll');
|
const e = $(this.$el).find(".clusterize-scroll");
|
||||||
|
|
||||||
var lineHeight = e[0].scrollHeight / totalLines;
|
const lineHeight = e[0].scrollHeight / totalLines;
|
||||||
var linesPerPage = Math.floor(e[0].clientHeight / lineHeight);
|
const linesPerPage = Math.floor(e[0].clientHeight / lineHeight);
|
||||||
var current = e[0].scrollTop / lineHeight;
|
const current = e[0].scrollTop / lineHeight;
|
||||||
var target = line - 1 - Math.floor(linesPerPage / 2);
|
const target = line - 1 - Math.floor(linesPerPage / 2);
|
||||||
|
|
||||||
// Update scroll position
|
// Update scroll position
|
||||||
if (!this.scrolling) {
|
if (!this.scrolling) {
|
||||||
if (target < current - 20 || current + 20 < target)
|
if (target < current - 20 || current + 20 < target) {
|
||||||
e[0].scrollTop = target * lineHeight;
|
e[0].scrollTop = target * lineHeight;
|
||||||
|
} else {
|
||||||
else {
|
|
||||||
this.scrolling = true;
|
this.scrolling = true;
|
||||||
e.animate({scrollTop: target * lineHeight}, {
|
e.animate({scrollTop: target * lineHeight}, {
|
||||||
complete: function () {this.scrolling = false}.bind(this)
|
complete: function () {
|
||||||
})
|
this.scrolling = false;
|
||||||
|
}.bind(this)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.nextTick(this.highlight);
|
Vue.nextTick(this.highlight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,65 +1,44 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var modbus = require('./modbus.js');
|
|
||||||
|
|
||||||
|
const modbus = require("./modbus.js");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#indicators-template',
|
template: "#indicators-template",
|
||||||
props: ['state'],
|
props: ["state"],
|
||||||
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
modbus_status: function () {return modbus.status_to_string(this.state.mx)},
|
modbus_status: function () {
|
||||||
|
return modbus.status_to_string(this.state.mx);
|
||||||
|
},
|
||||||
|
|
||||||
sense_error: function () {
|
sense_error: function () {
|
||||||
var error = '';
|
let error = "";
|
||||||
|
|
||||||
if (this.state.motor_voltage_sense_error) error += 'Motor voltage\n';
|
if (this.state.motor_voltage_sense_error) {
|
||||||
if (this.state.motor_current_sense_error) error += 'Motor current\n';
|
error += "Motor voltage\n";
|
||||||
if (this.state.load1_sense_error) error += 'Load 1\n';
|
}
|
||||||
if (this.state.load2_sense_error) error += 'Load 2\n';
|
if (this.state.motor_current_sense_error) {
|
||||||
if (this.state.vdd_current_sense_error) error += 'Vdd current\n';
|
error += "Motor current\n";
|
||||||
|
}
|
||||||
|
if (this.state.load1_sense_error) {
|
||||||
|
error += "Load 1\n";
|
||||||
|
}
|
||||||
|
if (this.state.load2_sense_error) {
|
||||||
|
error += "Load 2\n";
|
||||||
|
}
|
||||||
|
if (this.state.vdd_current_sense_error) {
|
||||||
|
error += "Vdd current\n";
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
is_motor_enabled: function (motor) {
|
is_motor_enabled: function (motor) {
|
||||||
return typeof this.state[motor + 'me'] != 'undefined' &&
|
return typeof this.state[`${motor}me`] != "undefined" && this.state[`${motor}me`];
|
||||||
this.state[motor + 'me'];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_min_pin: function (motor) {
|
get_min_pin: function (motor) {
|
||||||
switch (motor) {
|
switch (motor) {
|
||||||
case 0: return 3;
|
case 0: return 3;
|
||||||
@@ -69,7 +48,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_max_pin: function (motor) {
|
get_max_pin: function (motor) {
|
||||||
switch (motor) {
|
switch (motor) {
|
||||||
case 0: return 4;
|
case 0: return 4;
|
||||||
@@ -79,29 +57,38 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
motor_fault_class: function (motor, bit) {
|
motor_fault_class: function (motor, bit) {
|
||||||
if (typeof motor == 'undefined') {
|
if (typeof motor == "undefined") {
|
||||||
var status = this.state['fa'];
|
const status = this.state["fa"];
|
||||||
if (typeof status == 'undefined') return 'fa-question';
|
|
||||||
return 'fa-thumbs-' + (status ? 'down error' : 'up success')
|
if (typeof status == "undefined") {
|
||||||
|
return "fa-question";
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = this.state[motor + 'df'];
|
return `fa-thumbs-${status ? "down error" : "up success"}`;
|
||||||
if (typeof flags == 'undefined') return 'fa-question';
|
}
|
||||||
return (flags & (1 << bit)) ? 'fa-thumbs-down error' :
|
|
||||||
'fa-thumbs-up success';
|
const flags = this.state[`${motor}df`];
|
||||||
|
|
||||||
|
if (typeof flags == "undefined") {
|
||||||
|
return "fa-question";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (flags & (1 << bit)) ? "fa-thumbs-down error" :
|
||||||
|
"fa-thumbs-up success";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
motor_reset: function (motor) {
|
motor_reset: function (motor) {
|
||||||
if (typeof motor == 'undefined') {
|
if (typeof motor == "undefined") {
|
||||||
var cmd = '';
|
let cmd = "";
|
||||||
for (var i = 0; i < 4; i++)
|
for (let i = 0; i < 4; i++) {
|
||||||
cmd += '\\$' + i + 'df=0\n';
|
cmd += `\\$${i}df=0\n`;
|
||||||
this.$dispatch('send', cmd);
|
}
|
||||||
|
|
||||||
} else this.$dispatch('send', '\\$' + motor + 'df=0');
|
this.$dispatch("send", cmd);
|
||||||
|
} else {
|
||||||
|
this.$dispatch("send", `\\$${motor}df=0`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,177 +1,155 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: "#io-indicator-template",
|
template: "#io-indicator-template",
|
||||||
props: ['name', 'state'],
|
props: ["name", "state"],
|
||||||
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
klass: function () {
|
klass: function () {
|
||||||
if (this.name == 'min-switch-0') return this.get_motor_min_class(0);
|
switch (this.name) {
|
||||||
if (this.name == 'min-switch-1') return this.get_motor_min_class(1);
|
case "min-switch-0": return this.get_motor_min_class(0);
|
||||||
if (this.name == 'min-switch-2') return this.get_motor_min_class(2);
|
case "min-switch-1": return this.get_motor_min_class(1);
|
||||||
if (this.name == 'min-switch-3') return this.get_motor_min_class(3);
|
case "min-switch-2": return this.get_motor_min_class(2);
|
||||||
if (this.name == 'max-switch-0') return this.get_motor_max_class(0);
|
case "min-switch-3": return this.get_motor_min_class(3);
|
||||||
if (this.name == 'max-switch-1') return this.get_motor_max_class(1);
|
case "max-switch-0": return this.get_motor_max_class(0);
|
||||||
if (this.name == 'max-switch-2') return this.get_motor_max_class(2);
|
case "max-switch-1": return this.get_motor_max_class(1);
|
||||||
if (this.name == 'max-switch-3') return this.get_motor_max_class(3);
|
case "max-switch-2": return this.get_motor_max_class(2);
|
||||||
if (this.name == 'estop') return this.get_input_class('ew', 'et');
|
case "max-switch-3": return this.get_motor_max_class(3);
|
||||||
if (this.name == 'probe') return this.get_input_class('pw', 'pt');
|
case "estop": return this.get_input_class("ew", "et");
|
||||||
if (this.name == 'load-1') return this.get_output_class('1');
|
case "probe": return this.get_input_class("pw", "pt");
|
||||||
if (this.name == 'load-2') return this.get_output_class('2');
|
case "load-1": return this.get_output_class("1");
|
||||||
if (this.name == 'fault') return this.get_output_class('f');
|
case "load-2": return this.get_output_class("2");
|
||||||
if (this.name == 'tool-enable-mode') return this.get_output_class('e');
|
case "fault": return this.get_output_class("f");
|
||||||
if (this.name == 'tool-direction-mode') return this.get_output_class('d');
|
case "tool-enable-mode": return this.get_output_class("e");
|
||||||
},
|
case "tool-direction-mode": return this.get_output_class("d");
|
||||||
|
|
||||||
|
|
||||||
tooltip: function () {
|
|
||||||
if (this.name == 'min-switch-0') return this.get_motor_min_tooltip(0);
|
|
||||||
if (this.name == 'min-switch-1') return this.get_motor_min_tooltip(1);
|
|
||||||
if (this.name == 'min-switch-2') return this.get_motor_min_tooltip(2);
|
|
||||||
if (this.name == 'min-switch-3') return this.get_motor_min_tooltip(3);
|
|
||||||
if (this.name == 'max-switch-0') return this.get_motor_max_tooltip(0);
|
|
||||||
if (this.name == 'max-switch-1') return this.get_motor_max_tooltip(1);
|
|
||||||
if (this.name == 'max-switch-2') return this.get_motor_max_tooltip(2);
|
|
||||||
if (this.name == 'max-switch-3') return this.get_motor_max_tooltip(3);
|
|
||||||
if (this.name == 'estop') return this.get_input_tooltip('ew', 'et');
|
|
||||||
if (this.name == 'probe') return this.get_input_tooltip('pw', 'pt');
|
|
||||||
if (this.name == 'load-1') return this.get_output_tooltip('1');
|
|
||||||
if (this.name == 'load-2') return this.get_output_tooltip('2');
|
|
||||||
if (this.name == 'fault') return this.get_output_tooltip('f');
|
|
||||||
if (this.name == 'tool-direction-mode')
|
|
||||||
return this.get_output_tooltip('d');
|
|
||||||
if (this.name == 'tool-enable-mode')
|
|
||||||
return this.get_output_tooltip('e');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tooltip: function () {
|
||||||
|
switch (this.name) {
|
||||||
|
case "min-switch-0": return this.get_motor_min_tooltip(0);
|
||||||
|
case "min-switch-1": return this.get_motor_min_tooltip(1);
|
||||||
|
case "min-switch-2": return this.get_motor_min_tooltip(2);
|
||||||
|
case "min-switch-3": return this.get_motor_min_tooltip(3);
|
||||||
|
case "max-switch-0": return this.get_motor_max_tooltip(0);
|
||||||
|
case "max-switch-1": return this.get_motor_max_tooltip(1);
|
||||||
|
case "max-switch-2": return this.get_motor_max_tooltip(2);
|
||||||
|
case "max-switch-3": return this.get_motor_max_tooltip(3);
|
||||||
|
case "estop": return this.get_input_tooltip("ew", "et");
|
||||||
|
case "probe": return this.get_input_tooltip("pw", "pt");
|
||||||
|
case "load-1": return this.get_output_tooltip("1");
|
||||||
|
case "load-2": return this.get_output_tooltip("2");
|
||||||
|
case "fault": return this.get_output_tooltip("f");
|
||||||
|
case "tool-direction-mode": return this.get_output_tooltip("d");
|
||||||
|
case "tool-enable-mode": return this.get_output_tooltip("e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
get_io_state_class: function (active, state) {
|
get_io_state_class: function (active, state) {
|
||||||
if (typeof active == 'undefined' || typeof state == 'undefined')
|
if (typeof active == "undefined" || typeof state == "undefined") {
|
||||||
return 'fa-exclamation-triangle warn';
|
return "fa-exclamation-triangle warn";
|
||||||
|
}
|
||||||
|
|
||||||
if (state == 2) return 'fa-circle-o';
|
if (state == 2) {
|
||||||
|
return "fa-circle-o";
|
||||||
|
}
|
||||||
|
|
||||||
return (state ? 'fa-plus-circle' : 'fa-minus-circle') + ' ' +
|
const icon = state ? "fa-plus-circle" : "fa-minus-circle";
|
||||||
(active ? 'active' : 'inactive');
|
return `${icon} ${active ? "active" : "inactive"}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_input_active: function (stateCode, typeCode) {
|
get_input_active: function (stateCode, typeCode) {
|
||||||
var type = this.state[typeCode];
|
const type = this.state[typeCode];
|
||||||
var state = this.state[stateCode];
|
const state = this.state[stateCode];
|
||||||
|
|
||||||
if (type == 1) return !state; // Normally open
|
if (type == 1) {
|
||||||
else if (type == 2) return state; // Normally closed
|
return !state; // Normally open
|
||||||
|
} else if (type == 2) {
|
||||||
|
return state; // Normally closed
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_input_class: function (stateCode, typeCode) {
|
get_input_class: function (stateCode, typeCode) {
|
||||||
return this.get_io_state_class(this.get_input_active(stateCode, typeCode),
|
return this.get_io_state_class(this.get_input_active(stateCode, typeCode), this.state[stateCode]);
|
||||||
this.state[stateCode]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_output_class: function (output) {
|
get_output_class: function (output) {
|
||||||
return this.get_io_state_class(this.state[output + 'oa'],
|
return this.get_io_state_class(this.state[`${output}oa`], this.state[`${output}os`]);
|
||||||
this.state[output + 'os']);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_motor_min_class: function (motor) {
|
get_motor_min_class: function (motor) {
|
||||||
return this.get_input_class(motor + 'lw', motor + 'ls');
|
return this.get_input_class(`${motor}lw`, `${motor}ls`);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_motor_max_class: function (motor) {
|
get_motor_max_class: function (motor) {
|
||||||
return this.get_input_class(motor + 'xw', motor + 'xs');
|
return this.get_input_class(`${motor}xw`, `${motor}xs`);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_tooltip: function (mode, active, state) {
|
get_tooltip: function (mode, active, state) {
|
||||||
if (typeof mode == 'undefined' || typeof active == 'undefined' ||
|
if (typeof mode == "undefined" || typeof active == "undefined" || typeof state == "undefined") {
|
||||||
typeof state == 'undefined') return 'Invalid';
|
return "Invalid";
|
||||||
|
}
|
||||||
|
|
||||||
if (state == 0) state = 'Lo/Gnd';
|
if (state == 0) {
|
||||||
else if (state == 1) state = 'Hi/+3.3v';
|
state = "Lo/Gnd";
|
||||||
else if (state == 2) state = 'Tristated';
|
} else if (state == 1) {
|
||||||
else return 'Invalid';
|
state = "Hi/+3.3v";
|
||||||
|
} else if (state == 2) {
|
||||||
|
state = "Tristated";
|
||||||
|
} else {
|
||||||
|
return "Invalid";
|
||||||
|
}
|
||||||
|
|
||||||
return 'Mode: ' + mode + '\nActive: ' + (active ? 'True' : 'False') +
|
return `Mode: ${mode}\nActive: ${active ? "True" : "False"}\nLevel: ${state}`;
|
||||||
'\nLevel: ' + state;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_input_tooltip: function (stateCode, typeCode) {
|
get_input_tooltip: function (stateCode, typeCode) {
|
||||||
var type = this.state[typeCode];
|
let type = this.state[typeCode];
|
||||||
if (type == 0) return 'Disabled';
|
if (type == 0) {
|
||||||
else if (type == 1) type = 'Normally open';
|
return "Disabled";
|
||||||
else if (type == 2) type = 'Normally closed';
|
} else if (type == 1) {
|
||||||
|
type = "Normally open";
|
||||||
|
} else if (type == 2) {
|
||||||
|
type = "Normally closed";
|
||||||
|
}
|
||||||
|
|
||||||
var active = this.get_input_active(stateCode, typeCode);
|
const active = this.get_input_active(stateCode, typeCode);
|
||||||
var state = this.state[stateCode];
|
const state = this.state[stateCode];
|
||||||
|
|
||||||
return this.get_tooltip(type, active, state);
|
return this.get_tooltip(type, active, state);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_output_tooltip: function (output) {
|
get_output_tooltip: function (output) {
|
||||||
var mode = this.state[output + 'om'];
|
let mode = this.state[`${output}om`];
|
||||||
if (mode == 0) return 'Disabled';
|
|
||||||
else if (mode == 1) mode = 'Lo/Hi';
|
|
||||||
else if (mode == 2) mode = 'Hi/Lo';
|
|
||||||
else if (mode == 3) mode = 'Tri/Lo';
|
|
||||||
else if (mode == 4) mode = 'Tri/Hi';
|
|
||||||
else if (mode == 5) mode = 'Lo/Tri';
|
|
||||||
else if (mode == 6) mode = 'Hi/Tri';
|
|
||||||
else mode = undefined;
|
|
||||||
|
|
||||||
var active = this.state[output + 'oa'];
|
switch (mode) {
|
||||||
var state = this.state[output + 'os'];
|
case 0: return "Disabled";
|
||||||
|
case 1: mode = "Lo/Hi"; break;
|
||||||
|
case 2: mode = "Hi/Lo"; break;
|
||||||
|
case 3: mode = "Tri/Lo"; break;
|
||||||
|
case 4: mode = "Tri/Hi"; break;
|
||||||
|
case 5: mode = "Lo/Tri"; break;
|
||||||
|
case 6: mode = "Hi/Tri"; break;
|
||||||
|
default:
|
||||||
|
mode = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const active = this.state[`${output}oa`];
|
||||||
|
const state = this.state[`${output}os`];
|
||||||
|
|
||||||
return this.get_tooltip(mode, active, state);
|
return this.get_tooltip(mode, active, state);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_motor_min_tooltip: function (motor) {
|
get_motor_min_tooltip: function (motor) {
|
||||||
return this.get_input_tooltip(motor + 'lw', motor + 'ls');
|
return this.get_input_tooltip(`${motor}lw`, `${motor}ls`);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_motor_max_tooltip: function (motor) {
|
get_motor_max_tooltip: function (motor) {
|
||||||
return this.get_input_tooltip(motor + 'xw', motor + 'xs');
|
return this.get_input_tooltip(`${motor}xw`, `${motor}xs`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,42 +1,13 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#io-view-template',
|
template: "#io-view-template",
|
||||||
props: ['config', 'template', 'state'],
|
props: ["config", "template", "state"],
|
||||||
|
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'input-changed': function() {
|
"input-changed": function() {
|
||||||
this.$dispatch('config-changed');
|
this.$dispatch("config-changed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
104
src/js/main.js
104
src/js/main.js
@@ -1,13 +1,13 @@
|
|||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
function cookie_get(name) {
|
function cookie_get(name) {
|
||||||
var decodedCookie = decodeURIComponent(document.cookie);
|
const decodedCookie = decodeURIComponent(document.cookie);
|
||||||
var ca = decodedCookie.split(';');
|
const ca = decodedCookie.split(";");
|
||||||
name = name + '=';
|
name = `${name}=`;
|
||||||
|
|
||||||
for (var i = 0; i < ca.length; i++) {
|
for (let i = 0; i < ca.length; i++) {
|
||||||
var c = ca[i];
|
let c = ca[i];
|
||||||
while (c.charAt(0) == ' ') {
|
while (c.charAt(0) == " ") {
|
||||||
c = c.substring(1);
|
c = c.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,101 +18,101 @@ function cookie_get(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cookie_set(name, value, days) {
|
function cookie_set(name, value, days) {
|
||||||
var d = new Date();
|
const d = new Date();
|
||||||
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
|
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
|
||||||
var expires = 'expires=' + d.toUTCString();
|
const expires = `expires=${d.toUTCString()}`;
|
||||||
document.cookie = name + '=' + value + ';' + expires + ';path=/';
|
document.cookie = `${name}=${value};${expires};path=/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
var uuid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+';
|
const uuid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+";
|
||||||
|
|
||||||
function uuid(length) {
|
function uuid(length) {
|
||||||
if (typeof length == 'undefined') {
|
if (typeof length == "undefined") {
|
||||||
length = 52;
|
length = 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
var s = '';
|
let s = "";
|
||||||
for (var i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
s += uuid_chars[Math.floor(Math.random() * uuid_chars.length)];
|
s += uuid_chars[Math.floor(Math.random() * uuid_chars.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
if (typeof cookie_get('client-id') == 'undefined') {
|
if (typeof cookie_get("client-id") == "undefined") {
|
||||||
cookie_set('client-id', uuid(), 10000);
|
cookie_set("client-id", uuid(), 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register global components
|
// Register global components
|
||||||
Vue.component('templated-input', require('./templated-input'));
|
Vue.component("templated-input", require("./templated-input"));
|
||||||
Vue.component('message', require('./message'));
|
Vue.component("message", require("./message"));
|
||||||
Vue.component('indicators', require('./indicators'));
|
Vue.component("indicators", require("./indicators"));
|
||||||
Vue.component('io-indicator', require('./io-indicator'));
|
Vue.component("io-indicator", require("./io-indicator"));
|
||||||
Vue.component('console', require('./console'));
|
Vue.component("console", require("./console"));
|
||||||
Vue.component('unit-value', require('./unit-value'));
|
Vue.component("unit-value", require("./unit-value"));
|
||||||
|
|
||||||
Vue.filter('number', function (value) {
|
Vue.filter("number", function (value) {
|
||||||
if (isNaN(value)) {
|
if (isNaN(value)) {
|
||||||
return 'NaN';
|
return "NaN";
|
||||||
}
|
}
|
||||||
|
|
||||||
return value.toLocaleString();
|
return value.toLocaleString();
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.filter('percent', function (value, precision) {
|
Vue.filter("percent", function (value, precision) {
|
||||||
if (typeof value == 'undefined') {
|
if (typeof value == "undefined") {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof precision == 'undefined') {
|
if (typeof precision == "undefined") {
|
||||||
precision = 2;
|
precision = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (value * 100.0).toFixed(precision) + '%';
|
return `${(value * 100.0).toFixed(precision)}%`;
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.filter('non_zero_percent', function (value, precision) {
|
Vue.filter("non_zero_percent", function (value, precision) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof precision == 'undefined') {
|
if (typeof precision == "undefined") {
|
||||||
precision = 2;
|
precision = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (value * 100.0).toFixed(precision) + '%';
|
return `${(value * 100.0).toFixed(precision)}%`;
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.filter('fixed', function (value, precision) {
|
Vue.filter("fixed", function (value, precision) {
|
||||||
if (typeof value == 'undefined') {
|
if (typeof value == "undefined") {
|
||||||
return '0';
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseFloat(value).toFixed(precision)
|
return parseFloat(value).toFixed(precision);
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.filter('upper', function (value) {
|
Vue.filter("upper", function (value) {
|
||||||
if (typeof value == 'undefined') {
|
if (typeof value == "undefined") {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return value.toUpperCase()
|
return value.toUpperCase();
|
||||||
});
|
});
|
||||||
|
|
||||||
Vue.filter('time', function (value, precision) {
|
Vue.filter("time", function (value, precision) {
|
||||||
if (isNaN(value)) {
|
if (isNaN(value)) {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNaN(precision)) {
|
if (isNaN(precision)) {
|
||||||
precision = 0;
|
precision = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var MIN = 60;
|
const MIN = 60;
|
||||||
var HR = MIN * 60;
|
const HR = MIN * 60;
|
||||||
var DAY = HR * 24;
|
const DAY = HR * 24;
|
||||||
var parts = [];
|
const parts = [];
|
||||||
|
|
||||||
if (DAY <= value) {
|
if (DAY <= value) {
|
||||||
parts.push(Math.floor(value / DAY));
|
parts.push(Math.floor(value / DAY));
|
||||||
@@ -133,16 +133,16 @@ $(function () {
|
|||||||
|
|
||||||
parts.push(value);
|
parts.push(value);
|
||||||
|
|
||||||
for (var i = 0; i < parts.length; i++) {
|
for (let i = 0; i < parts.length; i++) {
|
||||||
parts[i] = parts[i].toFixed(i == parts.length - 1 ? precision : 0);
|
parts[i] = parts[i].toFixed(i == parts.length - 1 ? precision : 0);
|
||||||
if (i && parts[i] < 10) {
|
if (i && parts[i] < 10) {
|
||||||
parts[i] = '0' + parts[i];
|
parts[i] = `0${parts[i]}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parts.join(':');
|
return parts.join(":");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Vue app
|
// Vue app
|
||||||
require('./app');
|
require("./app");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,35 +1,7 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#message-template',
|
template: "#message-template",
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
show: {
|
show: {
|
||||||
@@ -44,4 +16,4 @@ module.exports = {
|
|||||||
twoWay: false
|
twoWay: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,48 +1,20 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
replace: true,
|
replace: true,
|
||||||
template: '#modbus-reg-view-template',
|
template: "#modbus-reg-view-template",
|
||||||
props: ['index', 'model', 'template', 'enable'],
|
props: ["index", "model", "template", "enable"],
|
||||||
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
has_user_value: function () {
|
has_user_value: function () {
|
||||||
var type = this.model['reg-type'];
|
const type = this.model["reg-type"];
|
||||||
return type.indexOf('write') != -1 || type.indexOf('fixed') != -1;
|
return type.indexOf("write") != -1 || type.indexOf("fixed") != -1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
change: function () {this.$dispatch('input-changed')}
|
change: function () {
|
||||||
|
this.$dispatch("input-changed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,35 +1,7 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
// Must match modbus.c
|
// Must match modbus.c
|
||||||
var exports = {
|
const exports = {
|
||||||
DISCONNECTED: 0,
|
DISCONNECTED: 0,
|
||||||
OK: 1,
|
OK: 1,
|
||||||
CRC: 2,
|
CRC: 2,
|
||||||
@@ -37,15 +9,15 @@ var exports = {
|
|||||||
TIMEDOUT: 4
|
TIMEDOUT: 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.status_to_string =
|
exports.status_to_string =
|
||||||
function (status) {
|
function (status) {
|
||||||
if (status == exports.OK) return 'Ok';
|
switch (status) {
|
||||||
if (status == exports.CRC) return 'CRC error';
|
case exports.OK: return "Ok";
|
||||||
if (status == exports.INVALID) return 'Invalid response';
|
case exports.CRC: return "CRC error";
|
||||||
if (status == exports.TIMEDOUT) return 'Timedout';
|
case exports.INVALID: return "Invalid response";
|
||||||
return 'Disconnected';
|
case exports.TIMEDOUT: return "Timedout";
|
||||||
|
default: return "Disconnected";
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = exports;
|
module.exports = exports;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#motor-view-template',
|
template: "#motor-view-template",
|
||||||
props: ['index', 'config', 'template', 'state'],
|
props: ["index", "config", "template", "state"],
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
metric: function () {
|
metric: function () {
|
||||||
@@ -10,7 +10,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
is_slave: function () {
|
is_slave: function () {
|
||||||
for (var i = 0; i < this.index; i++) {
|
for (let i = 0; i < this.index; i++) {
|
||||||
if (this.motor.axis == this.config.motors[i].axis) {
|
if (this.motor.axis == this.config.motors[i].axis) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -20,76 +20,76 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
motor: function () {
|
motor: function () {
|
||||||
return this.config.motors[this.index]
|
return this.config.motors[this.index];
|
||||||
},
|
},
|
||||||
|
|
||||||
invalidMaxVelocity: function () {
|
invalidMaxVelocity: function () {
|
||||||
return this.maxMaxVelocity < this.motor['max-velocity'];
|
return this.maxMaxVelocity < this.motor["max-velocity"];
|
||||||
},
|
},
|
||||||
|
|
||||||
maxMaxVelocity: function () {
|
maxMaxVelocity: function () {
|
||||||
return 1 * (15 * this.umPerStep / this.motor['microsteps']).toFixed(3);
|
return 1 * (15 * this.umPerStep / this.motor["microsteps"]).toFixed(3);
|
||||||
},
|
},
|
||||||
|
|
||||||
ustepPerSec: function () {
|
ustepPerSec: function () {
|
||||||
return this.rpm * this.stepsPerRev * this.motor['microsteps'] / 60;
|
return this.rpm * this.stepsPerRev * this.motor["microsteps"] / 60;
|
||||||
},
|
},
|
||||||
|
|
||||||
rpm: function () {
|
rpm: function () {
|
||||||
return 1000 * this.motor['max-velocity'] / this.motor['travel-per-rev'];
|
return 1000 * this.motor["max-velocity"] / this.motor["travel-per-rev"];
|
||||||
},
|
},
|
||||||
|
|
||||||
gForce: function () {
|
gForce: function () {
|
||||||
return this.motor['max-accel'] * 0.0283254504
|
return this.motor["max-accel"] * 0.0283254504;
|
||||||
},
|
},
|
||||||
|
|
||||||
gForcePerMin: function () {
|
gForcePerMin: function () {
|
||||||
return this.motor['max-jerk'] * 0.0283254504
|
return this.motor["max-jerk"] * 0.0283254504;
|
||||||
},
|
},
|
||||||
|
|
||||||
stepsPerRev: function () {
|
stepsPerRev: function () {
|
||||||
return 360 / this.motor['step-angle']
|
return 360 / this.motor["step-angle"];
|
||||||
},
|
},
|
||||||
|
|
||||||
umPerStep: function () {
|
umPerStep: function () {
|
||||||
return this.motor['travel-per-rev'] * this.motor['step-angle'] / 0.36
|
return this.motor["travel-per-rev"] * this.motor["step-angle"] / 0.36;
|
||||||
},
|
},
|
||||||
|
|
||||||
milPerStep: function () {
|
milPerStep: function () {
|
||||||
return this.umPerStep / 25.4
|
return this.umPerStep / 25.4;
|
||||||
},
|
},
|
||||||
|
|
||||||
invalidStallVelocity: function () {
|
invalidStallVelocity: function () {
|
||||||
if (!this.motor['homing-mode'].startsWith('stall-')) {
|
if (!this.motor["homing-mode"].startsWith("stall-")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.maxStallVelocity < this.motor['search-velocity'];
|
return this.maxStallVelocity < this.motor["search-velocity"];
|
||||||
},
|
},
|
||||||
|
|
||||||
stallRPM: function () {
|
stallRPM: function () {
|
||||||
var v = this.motor['search-velocity'];
|
const v = this.motor["search-velocity"];
|
||||||
return 1000 * v / this.motor['travel-per-rev'];
|
return 1000 * v / this.motor["travel-per-rev"];
|
||||||
},
|
},
|
||||||
|
|
||||||
maxStallVelocity: function () {
|
maxStallVelocity: function () {
|
||||||
var maxRate = 900000 / this.motor['stall-sample-time'];
|
const maxRate = 900000 / this.motor["stall-sample-time"];
|
||||||
var ustep = this.motor['stall-microstep'];
|
const ustep = this.motor["stall-microstep"];
|
||||||
var angle = this.motor['step-angle'];
|
const angle = this.motor["step-angle"];
|
||||||
var travel = this.motor['travel-per-rev'];
|
const travel = this.motor["travel-per-rev"];
|
||||||
var maxStall = maxRate * 60 / 360 / 1000 * angle / ustep * travel;
|
const maxStall = maxRate * 60 / 360 / 1000 * angle / ustep * travel;
|
||||||
|
|
||||||
return 1 * maxStall.toFixed(3);
|
return 1 * maxStall.toFixed(3);
|
||||||
},
|
},
|
||||||
|
|
||||||
stallUStepPerSec: function () {
|
stallUStepPerSec: function () {
|
||||||
var ustep = this.motor['stall-microstep'];
|
const ustep = this.motor["stall-microstep"];
|
||||||
return this.stallRPM * this.stepsPerRev * ustep / 60;
|
return this.stallRPM * this.stepsPerRev * ustep / 60;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'input-changed': function () {
|
"input-changed": function () {
|
||||||
Vue.nextTick(function () {
|
Vue.nextTick(function () {
|
||||||
// Limit max-velocity
|
// Limit max-velocity
|
||||||
if (this.invalidMaxVelocity) {
|
if (this.invalidMaxVelocity) {
|
||||||
@@ -101,8 +101,8 @@ module.exports = {
|
|||||||
this.$set('motor["search-velocity"]', this.maxStallVelocity);
|
this.$set('motor["search-velocity"]', this.maxStallVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$dispatch('config-changed');
|
this.$dispatch("config-changed");
|
||||||
}.bind(this))
|
}.bind(this));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ module.exports = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return templ.hmodes.indexOf(this.motor['homing-mode']) != -1;
|
return templ.hmodes.indexOf(this.motor["homing-mode"]) != -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
421
src/js/orbit.js
421
src/js/orbit.js
@@ -7,7 +7,7 @@
|
|||||||
* @author jcoffland / https://buildbotics.com/
|
* @author jcoffland / https://buildbotics.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
// This set of controls performs orbiting, dollying (zooming), and panning.
|
// This set of controls performs orbiting, dollying (zooming), and panning.
|
||||||
// Unlike TrackballControls, it maintains the "up" direction object.up
|
// Unlike TrackballControls, it maintains the "up" direction object.up
|
||||||
@@ -17,8 +17,42 @@
|
|||||||
// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
|
// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
|
||||||
// Pan - right mouse, or arrow keys / touch: two-finger move
|
// Pan - right mouse, or arrow keys / touch: two-finger move
|
||||||
|
|
||||||
|
const OrbitControls = function (object, domElement) {
|
||||||
|
// internals
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||||
|
const scope = this;
|
||||||
|
|
||||||
|
const changeEvent = {type: "change"};
|
||||||
|
const startEvent = {type: "start"};
|
||||||
|
const endEvent = {type: "end"};
|
||||||
|
|
||||||
|
const STATE = {
|
||||||
|
NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = STATE.NONE;
|
||||||
|
const EPS = 0.000001;
|
||||||
|
|
||||||
|
// current position in spherical coordinates
|
||||||
|
const spherical = new THREE.Spherical();
|
||||||
|
const sphericalDelta = new THREE.Spherical();
|
||||||
|
|
||||||
|
let scale = 1;
|
||||||
|
const panOffset = new THREE.Vector3();
|
||||||
|
let zoomChanged = false;
|
||||||
|
|
||||||
|
const rotateStart = new THREE.Vector2();
|
||||||
|
const rotateEnd = new THREE.Vector2();
|
||||||
|
const rotateDelta = new THREE.Vector2();
|
||||||
|
|
||||||
|
const panStart = new THREE.Vector2();
|
||||||
|
const panEnd = new THREE.Vector2();
|
||||||
|
const panDelta = new THREE.Vector2();
|
||||||
|
|
||||||
|
const dollyStart = new THREE.Vector2();
|
||||||
|
const dollyEnd = new THREE.Vector2();
|
||||||
|
const dollyDelta = new THREE.Vector2();
|
||||||
|
|
||||||
var OrbitControls = function (object, domElement) {
|
|
||||||
this.object = object;
|
this.object = object;
|
||||||
this.domElement = domElement != undefined ? domElement : document;
|
this.domElement = domElement != undefined ? domElement : document;
|
||||||
|
|
||||||
@@ -85,16 +119,19 @@ var OrbitControls = function (object, domElement) {
|
|||||||
this.zoom0 = this.object.zoom;
|
this.zoom0 = this.object.zoom;
|
||||||
|
|
||||||
// public methods
|
// public methods
|
||||||
this.getPolarAngle = function () {return spherical.phi}
|
this.getPolarAngle = function () {
|
||||||
this.getAzimuthalAngle = function () {return spherical.theta}
|
return spherical.phi;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getAzimuthalAngle = function () {
|
||||||
|
return spherical.theta;
|
||||||
|
};
|
||||||
|
|
||||||
this.saveState = function () {
|
this.saveState = function () {
|
||||||
scope.target0.copy(scope.target);
|
scope.target0.copy(scope.target);
|
||||||
scope.position0.copy(scope.object.position);
|
scope.position0.copy(scope.object.position);
|
||||||
scope.zoom0 = scope.object.zoom;
|
scope.zoom0 = scope.object.zoom;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
this.reset = function () {
|
this.reset = function () {
|
||||||
scope.target.copy(scope.target0);
|
scope.target.copy(scope.target0);
|
||||||
@@ -106,22 +143,20 @@ var OrbitControls = function (object, domElement) {
|
|||||||
scope.update();
|
scope.update();
|
||||||
|
|
||||||
state = STATE.NONE;
|
state = STATE.NONE;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
this.update = function () {
|
this.update = function () {
|
||||||
var offset = new THREE.Vector3();
|
const offset = new THREE.Vector3();
|
||||||
|
|
||||||
// so camera.up is the orbit axis
|
// so camera.up is the orbit axis
|
||||||
var quat = new THREE.Quaternion()
|
const quat = new THREE.Quaternion().setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0));
|
||||||
.setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0));
|
const quatInverse = quat.clone().inverse();
|
||||||
var quatInverse = quat.clone().inverse();
|
|
||||||
|
|
||||||
var lastPosition = new THREE.Vector3();
|
const lastPosition = new THREE.Vector3();
|
||||||
var lastQuaternion = new THREE.Quaternion();
|
const lastQuaternion = new THREE.Quaternion();
|
||||||
|
|
||||||
return function update() {
|
return function update() {
|
||||||
var position = scope.object.position;
|
const position = scope.object.position;
|
||||||
|
|
||||||
offset.copy(position).sub(scope.target);
|
offset.copy(position).sub(scope.target);
|
||||||
|
|
||||||
@@ -131,28 +166,24 @@ var OrbitControls = function (object, domElement) {
|
|||||||
// angle from z-axis around y-axis
|
// angle from z-axis around y-axis
|
||||||
spherical.setFromVector3(offset);
|
spherical.setFromVector3(offset);
|
||||||
|
|
||||||
if (scope.autoRotate && state == STATE.NONE)
|
if (scope.autoRotate && state == STATE.NONE) {
|
||||||
rotateLeft(getAutoRotationAngle());
|
rotateLeft(getAutoRotationAngle());
|
||||||
|
}
|
||||||
|
|
||||||
spherical.theta += sphericalDelta.theta;
|
spherical.theta += sphericalDelta.theta;
|
||||||
spherical.phi += sphericalDelta.phi;
|
spherical.phi += sphericalDelta.phi;
|
||||||
|
|
||||||
// restrict theta to be between desired limits
|
// restrict theta to be between desired limits
|
||||||
spherical.theta =
|
spherical.theta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, spherical.theta));
|
||||||
Math.max(scope.minAzimuthAngle,
|
|
||||||
Math.min(scope.maxAzimuthAngle, spherical.theta));
|
|
||||||
|
|
||||||
// restrict phi to be between desired limits
|
// restrict phi to be between desired limits
|
||||||
spherical.phi =
|
spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
|
||||||
Math.max(scope.minPolarAngle,
|
|
||||||
Math.min(scope.maxPolarAngle, spherical.phi));
|
|
||||||
|
|
||||||
spherical.makeSafe();
|
spherical.makeSafe();
|
||||||
spherical.radius *= scale;
|
spherical.radius *= scale;
|
||||||
|
|
||||||
// restrict radius to be between desired limits
|
// restrict radius to be between desired limits
|
||||||
spherical.radius =
|
spherical.radius = Math.max(10, Math.min(scope.object.far * 0.8, spherical.radius));
|
||||||
Math.max(10, Math.min(scope.object.far * 0.8, spherical.radius));
|
|
||||||
|
|
||||||
// move target to panned location
|
// move target to panned location
|
||||||
scope.target.add(panOffset);
|
scope.target.add(panOffset);
|
||||||
@@ -178,9 +209,10 @@ var OrbitControls = function (object, domElement) {
|
|||||||
// update condition is:
|
// update condition is:
|
||||||
// min(camera displacement, camera rotation in radians)^2 > EPS
|
// min(camera displacement, camera rotation in radians)^2 > EPS
|
||||||
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
|
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
|
||||||
if (zoomChanged || scale != 1 ||
|
if (zoomChanged
|
||||||
lastPosition.distanceToSquared(scope.object.position) > EPS ||
|
|| scale != 1
|
||||||
8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
|
|| lastPosition.distanceToSquared(scope.object.position) > EPS
|
||||||
|
|| 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
|
||||||
|
|
||||||
scope.dispatchEvent(changeEvent);
|
scope.dispatchEvent(changeEvent);
|
||||||
|
|
||||||
@@ -193,187 +225,150 @@ var OrbitControls = function (object, domElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
}()
|
}();
|
||||||
|
|
||||||
|
|
||||||
this.dispose = function () {
|
this.dispose = function () {
|
||||||
scope.domElement.removeEventListener('contextmenu', onContextMenu, false);
|
scope.domElement.removeEventListener("contextmenu", onContextMenu, false);
|
||||||
scope.domElement.removeEventListener('mousedown', onMouseDown, false);
|
scope.domElement.removeEventListener("mousedown", onMouseDown, false);
|
||||||
scope.domElement.removeEventListener('wheel', onMouseWheel, false);
|
scope.domElement.removeEventListener("wheel", onMouseWheel, false);
|
||||||
scope.domElement.removeEventListener('touchstart', onTouchStart, false);
|
scope.domElement.removeEventListener("touchstart", onTouchStart, false);
|
||||||
scope.domElement.removeEventListener('touchend', onTouchEnd, false);
|
scope.domElement.removeEventListener("touchend", onTouchEnd, false);
|
||||||
scope.domElement.removeEventListener('touchmove', onTouchMove, false);
|
scope.domElement.removeEventListener("touchmove", onTouchMove, false);
|
||||||
document.removeEventListener('mousemove', onMouseMove, false);
|
document.removeEventListener("mousemove", onMouseMove, false);
|
||||||
document.removeEventListener('mouseup', onMouseUp, false);
|
document.removeEventListener("mouseup", onMouseUp, false);
|
||||||
window.removeEventListener('keydown', onKeyDown, false);
|
window.removeEventListener("keydown", onKeyDown, false);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// internals
|
|
||||||
var scope = this;
|
|
||||||
|
|
||||||
var changeEvent = {type: 'change'};
|
|
||||||
var startEvent = {type: 'start'};
|
|
||||||
var endEvent = {type: 'end'};
|
|
||||||
|
|
||||||
var STATE = {
|
|
||||||
NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var state = STATE.NONE;
|
|
||||||
var EPS = 0.000001;
|
|
||||||
|
|
||||||
// current position in spherical coordinates
|
|
||||||
var spherical = new THREE.Spherical();
|
|
||||||
var sphericalDelta = new THREE.Spherical();
|
|
||||||
|
|
||||||
var scale = 1;
|
|
||||||
var panOffset = new THREE.Vector3();
|
|
||||||
var zoomChanged = false;
|
|
||||||
|
|
||||||
var rotateStart = new THREE.Vector2();
|
|
||||||
var rotateEnd = new THREE.Vector2();
|
|
||||||
var rotateDelta = new THREE.Vector2();
|
|
||||||
|
|
||||||
var panStart = new THREE.Vector2();
|
|
||||||
var panEnd = new THREE.Vector2();
|
|
||||||
var panDelta = new THREE.Vector2();
|
|
||||||
|
|
||||||
var dollyStart = new THREE.Vector2();
|
|
||||||
var dollyEnd = new THREE.Vector2();
|
|
||||||
var dollyDelta = new THREE.Vector2();
|
|
||||||
|
|
||||||
|
|
||||||
function getAutoRotationAngle() {
|
function getAutoRotationAngle() {
|
||||||
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getZoomScale() {
|
||||||
|
return Math.pow(0.95, scope.zoomSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
function getZoomScale() {return Math.pow(0.95, scope.zoomSpeed)}
|
function rotateLeft(angle) {
|
||||||
function rotateLeft(angle) {sphericalDelta.theta -= angle}
|
sphericalDelta.theta -= angle;
|
||||||
function rotateUp(angle) {sphericalDelta.phi -= angle}
|
}
|
||||||
|
|
||||||
|
function rotateUp(angle) {
|
||||||
|
sphericalDelta.phi -= angle;
|
||||||
|
}
|
||||||
|
|
||||||
var panLeft = function () {
|
const panLeft = function () {
|
||||||
var v = new THREE.Vector3();
|
const v = new THREE.Vector3();
|
||||||
|
|
||||||
return function panLeft(distance, objectMatrix) {
|
return function panLeft(distance, objectMatrix) {
|
||||||
v.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix
|
v.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix
|
||||||
v.multiplyScalar(-distance);
|
v.multiplyScalar(-distance);
|
||||||
panOffset.add(v);
|
panOffset.add(v);
|
||||||
}
|
};
|
||||||
}()
|
}();
|
||||||
|
|
||||||
|
const panUp = function () {
|
||||||
var panUp = function () {
|
const v = new THREE.Vector3();
|
||||||
var v = new THREE.Vector3();
|
|
||||||
|
|
||||||
return function panUp(distance, objectMatrix) {
|
return function panUp(distance, objectMatrix) {
|
||||||
if (scope.screenSpacePanning) v.setFromMatrixColumn(objectMatrix, 1);
|
if (scope.screenSpacePanning) {
|
||||||
else {
|
v.setFromMatrixColumn(objectMatrix, 1);
|
||||||
|
} else {
|
||||||
v.setFromMatrixColumn(objectMatrix, 0);
|
v.setFromMatrixColumn(objectMatrix, 0);
|
||||||
v.crossVectors(scope.object.up, v);
|
v.crossVectors(scope.object.up, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
v.multiplyScalar(distance);
|
v.multiplyScalar(distance);
|
||||||
panOffset.add(v);
|
panOffset.add(v);
|
||||||
}
|
};
|
||||||
}()
|
}();
|
||||||
|
|
||||||
|
|
||||||
function unknownCamera() {
|
function unknownCamera() {
|
||||||
console.warn('WARNING: OrbitControls.js encountered an unknown camera ' +
|
console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan & zoom disabled.");
|
||||||
'type - pan & zoom disabled.');
|
|
||||||
scope.enablePan = false;
|
scope.enablePan = false;
|
||||||
scope.enableZoom = false;
|
scope.enableZoom = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// deltaX and deltaY are in pixels; right and down are positive
|
// deltaX and deltaY are in pixels; right and down are positive
|
||||||
var pan = function () {
|
const pan = function () {
|
||||||
var offset = new THREE.Vector3();
|
const offset = new THREE.Vector3();
|
||||||
|
|
||||||
return function pan(deltaX, deltaY) {
|
return function pan(deltaX, deltaY) {
|
||||||
var element = scope.domElement === document ?
|
const element = scope.domElement === document
|
||||||
scope.domElement.body : scope.domElement;
|
? scope.domElement.body
|
||||||
|
: scope.domElement;
|
||||||
|
|
||||||
if (scope.object.isPerspectiveCamera) {
|
if (scope.object.isPerspectiveCamera) {
|
||||||
// perspective
|
// perspective
|
||||||
offset.copy(scope.object.position).sub(scope.target);
|
offset.copy(scope.object.position).sub(scope.target);
|
||||||
var targetDistance = offset.length();
|
let targetDistance = offset.length();
|
||||||
|
|
||||||
// half of the fov is center to top of screen
|
// half of the fov is center to top of screen
|
||||||
targetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0);
|
targetDistance *= Math.tan((scope.object.fov / 2) * Math.PI / 180.0);
|
||||||
|
|
||||||
// we use only clientHeight here so aspect ratio does not distort speed
|
// we use only clientHeight here so aspect ratio does not distort speed
|
||||||
panLeft(2 * deltaX * targetDistance / element.clientHeight,
|
panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
|
||||||
scope.object.matrix);
|
panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
|
||||||
panUp(2 * deltaY * targetDistance / element.clientHeight,
|
|
||||||
scope.object.matrix);
|
|
||||||
|
|
||||||
} else if (scope.object.isOrthographicCamera) {
|
} else if (scope.object.isOrthographicCamera) {
|
||||||
// orthographic
|
// orthographic
|
||||||
panLeft(deltaX * (scope.object.right - scope.object.left) /
|
panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
|
||||||
scope.object.zoom / element.clientWidth, scope.object.matrix);
|
panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
|
||||||
panUp(deltaY * (scope.object.top - scope.object.bottom) /
|
|
||||||
scope.object.zoom / element.clientHeight, scope.object.matrix);
|
|
||||||
|
|
||||||
} else unknownCamera();
|
} else {
|
||||||
|
unknownCamera();
|
||||||
}
|
}
|
||||||
}()
|
};
|
||||||
|
}();
|
||||||
|
|
||||||
function dollyIn(dollyScale) {
|
function dollyIn(dollyScale) {
|
||||||
if (scope.object.isPerspectiveCamera) scale /= dollyScale;
|
if (scope.object.isPerspectiveCamera) {
|
||||||
|
scale /= dollyScale;
|
||||||
else if (scope.object.isOrthographicCamera) {
|
} else if (scope.object.isOrthographicCamera) {
|
||||||
scope.object.zoom =
|
scope.object.zoom =
|
||||||
Math.max(scope.minZoom,
|
Math.max(scope.minZoom,
|
||||||
Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
|
Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
|
||||||
scope.object.updateProjectionMatrix();
|
scope.object.updateProjectionMatrix();
|
||||||
zoomChanged = true;
|
zoomChanged = true;
|
||||||
|
|
||||||
} else unknownCamera();
|
} else {
|
||||||
|
unknownCamera();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function dollyOut(dollyScale) {
|
function dollyOut(dollyScale) {
|
||||||
if (scope.object.isPerspectiveCamera) scale *= dollyScale;
|
if (scope.object.isPerspectiveCamera) {
|
||||||
|
scale *= dollyScale;
|
||||||
else if (scope.object.isOrthographicCamera) {
|
} else if (scope.object.isOrthographicCamera) {
|
||||||
scope.object.zoom =
|
scope.object.zoom =
|
||||||
Math.max(scope.minZoom,
|
Math.max(scope.minZoom,
|
||||||
Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
|
Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
|
||||||
scope.object.updateProjectionMatrix();
|
scope.object.updateProjectionMatrix();
|
||||||
zoomChanged = true;
|
zoomChanged = true;
|
||||||
|
|
||||||
} else unknownCamera();
|
} else {
|
||||||
|
unknownCamera();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// event callbacks - update the object state
|
// event callbacks - update the object state
|
||||||
function handleMouseDownRotate(event) {
|
function handleMouseDownRotate(event) {
|
||||||
rotateStart.set(event.clientX, event.clientY);
|
rotateStart.set(event.clientX, event.clientY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleMouseDownDolly(event) {
|
function handleMouseDownDolly(event) {
|
||||||
dollyStart.set(event.clientX, event.clientY);
|
dollyStart.set(event.clientX, event.clientY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleMouseDownPan(event) {
|
function handleMouseDownPan(event) {
|
||||||
panStart.set(event.clientX, event.clientY);
|
panStart.set(event.clientX, event.clientY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleMouseMoveRotate(event) {
|
function handleMouseMoveRotate(event) {
|
||||||
rotateEnd.set(event.clientX, event.clientY);
|
rotateEnd.set(event.clientX, event.clientY);
|
||||||
rotateDelta.subVectors(rotateEnd, rotateStart)
|
rotateDelta.subVectors(rotateEnd, rotateStart)
|
||||||
.multiplyScalar(scope.rotateSpeed);
|
.multiplyScalar(scope.rotateSpeed);
|
||||||
|
|
||||||
var element = scope.domElement === document ?
|
const element = scope.domElement === document ?
|
||||||
scope.domElement.body : scope.domElement;
|
scope.domElement.body : scope.domElement;
|
||||||
|
|
||||||
// yes, height
|
// yes, height
|
||||||
@@ -385,19 +380,20 @@ var OrbitControls = function (object, domElement) {
|
|||||||
scope.update();
|
scope.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleMouseMoveDolly(event) {
|
function handleMouseMoveDolly(event) {
|
||||||
dollyEnd.set(event.clientX, event.clientY);
|
dollyEnd.set(event.clientX, event.clientY);
|
||||||
dollyDelta.subVectors(dollyEnd, dollyStart);
|
dollyDelta.subVectors(dollyEnd, dollyStart);
|
||||||
|
|
||||||
if (dollyDelta.y > 0) dollyIn(getZoomScale());
|
if (dollyDelta.y > 0) {
|
||||||
else if (dollyDelta.y < 0) dollyOut(getZoomScale());
|
dollyIn(getZoomScale());
|
||||||
|
} else if (dollyDelta.y < 0) {
|
||||||
|
dollyOut(getZoomScale());
|
||||||
|
}
|
||||||
|
|
||||||
dollyStart.copy(dollyEnd);
|
dollyStart.copy(dollyEnd);
|
||||||
scope.update();
|
scope.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleMouseMovePan(event) {
|
function handleMouseMovePan(event) {
|
||||||
panEnd.set(event.clientX, event.clientY);
|
panEnd.set(event.clientX, event.clientY);
|
||||||
panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
|
panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
|
||||||
@@ -406,18 +402,16 @@ var OrbitControls = function (object, domElement) {
|
|||||||
scope.update();
|
scope.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleMouseUp(event) {}
|
|
||||||
|
|
||||||
|
|
||||||
function handleMouseWheel(event) {
|
function handleMouseWheel(event) {
|
||||||
if (event.deltaY < 0) dollyOut(getZoomScale());
|
if (event.deltaY < 0) {
|
||||||
else if (event.deltaY > 0) dollyIn(getZoomScale());
|
dollyOut(getZoomScale());
|
||||||
|
} else if (event.deltaY > 0) {
|
||||||
|
dollyIn(getZoomScale());
|
||||||
|
}
|
||||||
|
|
||||||
scope.update();
|
scope.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
switch (event.keyCode) {
|
switch (event.keyCode) {
|
||||||
case scope.keys.UP:
|
case scope.keys.UP:
|
||||||
@@ -442,35 +436,32 @@ var OrbitControls = function (object, domElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleTouchStartRotate(event) {
|
function handleTouchStartRotate(event) {
|
||||||
rotateStart.set(event.touches[0].pageX, event.touches[0].pageY);
|
rotateStart.set(event.touches[0].pageX, event.touches[0].pageY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleTouchStartDollyPan(event) {
|
function handleTouchStartDollyPan(event) {
|
||||||
if (scope.enableZoom) {
|
if (scope.enableZoom) {
|
||||||
var dx = event.touches[0].pageX - event.touches[1].pageX;
|
const dx = event.touches[0].pageX - event.touches[1].pageX;
|
||||||
var dy = event.touches[0].pageY - event.touches[1].pageY;
|
const dy = event.touches[0].pageY - event.touches[1].pageY;
|
||||||
var distance = Math.sqrt(dx * dx + dy * dy);
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
dollyStart.set(0, distance);
|
dollyStart.set(0, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope.enablePan) {
|
if (scope.enablePan) {
|
||||||
var x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX);
|
const x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX);
|
||||||
var y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY);
|
const y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY);
|
||||||
panStart.set(x, y);
|
panStart.set(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleTouchMoveRotate(event) {
|
function handleTouchMoveRotate(event) {
|
||||||
rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);
|
rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);
|
||||||
rotateDelta.subVectors(rotateEnd, rotateStart)
|
rotateDelta.subVectors(rotateEnd, rotateStart)
|
||||||
.multiplyScalar(scope.rotateSpeed);
|
.multiplyScalar(scope.rotateSpeed);
|
||||||
|
|
||||||
var element = scope.domElement === document ?
|
const element = scope.domElement === document ?
|
||||||
scope.domElement.body : scope.domElement;
|
scope.domElement.body : scope.domElement;
|
||||||
|
|
||||||
// yes, height
|
// yes, height
|
||||||
@@ -480,12 +471,11 @@ var OrbitControls = function (object, domElement) {
|
|||||||
scope.update();
|
scope.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleTouchMoveDollyPan(event) {
|
function handleTouchMoveDollyPan(event) {
|
||||||
if (scope.enableZoom) {
|
if (scope.enableZoom) {
|
||||||
var dx = event.touches[0].pageX - event.touches[1].pageX;
|
const dx = event.touches[0].pageX - event.touches[1].pageX;
|
||||||
var dy = event.touches[0].pageY - event.touches[1].pageY;
|
const dy = event.touches[0].pageY - event.touches[1].pageY;
|
||||||
var distance = Math.sqrt(dx * dx + dy * dy);
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
dollyEnd.set(0, distance);
|
dollyEnd.set(0, distance);
|
||||||
dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
|
dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, scope.zoomSpeed));
|
||||||
@@ -493,10 +483,9 @@ var OrbitControls = function (object, domElement) {
|
|||||||
dollyStart.copy(dollyEnd);
|
dollyStart.copy(dollyEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (scope.enablePan) {
|
if (scope.enablePan) {
|
||||||
var x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX);
|
const x = 0.5 * (event.touches[0].pageX + event.touches[1].pageX);
|
||||||
var y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY);
|
const y = 0.5 * (event.touches[0].pageY + event.touches[1].pageY);
|
||||||
|
|
||||||
panEnd.set(x, y);
|
panEnd.set(x, y);
|
||||||
panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
|
panDelta.subVectors(panEnd, panStart).multiplyScalar(scope.panSpeed);
|
||||||
@@ -507,82 +496,94 @@ var OrbitControls = function (object, domElement) {
|
|||||||
scope.update();
|
scope.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleTouchEnd(event) {}
|
|
||||||
|
|
||||||
|
|
||||||
// event handlers - listen for events and reset state
|
// event handlers - listen for events and reset state
|
||||||
function onMouseDown(event) {
|
function onMouseDown(event) {
|
||||||
if (!scope.enabled) return;
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
switch (event.button) {
|
switch (event.button) {
|
||||||
case scope.mouseButtons.ORBIT:
|
case scope.mouseButtons.ORBIT:
|
||||||
if (!scope.enableRotate) return;
|
if (!scope.enableRotate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMouseDownRotate(event);
|
handleMouseDownRotate(event);
|
||||||
state = STATE.ROTATE;
|
state = STATE.ROTATE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case scope.mouseButtons.ZOOM:
|
case scope.mouseButtons.ZOOM:
|
||||||
if (!scope.enableZoom) return;
|
if (!scope.enableZoom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMouseDownDolly(event);
|
handleMouseDownDolly(event);
|
||||||
state = STATE.DOLLY;
|
state = STATE.DOLLY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case scope.mouseButtons.PAN:
|
case scope.mouseButtons.PAN:
|
||||||
if (!scope.enablePan) return;
|
if (!scope.enablePan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMouseDownPan(event);
|
handleMouseDownPan(event);
|
||||||
state = STATE.PAN;
|
state = STATE.PAN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != STATE.NONE) {
|
if (state != STATE.NONE) {
|
||||||
document.addEventListener('mousemove', onMouseMove, false);
|
document.addEventListener("mousemove", onMouseMove, false);
|
||||||
document.addEventListener('mouseup', onMouseUp, false);
|
document.addEventListener("mouseup", onMouseUp, false);
|
||||||
scope.dispatchEvent(startEvent);
|
scope.dispatchEvent(startEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onMouseMove(event) {
|
function onMouseMove(event) {
|
||||||
if (!scope.enabled) return;
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE.ROTATE:
|
case STATE.ROTATE:
|
||||||
if (!scope.enableRotate) return;
|
if (!scope.enableRotate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMouseMoveRotate(event);
|
handleMouseMoveRotate(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE.DOLLY:
|
case STATE.DOLLY:
|
||||||
if (!scope.enableZoom) return;
|
if (!scope.enableZoom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMouseMoveDolly(event);
|
handleMouseMoveDolly(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE.PAN:
|
case STATE.PAN:
|
||||||
if (!scope.enablePan) return;
|
if (!scope.enablePan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMouseMovePan(event);
|
handleMouseMovePan(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onMouseUp() {
|
||||||
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function onMouseUp(event) {
|
document.removeEventListener("mousemove", onMouseMove, false);
|
||||||
if (!scope.enabled) return;
|
document.removeEventListener("mouseup", onMouseUp, false);
|
||||||
|
|
||||||
handleMouseUp(event);
|
|
||||||
document.removeEventListener('mousemove', onMouseMove, false);
|
|
||||||
document.removeEventListener('mouseup', onMouseUp, false);
|
|
||||||
scope.dispatchEvent(endEvent);
|
scope.dispatchEvent(endEvent);
|
||||||
state = STATE.NONE;
|
state = STATE.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onMouseWheel(event) {
|
function onMouseWheel(event) {
|
||||||
if (!scope.enabled || !scope.enableZoom ||
|
if (!scope.enabled || !scope.enableZoom ||
|
||||||
(state != STATE.NONE && state != STATE.ROTATE)) return;
|
(state != STATE.NONE && state != STATE.ROTATE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -591,28 +592,34 @@ var OrbitControls = function (object, domElement) {
|
|||||||
scope.dispatchEvent(endEvent);
|
scope.dispatchEvent(endEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onKeyDown(event) {
|
function onKeyDown(event) {
|
||||||
if (!scope.enabled || !scope.enableKeys || !scope.enablePan) return;
|
if (!scope.enabled || !scope.enableKeys || !scope.enablePan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handleKeyDown(event);
|
handleKeyDown(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onTouchStart(event) {
|
function onTouchStart(event) {
|
||||||
if (!scope.enabled) return;
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
switch (event.touches.length) {
|
switch (event.touches.length) {
|
||||||
case 1: // one-fingered touch: rotate
|
case 1: // one-fingered touch: rotate
|
||||||
if (!scope.enableRotate) return;
|
if (!scope.enableRotate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleTouchStartRotate(event);
|
handleTouchStartRotate(event);
|
||||||
state = STATE.TOUCH_ROTATE;
|
state = STATE.TOUCH_ROTATE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // two-fingered touch: dolly-pan
|
case 2: // two-fingered touch: dolly-pan
|
||||||
if (!scope.enableZoom && !scope.enablePan) return;
|
if (!scope.enableZoom && !scope.enablePan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleTouchStartDollyPan(event);
|
handleTouchStartDollyPan(event);
|
||||||
state = STATE.TOUCH_DOLLY_PAN;
|
state = STATE.TOUCH_DOLLY_PAN;
|
||||||
break;
|
break;
|
||||||
@@ -620,27 +627,38 @@ var OrbitControls = function (object, domElement) {
|
|||||||
default: state = STATE.NONE;
|
default: state = STATE.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != STATE.NONE) scope.dispatchEvent(startEvent);
|
if (state != STATE.NONE) {
|
||||||
|
scope.dispatchEvent(startEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onTouchMove(event) {
|
function onTouchMove(event) {
|
||||||
if (!scope.enabled) return;
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
switch (event.touches.length) {
|
switch (event.touches.length) {
|
||||||
case 1: // one-fingered touch: rotate
|
case 1: // one-fingered touch: rotate
|
||||||
if (!scope.enableRotate) return;
|
if (!scope.enableRotate) {
|
||||||
if (state != STATE.TOUCH_ROTATE) return; // is this needed?
|
return;
|
||||||
|
}
|
||||||
|
if (state != STATE.TOUCH_ROTATE) {
|
||||||
|
return;
|
||||||
|
} // is this needed?
|
||||||
|
|
||||||
handleTouchMoveRotate(event);
|
handleTouchMoveRotate(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // two-fingered touch: dolly-pan
|
case 2: // two-fingered touch: dolly-pan
|
||||||
if (!scope.enableZoom && !scope.enablePan) return;
|
if (!scope.enableZoom && !scope.enablePan) {
|
||||||
if (state != STATE.TOUCH_DOLLY_PAN) return; // is this needed?
|
return;
|
||||||
|
}
|
||||||
|
if (state != STATE.TOUCH_DOLLY_PAN) {
|
||||||
|
return;
|
||||||
|
} // is this needed?
|
||||||
|
|
||||||
handleTouchMoveDollyPan(event);
|
handleTouchMoveDollyPan(event);
|
||||||
break;
|
break;
|
||||||
@@ -649,33 +667,32 @@ var OrbitControls = function (object, domElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onTouchEnd() {
|
||||||
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function onTouchEnd(event) {
|
|
||||||
if (!scope.enabled) return;
|
|
||||||
|
|
||||||
handleTouchEnd(event);
|
|
||||||
scope.dispatchEvent(endEvent);
|
scope.dispatchEvent(endEvent);
|
||||||
state = STATE.NONE;
|
state = STATE.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onContextMenu(event) {
|
function onContextMenu(event) {
|
||||||
if (!scope.enabled) return;
|
if (!scope.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope.domElement.addEventListener("contextmenu", onContextMenu, false);
|
||||||
scope.domElement.addEventListener('contextmenu', onContextMenu, false);
|
scope.domElement.addEventListener("mousedown", onMouseDown, false);
|
||||||
scope.domElement.addEventListener('mousedown', onMouseDown, false);
|
scope.domElement.addEventListener("wheel", onMouseWheel, false);
|
||||||
scope.domElement.addEventListener('wheel', onMouseWheel, false);
|
scope.domElement.addEventListener("touchstart", onTouchStart, false);
|
||||||
scope.domElement.addEventListener('touchstart', onTouchStart, false);
|
scope.domElement.addEventListener("touchend", onTouchEnd, false);
|
||||||
scope.domElement.addEventListener('touchend', onTouchEnd, false);
|
scope.domElement.addEventListener("touchmove", onTouchMove, false);
|
||||||
scope.domElement.addEventListener('touchmove', onTouchMove, false);
|
window.addEventListener("keydown", onKeyDown, false);
|
||||||
window .addEventListener('keydown', onKeyDown, false);
|
|
||||||
|
|
||||||
this.update(); // force an update at start
|
this.update(); // force an update at start
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype);
|
OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype);
|
||||||
OrbitControls.prototype.constructor = OrbitControls;
|
OrbitControls.prototype.constructor = OrbitControls;
|
||||||
|
|||||||
@@ -1,58 +1,32 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
Copyright 2018. Buildbotics LLC
|
const orbit = require("./orbit");
|
||||||
All Rights Reserved.
|
const cookie = require("./cookie")("bbctrl-");
|
||||||
|
const font = require("./helvetiker_regular.typeface.json");
|
||||||
For information regarding this software email:
|
|
||||||
Joseph Coffland
|
|
||||||
joseph@buildbotics.com
|
|
||||||
|
|
||||||
This software is free software: you clan redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public License
|
|
||||||
as published by the Free Software Foundation, either version 2.1 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This software is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the C! library. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var orbit = require('./orbit');
|
|
||||||
var cookie = require('./cookie')('bbctrl-');
|
|
||||||
var font = require('./helvetiker_regular.typeface.json')
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#path-viewer-template',
|
template: "#path-viewer-template",
|
||||||
props: ['toolpath'],
|
props: ["toolpath"],
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
snapView: cookie.get('snap-view', 'isometric'),
|
snapView: cookie.get("snap-view", "isometric"),
|
||||||
small: cookie.get_bool('small-path-view', true),
|
small: cookie.get_bool("small-path-view", true),
|
||||||
surfaceMode: 'cut',
|
surfaceMode: "cut",
|
||||||
showPath: cookie.get_bool('show-path', true),
|
showPath: cookie.get_bool("show-path", true),
|
||||||
showTool: cookie.get_bool('show-tool', true),
|
showTool: cookie.get_bool("show-tool", true),
|
||||||
showBBox: cookie.get_bool('show-bbox', true),
|
showBBox: cookie.get_bool("show-bbox", true),
|
||||||
showAxes: cookie.get_bool('show-axes', true),
|
showAxes: cookie.get_bool("show-axes", true),
|
||||||
showIntensity: cookie.get_bool('show-intensity', false)
|
showIntensity: cookie.get_bool("show-intensity", false)
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
target: function () {
|
target: function () {
|
||||||
return $(this.$el).find('.path-viewer-content')[0]
|
return $(this.$el).find(".path-viewer-content")[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
webglAvailable: function() {
|
webglAvailable: function() {
|
||||||
@@ -69,61 +43,64 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
toolpath: function () {Vue.nextTick(this.update)},
|
toolpath: function () {
|
||||||
surfaceMode: function (mode) {this.update_surface_mode(mode)},
|
Vue.nextTick(this.update);
|
||||||
|
},
|
||||||
|
|
||||||
|
surfaceMode: function (mode) {
|
||||||
|
this.update_surface_mode(mode);
|
||||||
|
},
|
||||||
|
|
||||||
small: function (enable) {
|
small: function (enable) {
|
||||||
cookie.set_bool('small-path-view', enable);
|
cookie.set_bool("small-path-view", enable);
|
||||||
Vue.nextTick(this.update_view)
|
Vue.nextTick(this.update_view);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
showPath: function (enable) {
|
showPath: function (enable) {
|
||||||
cookie.set_bool('show-path', enable);
|
cookie.set_bool("show-path", enable);
|
||||||
this.set_visible(this.pathView, enable)
|
this.set_visible(this.pathView, enable);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
showTool: function (enable) {
|
showTool: function (enable) {
|
||||||
cookie.set_bool('show-tool', enable);
|
cookie.set_bool("show-tool", enable);
|
||||||
this.set_visible(this.toolView, enable)
|
this.set_visible(this.toolView, enable);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
showAxes: function (enable) {
|
showAxes: function (enable) {
|
||||||
cookie.set_bool('show-axes', enable);
|
cookie.set_bool("show-axes", enable);
|
||||||
this.set_visible(this.axesView, enable)
|
this.set_visible(this.axesView, enable);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
showIntensity: function (enable) {
|
showIntensity: function (enable) {
|
||||||
cookie.set_bool('show-intensity', enable);
|
cookie.set_bool("show-intensity", enable);
|
||||||
Vue.nextTick(this.update)
|
Vue.nextTick(this.update);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
showBBox: function (enable) {
|
showBBox: function (enable) {
|
||||||
cookie.set_bool('show-bbox', enable);
|
cookie.set_bool("show-bbox", enable);
|
||||||
this.set_visible(this.bboxView, enable);
|
this.set_visible(this.bboxView, enable);
|
||||||
this.set_visible(this.envelopeView, enable);
|
this.set_visible(this.envelopeView, enable);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
x: function () {
|
||||||
x: function () {this.axis_changed()},
|
this.axis_changed();
|
||||||
y: function () {this.axis_changed()},
|
|
||||||
z: function () {this.axis_changed()}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
y: function () {
|
||||||
|
this.axis_changed();
|
||||||
|
},
|
||||||
|
|
||||||
|
z: function () {
|
||||||
|
this.axis_changed();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
ready: function () {
|
ready: function () {
|
||||||
this.graphics();
|
this.graphics();
|
||||||
Vue.nextTick(this.update);
|
Vue.nextTick(this.update);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
update: async function () {
|
update: async function () {
|
||||||
if (!this.webglAvailable) {
|
if (!this.webglAvailable) {
|
||||||
@@ -140,7 +117,9 @@ module.exports = {
|
|||||||
this.draw_loading();
|
this.draw_loading();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.enabled || !this.toolpath.filename) return;
|
if (!this.enabled || !this.toolpath.filename) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
async function get(url) {
|
async function get(url) {
|
||||||
const response = await fetch(`${url}?${Math.random()}`);
|
const response = await fetch(`${url}?${Math.random()}`);
|
||||||
@@ -150,11 +129,11 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [positions, speeds] = await Promise.all([
|
const [positions, speeds] = await Promise.all([
|
||||||
get('/api/path/' + this.toolpath.filename + '/positions'),
|
get(`/api/path/${this.toolpath.filename}/positions`),
|
||||||
get('/api/path/' + this.toolpath.filename + '/speeds')
|
get(`/api/path/${this.toolpath.filename}/speeds`)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.positions = positions
|
this.positions = positions;
|
||||||
this.speeds = speeds;
|
this.speeds = speeds;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
@@ -166,22 +145,22 @@ module.exports = {
|
|||||||
this.update_view();
|
this.update_view();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
update_surface_mode: function (mode) {
|
update_surface_mode: function (mode) {
|
||||||
if (!this.enabled) return;
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof this.surfaceMaterial != 'undefined') {
|
if (typeof this.surfaceMaterial != "undefined") {
|
||||||
this.surfaceMaterial.wireframe = mode == 'wire';
|
this.surfaceMaterial.wireframe = mode == "wire";
|
||||||
this.surfaceMaterial.needsUpdate = true;
|
this.surfaceMaterial.needsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set_visible(this.surfaceMesh, mode == 'cut' || mode == 'wire');
|
this.set_visible(this.surfaceMesh, mode == "cut" || mode == "wire");
|
||||||
this.set_visible(this.workpieceMesh, mode == 'solid');
|
this.set_visible(this.workpieceMesh, mode == "solid");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
load_surface: function (surface) {
|
load_surface: function (surface) {
|
||||||
if (typeof surface == 'undefined') {
|
if (typeof surface == "undefined") {
|
||||||
this.vertices = undefined;
|
this.vertices = undefined;
|
||||||
this.normals = undefined;
|
this.normals = undefined;
|
||||||
return;
|
return;
|
||||||
@@ -191,30 +170,35 @@ module.exports = {
|
|||||||
|
|
||||||
// Expand normals
|
// Expand normals
|
||||||
this.normals = [];
|
this.normals = [];
|
||||||
for (var i = 0; i < surface.normals.length / 3; i++)
|
for (let i = 0; i < surface.normals.length / 3; i++) {
|
||||||
for (var j = 0; j < 3; j++)
|
for (let j = 0; j < 3; j++) {
|
||||||
for (var k = 0; k < 3; k++)
|
for (let k = 0; k < 3; k++) {
|
||||||
this.normals.push(surface.normals[i * 3 + k]);
|
this.normals.push(surface.normals[i * 3 + k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
set_visible: function (target, visible) {
|
set_visible: function (target, visible) {
|
||||||
if (typeof target != 'undefined') target.visible = visible;
|
if (typeof target != "undefined") {
|
||||||
|
target.visible = visible;
|
||||||
|
}
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_dims: function () {
|
get_dims: function () {
|
||||||
var t = $(this.target);
|
const t = $(this.target);
|
||||||
var width = t.innerWidth();
|
const width = t.innerWidth();
|
||||||
var height = t.innerHeight();
|
const height = t.innerHeight();
|
||||||
return {width: width, height: height};
|
return {width: width, height: height};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
update_view: function () {
|
update_view: function () {
|
||||||
if (!this.enabled) return;
|
if (!this.enabled) {
|
||||||
var dims = this.get_dims();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dims = this.get_dims();
|
||||||
|
|
||||||
this.camera.aspect = dims.width / dims.height;
|
this.camera.aspect = dims.width / dims.height;
|
||||||
this.camera.updateProjectionMatrix();
|
this.camera.updateProjectionMatrix();
|
||||||
@@ -229,47 +213,59 @@ module.exports = {
|
|||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
update_tool: function (tool) {
|
update_tool: function (tool) {
|
||||||
if (!this.enabled) return;
|
if (!this.enabled) {
|
||||||
if (typeof tool == 'undefined') tool = this.toolView;
|
return;
|
||||||
if (typeof tool == 'undefined') return;
|
}
|
||||||
|
|
||||||
|
if (typeof tool == "undefined") {
|
||||||
|
tool = this.toolView;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof tool == "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tool.position.x = this.x.pos;
|
tool.position.x = this.x.pos;
|
||||||
tool.position.y = this.y.pos;
|
tool.position.y = this.y.pos;
|
||||||
tool.position.z = this.z.pos;
|
tool.position.z = this.z.pos;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
update_envelope: function (envelope) {
|
update_envelope: function (envelope) {
|
||||||
if (!this.enabled || !this.axes.homed) return;
|
if (!this.enabled || !this.axes.homed) {
|
||||||
if (typeof envelope == 'undefined') envelope = this.envelopeView;
|
return;
|
||||||
if (typeof envelope == 'undefined') return;
|
}
|
||||||
|
|
||||||
var min = new THREE.Vector3();
|
if (typeof envelope == "undefined") {
|
||||||
var max = new THREE.Vector3();
|
envelope = this.envelopeView;
|
||||||
|
}
|
||||||
|
|
||||||
for (var axis of 'xyz') {
|
if (typeof envelope == "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const min = new THREE.Vector3();
|
||||||
|
const max = new THREE.Vector3();
|
||||||
|
|
||||||
|
for (const axis of "xyz") {
|
||||||
min[axis] = this[axis].min - this[axis].off;
|
min[axis] = this[axis].min - this[axis].off;
|
||||||
max[axis] = this[axis].max - this[axis].off;
|
max[axis] = this[axis].max - this[axis].off;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bounds = new THREE.Box3(min, max);
|
const bounds = new THREE.Box3(min, max);
|
||||||
if (bounds.isEmpty()) {
|
if (bounds.isEmpty()) {
|
||||||
envelope.geometry = this.create_empty_geom();
|
envelope.geometry = this.create_empty_geom();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
envelope.geometry = this.create_bbox_geom(bounds);
|
envelope.geometry = this.create_bbox_geom(bounds);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
axis_changed: function () {
|
axis_changed: function () {
|
||||||
this.update_tool();
|
this.update_tool();
|
||||||
this.update_envelope();
|
this.update_envelope();
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
graphics: function () {
|
graphics: function () {
|
||||||
if (!this.webglAvailable) {
|
if (!this.webglAvailable) {
|
||||||
return;
|
return;
|
||||||
@@ -283,7 +279,7 @@ module.exports = {
|
|||||||
this.target.appendChild(this.renderer.domElement);
|
this.target.appendChild(this.renderer.domElement);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('WebGL not supported: ', e);
|
console.log("WebGL not supported: ", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,15 +291,13 @@ module.exports = {
|
|||||||
// Lighting
|
// Lighting
|
||||||
this.ambient = new THREE.AmbientLight(0xffffff, 0.5);
|
this.ambient = new THREE.AmbientLight(0xffffff, 0.5);
|
||||||
|
|
||||||
var keyLight = new THREE.DirectionalLight
|
const keyLight = new THREE.DirectionalLight(new THREE.Color("hsl(30, 100%, 75%)"), 0.75);
|
||||||
(new THREE.Color('hsl(30, 100%, 75%)'), 0.75);
|
|
||||||
keyLight.position.set(-100, 0, 100);
|
keyLight.position.set(-100, 0, 100);
|
||||||
|
|
||||||
var fillLight = new THREE.DirectionalLight
|
const fillLight = new THREE.DirectionalLight(new THREE.Color("hsl(240, 100%, 75%)"), 0.25);
|
||||||
(new THREE.Color('hsl(240, 100%, 75%)'), 0.25);
|
|
||||||
fillLight.position.set(100, 0, 100);
|
fillLight.position.set(100, 0, 100);
|
||||||
|
|
||||||
var backLight = new THREE.DirectionalLight(0xffffff, 0.5);
|
const backLight = new THREE.DirectionalLight(0xffffff, 0.5);
|
||||||
backLight.position.set(100, 0, -100).normalize();
|
backLight.position.set(100, 0, -100).normalize();
|
||||||
|
|
||||||
this.lights = new THREE.Group();
|
this.lights = new THREE.Group();
|
||||||
@@ -322,7 +316,7 @@ module.exports = {
|
|||||||
this.controls.enableZoom = true;
|
this.controls.enableZoom = true;
|
||||||
|
|
||||||
// Move lights with scene
|
// Move lights with scene
|
||||||
this.controls.addEventListener('change', function (scope) {
|
this.controls.addEventListener("change", function (scope) {
|
||||||
return function () {
|
return function () {
|
||||||
keyLight.position.copy(scope.camera.position);
|
keyLight.position.copy(scope.camera.position);
|
||||||
fillLight.position.copy(scope.camera.position);
|
fillLight.position.copy(scope.camera.position);
|
||||||
@@ -331,17 +325,16 @@ module.exports = {
|
|||||||
fillLight.lookAt(scope.controls.target);
|
fillLight.lookAt(scope.controls.target);
|
||||||
backLight.lookAt(scope.controls.target);
|
backLight.lookAt(scope.controls.target);
|
||||||
scope.dirty = true;
|
scope.dirty = true;
|
||||||
}
|
};
|
||||||
}(this))
|
}(this));
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
window.addEventListener('resize', this.update_view, false);
|
window.addEventListener("resize", this.update_view, false);
|
||||||
|
|
||||||
// Start it
|
// Start it
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
create_surface_material: function () {
|
create_surface_material: function () {
|
||||||
return new THREE.MeshPhongMaterial({
|
return new THREE.MeshPhongMaterial({
|
||||||
specular: 0x111111,
|
specular: 0x111111,
|
||||||
@@ -351,11 +344,10 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_loading: function () {
|
draw_loading: function () {
|
||||||
this.scene = new THREE.Scene();
|
this.scene = new THREE.Scene();
|
||||||
|
|
||||||
var geometry = new THREE.TextGeometry('Loading 3D View...', {
|
const geometry = new THREE.TextGeometry("Loading 3D View...", {
|
||||||
font: new THREE.Font(font),
|
font: new THREE.Font(font),
|
||||||
size: 40,
|
size: 40,
|
||||||
height: 5,
|
height: 5,
|
||||||
@@ -367,8 +359,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
geometry.computeBoundingBox();
|
geometry.computeBoundingBox();
|
||||||
|
|
||||||
var center = geometry.center();
|
const mesh = new THREE.Mesh(geometry, this.surfaceMaterial);
|
||||||
var mesh = new THREE.Mesh(geometry, this.surfaceMaterial);
|
|
||||||
|
|
||||||
this.scene.add(mesh);
|
this.scene.add(mesh);
|
||||||
this.scene.add(this.ambient);
|
this.scene.add(this.ambient);
|
||||||
@@ -376,21 +367,22 @@ module.exports = {
|
|||||||
this.update_view();
|
this.update_view();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_workpiece: function (scene, material) {
|
draw_workpiece: function (scene, material) {
|
||||||
if (typeof this.workpiece == 'undefined') return;
|
if (typeof this.workpiece == "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var min = this.workpiece.min;
|
let min = this.workpiece.min;
|
||||||
var max = this.workpiece.max;
|
let max = this.workpiece.max;
|
||||||
|
|
||||||
min = new THREE.Vector3(min[0], min[1], min[2]);
|
min = new THREE.Vector3(min[0], min[1], min[2]);
|
||||||
max = new THREE.Vector3(max[0], max[1], max[2]);
|
max = new THREE.Vector3(max[0], max[1], max[2]);
|
||||||
var dims = max.clone().sub(min);
|
const dims = max.clone().sub(min);
|
||||||
|
|
||||||
var geometry = new THREE.BoxGeometry(dims.x, dims.y, dims.z)
|
const geometry = new THREE.BoxGeometry(dims.x, dims.y, dims.z);
|
||||||
var mesh = new THREE.Mesh(geometry, material);
|
const mesh = new THREE.Mesh(geometry, material);
|
||||||
|
|
||||||
var offset = dims.clone();
|
const offset = dims.clone();
|
||||||
offset.divideScalar(2);
|
offset.divideScalar(2);
|
||||||
offset.add(min);
|
offset.add(min);
|
||||||
|
|
||||||
@@ -403,16 +395,15 @@ module.exports = {
|
|||||||
return mesh;
|
return mesh;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_surface: function (scene, material) {
|
draw_surface: function (scene, material) {
|
||||||
if (typeof this.vertices == 'undefined') return;
|
if (typeof this.vertices == "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var geometry = new THREE.BufferGeometry();
|
const geometry = new THREE.BufferGeometry();
|
||||||
|
|
||||||
geometry.addAttribute
|
geometry.addAttribute("position", new THREE.Float32BufferAttribute(this.vertices, 3));
|
||||||
('position', new THREE.Float32BufferAttribute(this.vertices, 3));
|
geometry.addAttribute("normal", new THREE.Float32BufferAttribute(this.normals, 3));
|
||||||
geometry.addAttribute
|
|
||||||
('normal', new THREE.Float32BufferAttribute(this.normals, 3));
|
|
||||||
|
|
||||||
geometry.computeBoundingSphere();
|
geometry.computeBoundingSphere();
|
||||||
geometry.computeBoundingBox();
|
geometry.computeBoundingBox();
|
||||||
@@ -420,15 +411,16 @@ module.exports = {
|
|||||||
return new THREE.Mesh(geometry, material);
|
return new THREE.Mesh(geometry, material);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_tool: function (scene, bbox) {
|
draw_tool: function (scene, bbox) {
|
||||||
// Tool size is relative to bounds
|
// Tool size is relative to bounds
|
||||||
var size = bbox.getSize(new THREE.Vector3());
|
const size = bbox.getSize(new THREE.Vector3());
|
||||||
var length = (size.x + size.y + size.z) / 24;
|
let length = (size.x + size.y + size.z) / 24;
|
||||||
|
|
||||||
if (length < 1) length = 1;
|
if (length < 1) {
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
|
||||||
var material = new THREE.MeshPhongMaterial({
|
const material = new THREE.MeshPhongMaterial({
|
||||||
transparent: true,
|
transparent: true,
|
||||||
opacity: 0.75,
|
opacity: 0.75,
|
||||||
specular: 0x161616,
|
specular: 0x161616,
|
||||||
@@ -436,30 +428,33 @@ module.exports = {
|
|||||||
color: 0xffa500 // Orange
|
color: 0xffa500 // Orange
|
||||||
});
|
});
|
||||||
|
|
||||||
var geometry = new THREE.CylinderGeometry(length / 2, 0, length, 128);
|
const geometry = new THREE.CylinderGeometry(length / 2, 0, length, 128);
|
||||||
geometry.translate(0, length / 2, 0);
|
geometry.translate(0, length / 2, 0);
|
||||||
geometry.rotateX(0.5 * Math.PI);
|
geometry.rotateX(0.5 * Math.PI);
|
||||||
|
|
||||||
var mesh = new THREE.Mesh(geometry, material);
|
const mesh = new THREE.Mesh(geometry, material);
|
||||||
this.update_tool(mesh);
|
this.update_tool(mesh);
|
||||||
mesh.visible = this.showTool;
|
mesh.visible = this.showTool;
|
||||||
scene.add(mesh);
|
scene.add(mesh);
|
||||||
return mesh;
|
return mesh;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_axis: function (axis, up, length, radius) {
|
draw_axis: function (axis, up, length, radius) {
|
||||||
var color;
|
let color;
|
||||||
|
|
||||||
if (axis == 0) color = 0xff0000; // Red
|
if (axis == 0) {
|
||||||
else if (axis == 1) color = 0x00ff00; // Green
|
color = 0xff0000;
|
||||||
else if (axis == 2) color = 0x0000ff; // Blue
|
} else if (axis == 1) {
|
||||||
|
color = 0x00ff00;
|
||||||
|
} else if (axis == 2) {
|
||||||
|
color = 0x0000ff;
|
||||||
|
}
|
||||||
|
|
||||||
var group = new THREE.Group();
|
const group = new THREE.Group();
|
||||||
var material = new THREE.MeshPhongMaterial({
|
const material = new THREE.MeshPhongMaterial({
|
||||||
specular: 0x161616, shininess: 10, color: color
|
specular: 0x161616, shininess: 10, color: color
|
||||||
});
|
});
|
||||||
var geometry = new THREE.CylinderGeometry(radius, radius, length, 128);
|
let geometry = new THREE.CylinderGeometry(radius, radius, length, 128);
|
||||||
geometry.translate(0, -length / 2, 0);
|
geometry.translate(0, -length / 2, 0);
|
||||||
group.add(new THREE.Mesh(geometry, material));
|
group.add(new THREE.Mesh(geometry, material));
|
||||||
|
|
||||||
@@ -467,28 +462,35 @@ module.exports = {
|
|||||||
geometry.translate(0, -length - radius, 0);
|
geometry.translate(0, -length - radius, 0);
|
||||||
group.add(new THREE.Mesh(geometry, material));
|
group.add(new THREE.Mesh(geometry, material));
|
||||||
|
|
||||||
if (axis == 0) group.rotateZ((up ? 0.5 : 1.5) * Math.PI);
|
if (axis == 0) {
|
||||||
else if (axis == 1) group.rotateX((up ? 0 : 1 ) * Math.PI);
|
group.rotateZ((up ? 0.5 : 1.5) * Math.PI);
|
||||||
else if (axis == 2) group.rotateX((up ? 1.5 : 0.5) * Math.PI);
|
} else if (axis == 1) {
|
||||||
|
group.rotateX((up ? 0 : 1 ) * Math.PI);
|
||||||
|
} else if (axis == 2) {
|
||||||
|
group.rotateX((up ? 1.5 : 0.5) * Math.PI);
|
||||||
|
}
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_axes: function (scene, bbox) {
|
draw_axes: function (scene, bbox) {
|
||||||
var size = bbox.getSize(new THREE.Vector3());
|
const size = bbox.getSize(new THREE.Vector3());
|
||||||
var length = (size.x + size.y + size.z) / 3;
|
let length = (size.x + size.y + size.z) / 3;
|
||||||
length /= 10;
|
length /= 10;
|
||||||
|
|
||||||
if (length < 1) length = 1;
|
if (length < 1) {
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
|
||||||
var radius = length / 20;
|
const radius = length / 20;
|
||||||
|
|
||||||
var group = new THREE.Group();
|
const group = new THREE.Group();
|
||||||
|
|
||||||
for (var axis = 0; axis < 3; axis++)
|
for (let axis = 0; axis < 3; axis++) {
|
||||||
for (var up = 0; up < 2; up++)
|
for (let up = 0; up < 2; up++) {
|
||||||
group.add(this.draw_axis(axis, up, length, radius));
|
group.add(this.draw_axis(axis, up, length, radius));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group.visible = this.showAxes;
|
group.visible = this.showAxes;
|
||||||
scene.add(group);
|
scene.add(group);
|
||||||
@@ -496,40 +498,42 @@ module.exports = {
|
|||||||
return group;
|
return group;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_color: function (speed) {
|
get_color: function (speed) {
|
||||||
if (isNaN(speed)) return [255, 0, 0]; // Rapid
|
if (isNaN(speed)) {
|
||||||
|
return [255, 0, 0];
|
||||||
|
} // Rapid
|
||||||
|
|
||||||
|
let intensity = speed / this.toolpath.maxSpeed;
|
||||||
|
if (typeof speed == "undefined" || !this.showIntensity) {
|
||||||
|
intensity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
var intensity = speed / this.toolpath.maxSpeed;
|
|
||||||
if (typeof speed == 'undefined' || !this.showIntensity) intensity = 1;
|
|
||||||
return [0, 255 * intensity, 127 * (1 - intensity)];
|
return [0, 255 * intensity, 127 * (1 - intensity)];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_path: function (scene) {
|
draw_path: function (scene) {
|
||||||
var geometry = new THREE.BufferGeometry();
|
const geometry = new THREE.BufferGeometry();
|
||||||
var material =
|
const material = new THREE.LineBasicMaterial({
|
||||||
new THREE.LineBasicMaterial({
|
|
||||||
vertexColors: THREE.VertexColors,
|
vertexColors: THREE.VertexColors,
|
||||||
linewidth: 1.5
|
linewidth: 1.5
|
||||||
});
|
});
|
||||||
|
|
||||||
var positions = new THREE.Float32BufferAttribute(this.positions, 3);
|
const positions = new THREE.Float32BufferAttribute(this.positions, 3);
|
||||||
geometry.addAttribute('position', positions);
|
geometry.addAttribute("position", positions);
|
||||||
|
|
||||||
var colors = [];
|
let colors = [];
|
||||||
for (var i = 0; i < this.speeds.length; i++) {
|
for (let i = 0; i < this.speeds.length; i++) {
|
||||||
var color = this.get_color(this.speeds[i]);
|
const color = this.get_color(this.speeds[i]);
|
||||||
Array.prototype.push.apply(colors, color);
|
Array.prototype.push.apply(colors, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
colors = new THREE.Uint8BufferAttribute(colors, 3, true);
|
colors = new THREE.Uint8BufferAttribute(colors, 3, true);
|
||||||
geometry.addAttribute('color', colors);
|
geometry.addAttribute("color", colors);
|
||||||
|
|
||||||
geometry.computeBoundingSphere();
|
geometry.computeBoundingSphere();
|
||||||
geometry.computeBoundingBox();
|
geometry.computeBoundingBox();
|
||||||
|
|
||||||
var line = new THREE.Line(geometry, material);
|
const line = new THREE.Line(geometry, material);
|
||||||
|
|
||||||
line.visible = this.showPath;
|
line.visible = this.showPath;
|
||||||
scene.add(line);
|
scene.add(line);
|
||||||
@@ -537,17 +541,15 @@ module.exports = {
|
|||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
create_empty_geom: function () {
|
create_empty_geom: function () {
|
||||||
var geometry = new THREE.BufferGeometry();
|
const geometry = new THREE.BufferGeometry();
|
||||||
geometry.addAttribute('position',
|
geometry.addAttribute("position",
|
||||||
new THREE.Float32BufferAttribute([], 3));
|
new THREE.Float32BufferAttribute([], 3));
|
||||||
return geometry;
|
return geometry;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
create_bbox_geom: function (bbox) {
|
create_bbox_geom: function (bbox) {
|
||||||
var vertices = [];
|
const vertices = [];
|
||||||
|
|
||||||
if (!bbox.isEmpty()) {
|
if (!bbox.isEmpty()) {
|
||||||
// Top
|
// Top
|
||||||
@@ -581,19 +583,18 @@ module.exports = {
|
|||||||
vertices.push(bbox.min.x, bbox.max.y, bbox.max.z);
|
vertices.push(bbox.min.x, bbox.max.y, bbox.max.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
var geometry = new THREE.BufferGeometry();
|
const geometry = new THREE.BufferGeometry();
|
||||||
|
|
||||||
geometry.addAttribute('position',
|
geometry.addAttribute("position",
|
||||||
new THREE.Float32BufferAttribute(vertices, 3));
|
new THREE.Float32BufferAttribute(vertices, 3));
|
||||||
|
|
||||||
return geometry;
|
return geometry;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_bbox: function (scene, bbox) {
|
draw_bbox: function (scene, bbox) {
|
||||||
var geometry = this.create_bbox_geom(bbox);
|
const geometry = this.create_bbox_geom(bbox);
|
||||||
var material = new THREE.LineBasicMaterial({color: 0xffffff});
|
const material = new THREE.LineBasicMaterial({color: 0xffffff});
|
||||||
var line = new THREE.LineSegments(geometry, material);
|
const line = new THREE.LineSegments(geometry, material);
|
||||||
|
|
||||||
line.visible = this.showBBox;
|
line.visible = this.showBBox;
|
||||||
|
|
||||||
@@ -602,11 +603,10 @@ module.exports = {
|
|||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw_envelope: function (scene) {
|
draw_envelope: function (scene) {
|
||||||
var geometry = this.create_empty_geom();
|
const geometry = this.create_empty_geom();
|
||||||
var material = new THREE.LineBasicMaterial({color: 0x00f7ff});
|
const material = new THREE.LineBasicMaterial({color: 0x00f7ff});
|
||||||
var line = new THREE.LineSegments(geometry, material);
|
const line = new THREE.LineSegments(geometry, material);
|
||||||
|
|
||||||
line.visible = this.showBBox;
|
line.visible = this.showBBox;
|
||||||
|
|
||||||
@@ -616,7 +616,6 @@ module.exports = {
|
|||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
draw: function (scene) {
|
draw: function (scene) {
|
||||||
// Lights
|
// Lights
|
||||||
scene.add(this.ambient);
|
scene.add(this.ambient);
|
||||||
@@ -629,7 +628,7 @@ module.exports = {
|
|||||||
this.update_surface_mode(this.surfaceMode);
|
this.update_surface_mode(this.surfaceMode);
|
||||||
|
|
||||||
// Compute bounding box
|
// Compute bounding box
|
||||||
var bbox = this.get_model_bounds();
|
const bbox = this.get_model_bounds();
|
||||||
|
|
||||||
// Tool, axes & bounds
|
// Tool, axes & bounds
|
||||||
this.toolView = this.draw_tool(scene, bbox);
|
this.toolView = this.draw_tool(scene, bbox);
|
||||||
@@ -638,10 +637,12 @@ module.exports = {
|
|||||||
this.envelopeView = this.draw_envelope(scene);
|
this.envelopeView = this.draw_envelope(scene);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
window.requestAnimationFrame(this.render);
|
window.requestAnimationFrame(this.render);
|
||||||
if (typeof this.scene == 'undefined') return;
|
|
||||||
|
if (typeof this.scene == "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.controls.update() || this.dirty) {
|
if (this.controls.update() || this.dirty) {
|
||||||
this.dirty = false;
|
this.dirty = false;
|
||||||
@@ -649,14 +650,13 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
get_model_bounds: function () {
|
get_model_bounds: function () {
|
||||||
var bbox = new THREE.Box3(new THREE.Vector3(0, 0, 0),
|
const bbox = new THREE.Box3(new THREE.Vector3(0, 0, 0),
|
||||||
new THREE.Vector3(0.00001, 0.00001, 0.00001));
|
new THREE.Vector3(0.00001, 0.00001, 0.00001));
|
||||||
|
|
||||||
function add(o) {
|
function add(o) {
|
||||||
if (typeof o != 'undefined') {
|
if (typeof o != "undefined") {
|
||||||
var oBBox = new THREE.Box3();
|
const oBBox = new THREE.Box3();
|
||||||
oBBox.setFromObject(o);
|
oBBox.setFromObject(o);
|
||||||
bbox.union(oBBox);
|
bbox.union(oBBox);
|
||||||
}
|
}
|
||||||
@@ -669,45 +669,53 @@ module.exports = {
|
|||||||
return bbox;
|
return bbox;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
snap: function (view) {
|
snap: function (view) {
|
||||||
if (this.loading) return;
|
if (this.loading) {
|
||||||
if (view != this.snapView) {
|
return;
|
||||||
this.snapView = view;
|
|
||||||
cookie.set('snap-view', view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var bbox = this.get_model_bounds();
|
if (view != this.snapView) {
|
||||||
|
this.snapView = view;
|
||||||
|
cookie.set("snap-view", view);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bbox = this.get_model_bounds();
|
||||||
this.controls.reset();
|
this.controls.reset();
|
||||||
bbox.getCenter(this.controls.target);
|
bbox.getCenter(this.controls.target);
|
||||||
this.update_view();
|
this.update_view();
|
||||||
|
|
||||||
// Compute new camera position
|
// Compute new camera position
|
||||||
var center = bbox.getCenter(new THREE.Vector3());
|
const center = bbox.getCenter(new THREE.Vector3());
|
||||||
var offset = new THREE.Vector3();
|
const offset = new THREE.Vector3();
|
||||||
|
|
||||||
|
switch (view) {
|
||||||
|
case "isometric": offset.y -= 1; offset.z += 1; break;
|
||||||
|
case "front": offset.y -= 1; break;
|
||||||
|
case "back": offset.y += 1; break;
|
||||||
|
case "left": offset.x -= 1; break;
|
||||||
|
case "right": offset.x += 1; break;
|
||||||
|
case "top": offset.z += 1; break;
|
||||||
|
case "bottom": offset.z -= 1; break;
|
||||||
|
}
|
||||||
|
|
||||||
if (view == 'isometric') {offset.y -= 1; offset.z += 1;}
|
|
||||||
if (view == 'front') offset.y -= 1;
|
|
||||||
if (view == 'back') offset.y += 1;
|
|
||||||
if (view == 'left') offset.x -= 1;
|
|
||||||
if (view == 'right') offset.x += 1;
|
|
||||||
if (view == 'top') offset.z += 1;
|
|
||||||
if (view == 'bottom') offset.z -= 1;
|
|
||||||
offset.normalize();
|
offset.normalize();
|
||||||
|
|
||||||
// Initial camera position
|
// Initial camera position
|
||||||
var position = new THREE.Vector3().copy(center).add(offset);
|
const position = new THREE.Vector3().copy(center).add(offset);
|
||||||
this.camera.position.copy(position);
|
this.camera.position.copy(position);
|
||||||
this.camera.lookAt(center); // Get correct camera orientation
|
this.camera.lookAt(center); // Get correct camera orientation
|
||||||
|
|
||||||
var theta = this.camera.fov / 180 * Math.PI; // View angle
|
const theta = this.camera.fov / 180 * Math.PI; // View angle
|
||||||
var cameraLine = new THREE.Line3(center, position);
|
const cameraLine = new THREE.Line3(center, position);
|
||||||
var cameraUp = new THREE.Vector3().copy(this.camera.up)
|
const cameraUp = new THREE.Vector3()
|
||||||
|
.copy(this.camera.up)
|
||||||
.applyQuaternion(this.camera.quaternion);
|
.applyQuaternion(this.camera.quaternion);
|
||||||
var cameraLeft =
|
const cameraLeft = new THREE.Vector3()
|
||||||
new THREE.Vector3().copy(offset).cross(cameraUp).normalize();
|
.copy(offset)
|
||||||
|
.cross(cameraUp)
|
||||||
|
.normalize();
|
||||||
|
|
||||||
var corners = [
|
const corners = [
|
||||||
new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.min.z),
|
new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.min.z),
|
||||||
new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.max.z),
|
new THREE.Vector3(bbox.min.x, bbox.min.y, bbox.max.z),
|
||||||
new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.min.z),
|
new THREE.Vector3(bbox.min.x, bbox.max.y, bbox.min.z),
|
||||||
@@ -716,39 +724,37 @@ module.exports = {
|
|||||||
new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.max.z),
|
new THREE.Vector3(bbox.max.x, bbox.min.y, bbox.max.z),
|
||||||
new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.min.z),
|
new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.min.z),
|
||||||
new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.max.z),
|
new THREE.Vector3(bbox.max.x, bbox.max.y, bbox.max.z),
|
||||||
]
|
];
|
||||||
|
|
||||||
var dist = this.camera.near; // Min camera dist
|
let dist = this.camera.near; // Min camera dist
|
||||||
|
|
||||||
for (var i = 0; i < corners.length; i++) {
|
for (let i = 0; i < corners.length; i++) {
|
||||||
// Project on to camera line
|
// Project on to camera line
|
||||||
var p1 = cameraLine
|
const p1 = cameraLine.closestPointToPoint(corners[i], false, new THREE.Vector3());
|
||||||
.closestPointToPoint(corners[i], false, new THREE.Vector3());
|
|
||||||
|
|
||||||
// Compute distance from projection to center
|
// Compute distance from projection to center
|
||||||
var d = p1.distanceTo(center);
|
let d = p1.distanceTo(center);
|
||||||
if (cameraLine.closestPointToPointParameter(p1, false) < 0) d = -d;
|
if (cameraLine.closestPointToPointParameter(p1, false) < 0) {
|
||||||
|
d = -d;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute up line
|
// Compute up line
|
||||||
var up =
|
const up = new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraUp));
|
||||||
new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraUp));
|
|
||||||
|
|
||||||
// Project on to up line
|
// Project on to up line
|
||||||
var p2 = up.closestPointToPoint(corners[i], false, new THREE.Vector3());
|
const p2 = up.closestPointToPoint(corners[i], false, new THREE.Vector3());
|
||||||
|
|
||||||
// Compute length
|
// Compute length
|
||||||
var l = p1.distanceTo(p2);
|
let l = p1.distanceTo(p2);
|
||||||
|
|
||||||
// Update min camera distance
|
// Update min camera distance
|
||||||
dist = Math.max(dist, d + l / Math.tan(theta / 2));
|
dist = Math.max(dist, d + l / Math.tan(theta / 2));
|
||||||
|
|
||||||
// Compute left line
|
// Compute left line
|
||||||
var left =
|
const left = new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraLeft));
|
||||||
new THREE.Line3(p1, new THREE.Vector3().copy(p1).add(cameraLeft));
|
|
||||||
|
|
||||||
// Project on to left line
|
// Project on to left line
|
||||||
var p3 =
|
const p3 = left.closestPointToPoint(corners[i], false, new THREE.Vector3());
|
||||||
left.closestPointToPoint(corners[i], false, new THREE.Vector3());
|
|
||||||
|
|
||||||
// Compute length
|
// Compute length
|
||||||
l = p1.distanceTo(p3);
|
l = p1.distanceTo(p3);
|
||||||
@@ -761,6 +767,5 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mixins: [require("./axis-vars")]
|
||||||
mixins: [require('./axis-vars')]
|
};
|
||||||
}
|
|
||||||
|
|||||||
113
src/js/sock.js
113
src/js/sock.js
@@ -1,38 +1,16 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
const Sock = function (url, retry, timeout) {
|
||||||
|
if (!(this instanceof Sock)) {
|
||||||
|
return new Sock(url, retry);
|
||||||
|
}
|
||||||
|
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
if (typeof retry == "undefined") {
|
||||||
All rights reserved.
|
retry = 2000;
|
||||||
|
}
|
||||||
This file ("the software") is free software: you can redistribute it
|
if (typeof timeout == "undefined") {
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
timeout = 16000;
|
||||||
version 2 as published by the Free Software Foundation. You should
|
}
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
|
|
||||||
var Sock = function (url, retry, timeout) {
|
|
||||||
if (!(this instanceof Sock)) return new Sock(url, retry);
|
|
||||||
|
|
||||||
if (typeof retry == 'undefined') retry = 2000;
|
|
||||||
if (typeof timeout == 'undefined') timeout = 16000;
|
|
||||||
|
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.retry = retry;
|
this.retry = retry;
|
||||||
@@ -41,87 +19,88 @@ var Sock = function (url, retry, timeout) {
|
|||||||
this.count = 0;
|
this.count = 0;
|
||||||
|
|
||||||
this.connect();
|
this.connect();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Sock.prototype.onmessage = function () {
|
||||||
|
// Ignore
|
||||||
|
};
|
||||||
|
|
||||||
Sock.prototype.onmessage = function () {}
|
Sock.prototype.onopen = function () {
|
||||||
Sock.prototype.onopen = function () {}
|
// Ignore
|
||||||
Sock.prototype.onclose = function () {}
|
};
|
||||||
|
|
||||||
|
Sock.prototype.onclose = function () {
|
||||||
|
// Ignore
|
||||||
|
};
|
||||||
|
|
||||||
Sock.prototype.connect = function () {
|
Sock.prototype.connect = function () {
|
||||||
console.debug('connecting to', this.url);
|
console.debug("connecting to", this.url);
|
||||||
this.close();
|
this.close();
|
||||||
|
|
||||||
this._sock = new SockJS(this.url);
|
this._sock = new SockJS(this.url);
|
||||||
|
|
||||||
this._sock.onmessage = function (e) {
|
this._sock.onmessage = function (e) {
|
||||||
console.debug('msg:', e.data);
|
console.debug("msg:", e.data);
|
||||||
this.heartbeat('msg');
|
this.heartbeat("msg");
|
||||||
this.onmessage(e);
|
this.onmessage(e);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
|
|
||||||
this._sock.onopen = function () {
|
this._sock.onopen = function () {
|
||||||
console.debug('connected');
|
console.debug("connected");
|
||||||
this.heartbeat('open');
|
this.heartbeat("open");
|
||||||
this.onopen();
|
this.onopen();
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
|
|
||||||
this._sock.onclose = function () {
|
this._sock.onclose = function () {
|
||||||
console.debug('disconnected');
|
console.debug("disconnected");
|
||||||
this._cancel_timeout();
|
this._cancel_timeout();
|
||||||
|
|
||||||
this.onclose();
|
this.onclose();
|
||||||
if (typeof this._sock != 'undefined')
|
if (typeof this._sock != "undefined") {
|
||||||
setTimeout(this.connect.bind(this), this.retry);
|
setTimeout(this.connect.bind(this), this.retry);
|
||||||
|
}
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
Sock.prototype._timedout = function () {
|
Sock.prototype._timedout = function () {
|
||||||
// Divide timeout so slow browser doesn't trigger timeouts when the
|
// Divide timeout so slow browser doesn't trigger timeouts when the
|
||||||
// connection is good.
|
// connection is good.
|
||||||
if (this.divisions <= ++this.count) {
|
if (this.divisions <= ++this.count) {
|
||||||
console.debug('connection timedout');
|
console.debug("connection timedout");
|
||||||
this._timeout = undefined;
|
this._timeout = undefined;
|
||||||
this._sock.close();
|
this._sock.close();
|
||||||
|
|
||||||
} else this._set_timeout();
|
} else {
|
||||||
}
|
this._set_timeout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Sock.prototype._cancel_timeout = function () {
|
Sock.prototype._cancel_timeout = function () {
|
||||||
clearTimeout(this._timeout);
|
clearTimeout(this._timeout);
|
||||||
this._timeout = undefined;
|
this._timeout = undefined;
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
Sock.prototype._set_timeout = function () {
|
Sock.prototype._set_timeout = function () {
|
||||||
this._timeout = setTimeout(this._timedout.bind(this),
|
this._timeout = setTimeout(this._timedout.bind(this),
|
||||||
this.timeout / this.divisions);
|
this.timeout / this.divisions);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Sock.prototype.heartbeat = function () {
|
||||||
Sock.prototype.heartbeat = function (msg) {
|
|
||||||
//console.debug('heartbeat ' + new Date().toLocaleTimeString() + ' ' + msg);
|
|
||||||
this._cancel_timeout();
|
this._cancel_timeout();
|
||||||
this._set_timeout();
|
this._set_timeout();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
Sock.prototype.close = function () {
|
Sock.prototype.close = function () {
|
||||||
if (typeof this._sock != 'undefined') {
|
if (typeof this._sock != "undefined") {
|
||||||
var sock = this._sock;
|
const sock = this._sock;
|
||||||
this._sock = undefined;
|
this._sock = undefined;
|
||||||
sock.close();
|
sock.close();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Sock.prototype.send = function (msg) {
|
||||||
|
this._sock.send(msg);
|
||||||
|
};
|
||||||
|
|
||||||
Sock.prototype.send = function (msg) {this._sock.send(msg)}
|
module.exports = Sock;
|
||||||
|
|
||||||
|
|
||||||
module.exports = Sock
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
replace: true,
|
replace: true,
|
||||||
template: '#templated-input-template',
|
template: "#templated-input-template",
|
||||||
props: ['name', 'model', 'template'],
|
props: ["name", "model", "template"],
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return { view: '' }
|
return { view: "" };
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@@ -33,10 +33,10 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
title: function () {
|
title: function () {
|
||||||
var s = `Default :${this.template.default} ${(this.template.unit || '')}`;
|
let s = `Default :${this.template.default} ${(this.template.unit || "")}`;
|
||||||
|
|
||||||
if (typeof this.template.help != 'undefined') {
|
if (typeof this.template.help != "undefined") {
|
||||||
s = this.template.help + '\n' + s;
|
s = `${this.template.help}\n${s}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@@ -45,7 +45,7 @@ module.exports = {
|
|||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
_view: function () {
|
_view: function () {
|
||||||
this.view = this._view
|
this.view = this._view;
|
||||||
},
|
},
|
||||||
|
|
||||||
view: function () {
|
view: function () {
|
||||||
@@ -58,12 +58,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ready: function () {
|
ready: function () {
|
||||||
this.view = this._view
|
this.view = this._view;
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
change: function () {
|
change: function () {
|
||||||
this.$dispatch('input-changed')
|
this.$dispatch("input-changed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,39 +1,12 @@
|
|||||||
/******************************************************************************\
|
"use strict";
|
||||||
|
|
||||||
This file is part of the Buildbotics firmware.
|
const api = require("./api");
|
||||||
|
const modbus = require("./modbus.js");
|
||||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
This file ("the software") is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License,
|
|
||||||
version 2 as published by the Free Software Foundation. You should
|
|
||||||
have received a copy of the GNU General Public License, version 2
|
|
||||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The software is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the software. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
For information regarding this software email:
|
|
||||||
"Joseph Coffland" <joseph@buildbotics.com>
|
|
||||||
|
|
||||||
\******************************************************************************/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const api = require('./api');
|
|
||||||
const modbus = require('./modbus.js');
|
|
||||||
const merge = require("lodash.merge");
|
const merge = require("lodash.merge");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
template: '#tool-view-template',
|
template: "#tool-view-template",
|
||||||
props: ['config', 'template', 'state'],
|
props: ["config", "template", "state"],
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
@@ -110,20 +83,22 @@ module.exports = {
|
|||||||
unsupported: true
|
unsupported: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
'modbus-reg': require('./modbus-reg.js')
|
"modbus-reg": require("./modbus-reg.js")
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'state.mr': function () { this.value = this.state.mr }
|
"state.mr": function () {
|
||||||
|
this.value = this.state.mr;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'input-changed': function () {
|
"input-changed": function () {
|
||||||
this.$dispatch('config-changed');
|
this.$dispatch("config-changed");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
@@ -135,19 +110,19 @@ module.exports = {
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
regs_tmpl: function () {
|
regs_tmpl: function () {
|
||||||
return this.template['modbus-spindle'].regs;
|
return this.template["modbus-spindle"].regs;
|
||||||
},
|
},
|
||||||
|
|
||||||
tool_type: function () {
|
tool_type: function () {
|
||||||
return this.config.tool['tool-type'].toUpperCase();
|
return this.config.tool["tool-type"].toUpperCase();
|
||||||
},
|
},
|
||||||
|
|
||||||
selected_tool: function () {
|
selected_tool: function () {
|
||||||
return this.config.tool['selected-tool'];
|
return this.config.tool["selected-tool"];
|
||||||
},
|
},
|
||||||
|
|
||||||
is_pwm_spindle: function () {
|
is_pwm_spindle: function () {
|
||||||
return this.selected_tool == 'pwm';
|
return this.selected_tool == "pwm";
|
||||||
},
|
},
|
||||||
|
|
||||||
is_modbus: function () {
|
is_modbus: function () {
|
||||||
@@ -170,13 +145,13 @@ module.exports = {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
change_selected_tool: function () {
|
change_selected_tool: function () {
|
||||||
const selectedToolSettings = this.config['selected-tool-settings'] || {};
|
const selectedToolSettings = this.config["selected-tool-settings"] || {};
|
||||||
const settings = selectedToolSettings[this.selected_tool] || {};
|
const settings = selectedToolSettings[this.selected_tool] || {};
|
||||||
this.config.tool = merge({}, this.config.tool, settings['tool']);
|
this.config.tool = merge({}, this.config.tool, settings["tool"]);
|
||||||
this.config['pwm-spindle'] = merge({}, this.config['pwm-spindle'], settings['pwm-spindle']);
|
this.config["pwm-spindle"] = merge({}, this.config["pwm-spindle"], settings["pwm-spindle"]);
|
||||||
this.config['modbus-spindle'] = merge({}, this.config['modbus-spindle'], settings['modbus-spindle']);
|
this.config["modbus-spindle"] = merge({}, this.config["modbus-spindle"], settings["modbus-spindle"]);
|
||||||
|
|
||||||
const tool = this.toolList.find(tool => tool.id == this.config.tool['selected-tool']);
|
const tool = this.toolList.find(tool => tool.id == this.config.tool["selected-tool"]);
|
||||||
this.config.tool["tool-type"] = tool.type || tool.name;
|
this.config.tool["tool-type"] = tool.type || tool.name;
|
||||||
|
|
||||||
this.$dispatch("config-changed");
|
this.$dispatch("config-changed");
|
||||||
@@ -207,71 +182,71 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get_reg_type: function (reg) {
|
get_reg_type: function (reg) {
|
||||||
return this.regs_tmpl.template['reg-type'].values[this.state[reg + 'vt']];
|
return this.regs_tmpl.template["reg-type"].values[this.state[`${reg}vt`]];
|
||||||
},
|
},
|
||||||
|
|
||||||
get_reg_addr: function (reg) {
|
get_reg_addr: function (reg) {
|
||||||
return this.state[reg + 'va'];
|
return this.state[`${reg}va`];
|
||||||
},
|
},
|
||||||
|
|
||||||
get_reg_value: function (reg) {
|
get_reg_value: function (reg) {
|
||||||
return this.state[reg + 'vv'];
|
return this.state[`${reg}vv`];
|
||||||
},
|
},
|
||||||
|
|
||||||
get_reg_fails: function (reg) {
|
get_reg_fails: function (reg) {
|
||||||
const fails = this.state[reg + 'vr']
|
const fails = this.state[`${reg}vr`];
|
||||||
return fails == 255 ? 'Max' : fails;
|
return fails == 255 ? "Max" : fails;
|
||||||
},
|
},
|
||||||
|
|
||||||
show_modbus_field: function (key) {
|
show_modbus_field: function (key) {
|
||||||
return key != 'regs' &&
|
return key != "regs" && (key != "multi-write" || this.tool_type == "CUSTOM MODBUS VFD");
|
||||||
(key != 'multi-write' || this.tool_type == 'CUSTOM MODBUS VFD');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
read: function (e) {
|
read: function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
api.put('modbus/read', { address: this.address });
|
api.put("modbus/read", { address: this.address });
|
||||||
},
|
},
|
||||||
|
|
||||||
write: function (e) {
|
write: function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
api.put('modbus/write', { address: this.address, value: this.value });
|
api.put("modbus/write", { address: this.address, value: this.value });
|
||||||
},
|
},
|
||||||
|
|
||||||
customize: function (e) {
|
customize: function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.config.tool['tool-type'] = 'Custom Modbus VFD';
|
this.config.tool["tool-type"] = "Custom Modbus VFD";
|
||||||
|
|
||||||
const regs = this.config['modbus-spindle'].regs;
|
const regs = this.config["modbus-spindle"].regs;
|
||||||
for (let i = 0; i < regs.length; i++) {
|
for (let i = 0; i < regs.length; i++) {
|
||||||
const reg = this.regs_tmpl.index[i];
|
const reg = this.regs_tmpl.index[i];
|
||||||
regs[i]['reg-type'] = this.get_reg_type(reg);
|
regs[i]["reg-type"] = this.get_reg_type(reg);
|
||||||
regs[i]['reg-addr'] = this.get_reg_addr(reg);
|
regs[i]["reg-addr"] = this.get_reg_addr(reg);
|
||||||
regs[i]['reg-value'] = this.get_reg_value(reg);
|
regs[i]["reg-value"] = this.get_reg_value(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$dispatch('config-changed');
|
this.$dispatch("config-changed");
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function (e) {
|
clear: function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.config.tool['tool-type'] = 'Custom Modbus VFD';
|
this.config.tool["tool-type"] = "Custom Modbus VFD";
|
||||||
|
|
||||||
const regs = this.config['modbus-spindle'].regs;
|
const regs = this.config["modbus-spindle"].regs;
|
||||||
for (let i = 0; i < regs.length; i++) {
|
for (let i = 0; i < regs.length; i++) {
|
||||||
regs[i]['reg-type'] = 'disabled';
|
regs[i]["reg-type"] = "disabled";
|
||||||
regs[i]['reg-addr'] = 0;
|
regs[i]["reg-addr"] = 0;
|
||||||
regs[i]['reg-value'] = 0;
|
regs[i]["reg-value"] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$dispatch('config-changed');
|
this.$dispatch("config-changed");
|
||||||
},
|
},
|
||||||
|
|
||||||
reset_failures: function (e) {
|
reset_failures: function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const regs = this.config['modbus-spindle'].regs;
|
const regs = this.config["modbus-spindle"].regs;
|
||||||
for (let reg = 0; reg < regs.length; reg++)
|
for (let reg = 0; reg < regs.length; reg++) {
|
||||||
this.$dispatch('send', '\$' + reg + 'vr=0');
|
this.$dispatch("send", `$${reg}vr=0`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
replace: true,
|
replace: true,
|
||||||
template: '{{text}}<span class="unit">{{metric ? unit : iunit}}</span>',
|
template: '{{text}}<span class="unit">{{metric ? unit : iunit}}</span>',
|
||||||
props: ['value', 'precision', 'unit', 'iunit', 'scale'],
|
props: ["value", "precision", "unit", "iunit", "scale"],
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
metric: {
|
metric: {
|
||||||
@@ -14,9 +14,9 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
text: function () {
|
text: function () {
|
||||||
var value = this.value;
|
let value = this.value;
|
||||||
if (typeof value == 'undefined') {
|
if (typeof value == "undefined") {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.metric) {
|
if (!this.metric) {
|
||||||
@@ -28,20 +28,20 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ready: function () {
|
ready: function () {
|
||||||
if (typeof this.precision == 'undefined') {
|
if (typeof this.precision == "undefined") {
|
||||||
this.precision = 0;
|
this.precision = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof this.unit == 'undefined') {
|
if (typeof this.unit == "undefined") {
|
||||||
this.unit = 'mm';
|
this.unit = "mm";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof this.iunit == 'undefined') {
|
if (typeof this.iunit == "undefined") {
|
||||||
this.iunit = 'in';
|
this.iunit = "in";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof this.scale == 'undefined') {
|
if (typeof this.scale == "undefined") {
|
||||||
this.scale = 25.4;
|
this.scale = 25.4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
9
src/js/utils.js
Normal file
9
src/js/utils.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
function clickFileInput(formClass) {
|
||||||
|
const form = document.querySelector(`.${formClass}`);
|
||||||
|
form.reset();
|
||||||
|
form.querySelector("input").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
clickFileInput
|
||||||
|
};
|
||||||
@@ -99,20 +99,26 @@
|
|||||||
{#each $networkInfo.wifi.networks as network}
|
{#each $networkInfo.wifi.networks as network}
|
||||||
<Item
|
<Item
|
||||||
class="wifi-network"
|
class="wifi-network"
|
||||||
on:SMUI:action={() => onNetworkSelected(network)}
|
on:SMUI:action={() =>
|
||||||
|
onNetworkSelected(network)}
|
||||||
>
|
>
|
||||||
<Graphic
|
<Graphic
|
||||||
class="strength {$networkInfo.wifi.ssid === network.Name
|
class="strength {$networkInfo.wifi
|
||||||
|
.ssid === network.Name
|
||||||
? 'active'
|
? 'active'
|
||||||
: ''}"
|
: ''}"
|
||||||
>
|
>
|
||||||
<span class="fa fa-wifi background" />
|
<span class="fa fa-wifi background" />
|
||||||
<span
|
<span
|
||||||
class="fa fa-wifi"
|
class="fa fa-wifi"
|
||||||
style={getWifiStrengthStyle(network)}
|
style={getWifiStrengthStyle(
|
||||||
|
network
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</Graphic>
|
</Graphic>
|
||||||
<Text style="margin-right: 20px;">{network.Name}</Text>
|
<Text style="margin-right: 20px;"
|
||||||
|
>{network.Name}</Text
|
||||||
|
>
|
||||||
{#if network.Encryption !== "Open"}
|
{#if network.Encryption !== "Open"}
|
||||||
<Meta>
|
<Meta>
|
||||||
<span class="fa fa-lock" />
|
<span class="fa fa-lock" />
|
||||||
|
|||||||
@@ -66,21 +66,21 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Lower <tt>max-deviation</tt> to follow the programmed path more precisely but
|
Lower <tt>max-deviation</tt> to follow the programmed path more precisely
|
||||||
at a slower speed.
|
but at a slower speed.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In order to improve traversal speed, the path planner may merge consecutive
|
In order to improve traversal speed, the path planner may merge
|
||||||
moves or round off sharp corners if doing so would deviate from the program
|
consecutive moves or round off sharp corners if doing so would deviate
|
||||||
path by less than <tt>max-deviation</tt>.
|
from the program path by less than <tt>max-deviation</tt>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
GCode commands
|
GCode commands
|
||||||
<a href={`${gcodeURL}#gcode:g61`} target="_blank">G61, G61.1</a>
|
<a href={`${gcodeURL}#gcode:g61`} target="_blank">G61, G61.1</a>
|
||||||
and <a href={`${gcodeURL}#gcode:g64`} target="_blank"> G64</a> also affect path
|
and <a href={`${gcodeURL}#gcode:g64`} target="_blank"> G64</a> also affect
|
||||||
planning accuracy.
|
path planning accuracy.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Cornering Speed (Advanced)</h2>
|
<h2>Cornering Speed (Advanced)</h2>
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Junction acceleration limits the cornering speed the planner will allow.
|
Junction acceleration limits the cornering speed the planner will allow.
|
||||||
Increasing this value will allow for faster traversal of corners but may
|
Increasing this value will allow for faster traversal of corners but may
|
||||||
cause the planner to violate axis jerk limits and stall the motors. Use with
|
cause the planner to violate axis jerk limits and stall the motors. Use
|
||||||
caution.
|
with caution.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import TextField from "@smui/textfield";
|
import TextField from "@smui/textfield";
|
||||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||||
@@ -88,7 +93,11 @@
|
|||||||
<Button>
|
<Button>
|
||||||
<Label>Cancel</Label>
|
<Label>Cancel</Label>
|
||||||
</Button>
|
</Button>
|
||||||
<Button defaultAction on:click={onConfirm} disabled={hostname.length === 0}>
|
<Button
|
||||||
|
defaultAction
|
||||||
|
on:click={onConfirm}
|
||||||
|
disabled={hostname.length === 0}
|
||||||
|
>
|
||||||
<Label>Confirm & Reboot</Label>
|
<Label>Confirm & Reboot</Label>
|
||||||
</Button>
|
</Button>
|
||||||
</Actions>
|
</Actions>
|
||||||
|
|||||||
@@ -46,7 +46,8 @@
|
|||||||
axis: string;
|
axis: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SetAxisPositionDialogProps = writable<SetAxisPositionDialogPropsType>();
|
const SetAxisPositionDialogProps =
|
||||||
|
writable<SetAxisPositionDialogPropsType>();
|
||||||
type SetAxisPositionDialogPropsType = {
|
type SetAxisPositionDialogPropsType = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
axis: string;
|
axis: string;
|
||||||
@@ -190,12 +191,14 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
keyboardObserver = new MutationObserver(() => {
|
keyboardObserver = new MutationObserver(() => {
|
||||||
const open = virtualKeyboard.getAttribute("_state") === "open";
|
const open =
|
||||||
|
virtualKeyboard.getAttribute("_state") === "open";
|
||||||
const keyboardHeight = Number.parseFloat(
|
const keyboardHeight = Number.parseFloat(
|
||||||
virtualKeyboardOverlay.style.height
|
virtualKeyboardOverlay.style.height
|
||||||
);
|
);
|
||||||
|
|
||||||
const dialogContainers = document.querySelectorAll<HTMLDivElement>(
|
const dialogContainers =
|
||||||
|
document.querySelectorAll<HTMLDivElement>(
|
||||||
".mdc-dialog .mdc-dialog__container"
|
".mdc-dialog .mdc-dialog__container"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
|
|
||||||
export let open;
|
export let open;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import TextField from "@smui/textfield";
|
import TextField from "@smui/textfield";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||||
@@ -21,9 +26,10 @@
|
|||||||
aria-labelledby="manual-home-axis-dialog-title"
|
aria-labelledby="manual-home-axis-dialog-title"
|
||||||
aria-describedby="manual-home-axis-dialog-content"
|
aria-describedby="manual-home-axis-dialog-content"
|
||||||
>
|
>
|
||||||
<Title id="manual-home-axis-dialog-title"
|
<Title id="manual-home-axis-dialog-title">
|
||||||
>Manually Home {axis.toUpperCase()} Axis</Title
|
Manually Home {axis.toUpperCase()} Axis
|
||||||
>
|
</Title>
|
||||||
|
|
||||||
<Content id="manual-home-axis-dialog-content">
|
<Content id="manual-home-axis-dialog-content">
|
||||||
<p>Set axis absolute position</p>
|
<p>Set axis absolute position</p>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
|
|
||||||
export let open: boolean;
|
export let open: boolean;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
"1/16 in",
|
"1/16 in",
|
||||||
"1/32 in",
|
"1/32 in",
|
||||||
];
|
];
|
||||||
|
|
||||||
const metricBits: `${number} mm`[] = [
|
const metricBits: `${number} mm`[] = [
|
||||||
"12 mm",
|
"12 mm",
|
||||||
"10 mm",
|
"10 mm",
|
||||||
@@ -289,17 +290,21 @@
|
|||||||
|
|
||||||
<Content id="probe-dialog-content" style="overflow: visible;">
|
<Content id="probe-dialog-content" style="overflow: visible;">
|
||||||
<div class="steps">
|
<div class="steps">
|
||||||
<p><b>Step {steps.indexOf(currentStep) + 1} of {steps.length}</b></p>
|
<p>
|
||||||
|
<b>Step {steps.indexOf(currentStep) + 1} of {steps.length}</b>
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
{#each steps as step}
|
{#each steps as step}
|
||||||
<li class:active={currentStep === step}>{stepLabels[step]}</li>
|
<li class:active={currentStep === step}>
|
||||||
|
{stepLabels[step]}
|
||||||
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
{#if currentStep === "CheckProbe"}
|
{#if currentStep === "CheckProbe"}
|
||||||
Attach the probe magnet to the collet, then touch the probe block to the
|
Attach the probe magnet to the collet, then touch the probe
|
||||||
bit.
|
block to the bit.
|
||||||
{:else if currentStep === "BitDimensions"}
|
{:else if currentStep === "BitDimensions"}
|
||||||
<TextFieldWithOptions
|
<TextFieldWithOptions
|
||||||
label="Cutter diameter"
|
label="Cutter diameter"
|
||||||
@@ -313,13 +318,17 @@
|
|||||||
/>
|
/>
|
||||||
{:else if currentStep === "PlaceProbeBlock"}
|
{:else if currentStep === "PlaceProbeBlock"}
|
||||||
{#if probeType === "xyz"}
|
{#if probeType === "xyz"}
|
||||||
Place the probe block face up, on the lower-left corner of your
|
Place the probe block face up, on the lower-left corner of
|
||||||
workpiece.
|
your workpiece.
|
||||||
{:else}
|
{:else}
|
||||||
Place the probe block face down, with the bit above the recess.
|
Place the probe block face down, with the bit above the
|
||||||
|
recess.
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<p>The probing procedure will begin as soon as you click 'Next'.</p>
|
<p>
|
||||||
|
The probing procedure will begin as soon as you click
|
||||||
|
'Next'.
|
||||||
|
</p>
|
||||||
{:else if currentStep === "Probe"}
|
{:else if currentStep === "Probe"}
|
||||||
Probing in progress...
|
Probing in progress...
|
||||||
{:else if currentStep === "Done"}
|
{:else if currentStep === "Done"}
|
||||||
@@ -327,7 +336,9 @@
|
|||||||
Could not find the probe block during probing!
|
Could not find the probe block during probing!
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Make sure the tip of the bit is less than {metric ? "25mm" : "1 in"}
|
Make sure the tip of the bit is less than {metric
|
||||||
|
? "25mm"
|
||||||
|
: "1 in"}
|
||||||
above the probe block, and try again.
|
above the probe block, and try again.
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script type="ts">
|
<script type="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import Radio from "@smui/radio";
|
import Radio from "@smui/radio";
|
||||||
import FormField from "@smui/form-field";
|
import FormField from "@smui/form-field";
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import TextField from "@smui/textfield";
|
import TextField from "@smui/textfield";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||||
@@ -35,9 +40,10 @@
|
|||||||
aria-labelledby="set-axis-position-dialog-title"
|
aria-labelledby="set-axis-position-dialog-title"
|
||||||
aria-describedby="set-axis-position-dialog-content"
|
aria-describedby="set-axis-position-dialog-content"
|
||||||
>
|
>
|
||||||
<Title id="set-axis-position-dialog-title"
|
<Title id="set-axis-position-dialog-title">
|
||||||
>Set {axis.toUpperCase()} Axis Position</Title
|
Set {axis.toUpperCase()} Axis Position
|
||||||
>
|
</Title>
|
||||||
|
|
||||||
<Content id="set-axis-position-dialog-content">
|
<Content id="set-axis-position-dialog-content">
|
||||||
<TextField
|
<TextField
|
||||||
label="Position"
|
label="Position"
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import TextField from "@smui/textfield";
|
import TextField from "@smui/textfield";
|
||||||
import CircularProgress from "@smui/circular-progress";
|
import CircularProgress from "@smui/circular-progress";
|
||||||
@@ -131,24 +136,27 @@
|
|||||||
<Content id="set-time-dialog-content">
|
<Content id="set-time-dialog-content">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div style="display: flex; justify-content: center">
|
<div style="display: flex; justify-content: center">
|
||||||
<CircularProgress style="height: 32px; width: 32px;" indeterminate />
|
<CircularProgress
|
||||||
|
style="height: 32px; width: 32px;"
|
||||||
|
indeterminate
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
{#if networkTimeSynchronized}
|
{#if networkTimeSynchronized}
|
||||||
<p>
|
<p>
|
||||||
Because this controller is connected to the internet, the time is
|
Because this controller is connected to the internet, the
|
||||||
managed automatically, and cannot be manually set.
|
time is managed automatically, and cannot be manually set.
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p>
|
<p>
|
||||||
Because this controller is not connected to the internet, you can
|
Because this controller is not connected to the internet,
|
||||||
manually set the time.
|
you can manually set the time.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Note: any time the controller is turned off, the time will need to be
|
Note: any time the controller is turned off, the time will
|
||||||
reset. If you connect the controller to the internet, the time will be
|
need to be reset. If you connect the controller to the
|
||||||
managed automatically.
|
internet, the time will be managed automatically.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Label>Date & Time</Label>
|
<Label>Date & Time</Label>
|
||||||
@@ -156,7 +164,10 @@
|
|||||||
bind:value
|
bind:value
|
||||||
use={[
|
use={[
|
||||||
InitialFocus,
|
InitialFocus,
|
||||||
[virtualKeyboardChange, (newValue) => (value = newValue)],
|
[
|
||||||
|
virtualKeyboardChange,
|
||||||
|
(newValue) => (value = newValue),
|
||||||
|
],
|
||||||
]}
|
]}
|
||||||
label="Time"
|
label="Time"
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
@@ -166,8 +177,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To display your local time correctly, the controller must know what
|
To display your local time correctly, the controller must know
|
||||||
timezone it is in.
|
what timezone it is in.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="timezones-container" style="margin-top: 20px;">
|
<div class="timezones-container" style="margin-top: 20px;">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, { Title, Actions, InitialFocus } from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import * as Api from "$lib/api"
|
import * as Api from "$lib/api";
|
||||||
|
|
||||||
export let open;
|
export let open;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import LinearProgress from "@smui/linear-progress";
|
import LinearProgress from "@smui/linear-progress";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Dialog, { Title, Content, Actions, InitialFocus } from "@smui/dialog";
|
import Dialog, {
|
||||||
|
Title,
|
||||||
|
Content,
|
||||||
|
Actions,
|
||||||
|
InitialFocus,
|
||||||
|
} from "@smui/dialog";
|
||||||
import Button, { Label } from "@smui/button";
|
import Button, { Label } from "@smui/button";
|
||||||
import TextField from "@smui/textfield";
|
import TextField from "@smui/textfield";
|
||||||
import Icon from "@smui/textfield/icon";
|
import Icon from "@smui/textfield/icon";
|
||||||
@@ -60,7 +65,10 @@
|
|||||||
bind:value={password}
|
bind:value={password}
|
||||||
use={[
|
use={[
|
||||||
InitialFocus,
|
InitialFocus,
|
||||||
[virtualKeyboardChange, (newValue) => (password = newValue)],
|
[
|
||||||
|
virtualKeyboardChange,
|
||||||
|
(newValue) => (password = newValue),
|
||||||
|
],
|
||||||
]}
|
]}
|
||||||
label="Password"
|
label="Password"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@@ -72,7 +80,9 @@
|
|||||||
slot="trailingIcon"
|
slot="trailingIcon"
|
||||||
on:click={() => (showPassword = !showPassword)}
|
on:click={() => (showPassword = !showPassword)}
|
||||||
>
|
>
|
||||||
<Icon class={`fa ${showPassword ? "fa-eye-slash" : "fa-eye"}`} />
|
<Icon
|
||||||
|
class={`fa ${showPassword ? "fa-eye-slash" : "fa-eye"}`}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<HelperText persistent slot="helper">
|
<HelperText persistent slot="helper">
|
||||||
Wifi passwords must be 8 to 128 characters
|
Wifi passwords must be 8 to 128 characters
|
||||||
@@ -82,7 +92,8 @@
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
<em>
|
<em>
|
||||||
Clicking {connectOrDisconnect} will reboot the controller to apply the changes.
|
Clicking {connectOrDisconnect} will reboot the controller to apply
|
||||||
|
the changes.
|
||||||
</em>
|
</em>
|
||||||
</p>
|
</p>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -95,7 +106,8 @@
|
|||||||
<Button
|
<Button
|
||||||
defaultAction
|
defaultAction
|
||||||
on:click={onConfirm}
|
on:click={onConfirm}
|
||||||
disabled={needPassword && (password.length < 8 || password.length > 128)}
|
disabled={needPassword &&
|
||||||
|
(password.length < 8 || password.length > 128)}
|
||||||
>
|
>
|
||||||
<Label>{connectOrDisconnect} & Reboot</Label>
|
<Label>{connectOrDisconnect} & Reboot</Label>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -31,15 +31,15 @@ const empty: NetworkInfo = {
|
|||||||
ssid: "",
|
ssid: "",
|
||||||
networks: []
|
networks: []
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export const networkInfo = writable<NetworkInfo>(empty);
|
export const networkInfo = writable<NetworkInfo>(empty);
|
||||||
|
|
||||||
export function processNetworkInfo(rawNetworkInfo: NetworkInfo) {
|
export function processNetworkInfo(rawNetworkInfo: NetworkInfo) {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const networksByName: Record<string, WifiNetwork> = {}
|
const networksByName: Record<string, WifiNetwork> = {};
|
||||||
|
|
||||||
for (let network of rawNetworkInfo.wifi.networks) {
|
for (const network of rawNetworkInfo.wifi.networks) {
|
||||||
if (network.Name) {
|
if (network.Name) {
|
||||||
network.lastSeen = now;
|
network.lastSeen = now;
|
||||||
network.active = rawNetworkInfo.wifi.ssid === network.Name;
|
network.active = rawNetworkInfo.wifi.ssid === network.Name;
|
||||||
@@ -53,7 +53,7 @@ export function processNetworkInfo(rawNetworkInfo: NetworkInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let network of Object.values(networksByName)) {
|
for (const network of Object.values(networksByName)) {
|
||||||
if (network.lastSeen - now > 30000) {
|
if (network.lastSeen - now > 30000) {
|
||||||
delete networksByName[network.Name];
|
delete networksByName[network.Name];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
type NumberWithUnit = {
|
|
||||||
value: number,
|
|
||||||
metric: boolean,
|
|
||||||
toMetric: () => number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function numberWithUnitToMetric() {
|
function numberWithUnitToMetric() {
|
||||||
return this.metric ? this.value : this.value * 25.4;
|
return this.metric ? this.value : this.value * 25.4;
|
||||||
}
|
}
|
||||||
@@ -38,12 +32,13 @@ function formatFraction(value: number) {
|
|||||||
export const numberWithUnit = {
|
export const numberWithUnit = {
|
||||||
regex: /^\s*(?:(\d+)\s*\/\s*(\d+)|(\d*\.\d+)|(\d+(?:\.\d+)?))\s*("|in|inch|inches|mm|millimeters)\s*$/,
|
regex: /^\s*(?:(\d+)\s*\/\s*(\d+)|(\d*\.\d+)|(\d+(?:\.\d+)?))\s*("|in|inch|inches|mm|millimeters)\s*$/,
|
||||||
parse: function (str: string) {
|
parse: function (str: string) {
|
||||||
|
// eslint-disable-next-line prefer-const
|
||||||
let [, numerator, denominator, decimal1, decimal2, unit]: any = str?.match(numberWithUnit.regex) ?? [];
|
let [, numerator, denominator, decimal1, decimal2, unit]: any = str?.match(numberWithUnit.regex) ?? [];
|
||||||
|
|
||||||
numerator = Number.parseFloat(numerator)
|
numerator = Number.parseFloat(numerator);
|
||||||
denominator = Number.parseFloat(denominator)
|
denominator = Number.parseFloat(denominator);
|
||||||
decimal1 = Number.parseFloat(decimal1)
|
decimal1 = Number.parseFloat(decimal1);
|
||||||
decimal2 = Number.parseFloat(decimal2)
|
decimal2 = Number.parseFloat(decimal2);
|
||||||
|
|
||||||
const metric = (unit ?? "").includes("m");
|
const metric = (unit ?? "").includes("m");
|
||||||
|
|
||||||
@@ -81,10 +76,10 @@ export const numberWithUnit = {
|
|||||||
return "";
|
return "";
|
||||||
|
|
||||||
case value.metric:
|
case value.metric:
|
||||||
return `${value.value} mm`
|
return `${value.value} mm`;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return `${formatFraction(value.value)} in`
|
return `${formatFraction(value.value)} in`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -6,36 +6,36 @@ async function doFetch(method: HttpMethod, url: string, data: any, config: Reque
|
|||||||
...config,
|
...config,
|
||||||
method,
|
method,
|
||||||
cache: "no-cache",
|
cache: "no-cache",
|
||||||
body: (typeof data === 'object')
|
body: (typeof data === "object")
|
||||||
? JSON.stringify(data)
|
? JSON.stringify(data)
|
||||||
: undefined,
|
: undefined,
|
||||||
headers: (typeof data === 'object')
|
headers: (typeof data === "object")
|
||||||
? {
|
? {
|
||||||
"Content-Type": 'application/json; charset=utf-8'
|
"Content-Type": "application/json; charset=utf-8"
|
||||||
}
|
}
|
||||||
: {}
|
: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
return await response.json();
|
return await response.json();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug('API Error: ' + url + ': ' + error);
|
console.debug(`API Error: ${url}: ${error}`);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function GET(url: string, config: RequestInit = {}) {
|
export async function GET(url: string, config: RequestInit = {}) {
|
||||||
return doFetch('GET', url, undefined, config);
|
return doFetch("GET", url, undefined, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function PUT(url: string, data: any = undefined, config: RequestInit = {}) {
|
export async function PUT(url: string, data: any = undefined, config: RequestInit = {}) {
|
||||||
return doFetch('PUT', url, data, config);
|
return doFetch("PUT", url, data, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST(url: string, data: any = undefined, config: RequestInit = {}) {
|
export async function POST(url: string, data: any = undefined, config: RequestInit = {}) {
|
||||||
return doFetch('POST', url, data, config);
|
return doFetch("POST", url, data, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function DELETE(url: string, config = {}) {
|
export async function DELETE(url: string, config = {}) {
|
||||||
return doFetch('DELETE', url, undefined, config);
|
return doFetch("DELETE", url, undefined, config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import 'polyfill-object.fromentries';
|
import "polyfill-object.fromentries";
|
||||||
import matchAll from "string.prototype.matchall";
|
import matchAll from "string.prototype.matchall";
|
||||||
|
|
||||||
matchAll.shim();
|
matchAll.shim();
|
||||||
|
|
||||||
import AdminNetworkView from '$components/AdminNetworkView.svelte';
|
import AdminNetworkView from "$components/AdminNetworkView.svelte";
|
||||||
import SettingsView from '$components/SettingsView.svelte';
|
import SettingsView from "$components/SettingsView.svelte";
|
||||||
import DialogHost, { showDialog } from "$dialogs/DialogHost.svelte";
|
import DialogHost, { showDialog } from "$dialogs/DialogHost.svelte";
|
||||||
import { handleConfigUpdate, setDisplayUnits } from '$lib/ConfigStore';
|
import { handleConfigUpdate, setDisplayUnits } from "$lib/ConfigStore";
|
||||||
import { handleControllerStateUpdate } from "$lib/ControllerState";
|
import { handleControllerStateUpdate } from "$lib/ControllerState";
|
||||||
import { registerControllerMethods } from "$lib/RegisterControllerMethods";
|
import { registerControllerMethods } from "$lib/RegisterControllerMethods";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user