From f60b6cf581ca73956d3a76c73cdbe6d35519d2de Mon Sep 17 00:00:00 2001 From: Laurent Eschenauer Date: Mon, 27 May 2013 23:20:12 +0200 Subject: [PATCH] Added simple battery widget --- config.js.example | 1 + plugins/battery/index.js | 5 ++ plugins/battery/public/css/style.css | 11 ++++ plugins/battery/public/js/battery.js | 80 ++++++++++++++++++++++++++++ plugins/battery/public/js/draw.js | 40 ++++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 plugins/battery/index.js create mode 100644 plugins/battery/public/css/style.css create mode 100644 plugins/battery/public/js/battery.js create mode 100644 plugins/battery/public/js/draw.js diff --git a/config.js.example b/config.js.example index 8ed48b8..eeebc3f 100644 --- a/config.js.example +++ b/config.js.example @@ -3,6 +3,7 @@ var config = { "video-png" // Display the video feed as static pngs (work in every browser) //, "video-stream" // Display the video as a native h264 stream decoded in JS , "hud" // Display the artificial horizon, altimeter, compass, etc. + , "battery" // Display a simple battery widget in the header bar , "pilot" // Pilot the drone with the keyboard ] }; diff --git a/plugins/battery/index.js b/plugins/battery/index.js new file mode 100644 index 0000000..ae690fe --- /dev/null +++ b/plugins/battery/index.js @@ -0,0 +1,5 @@ +function battery(name, deps) { + // Nothing special on the backend for now +}; + +module.exports = battery; diff --git a/plugins/battery/public/css/style.css b/plugins/battery/public/css/style.css new file mode 100644 index 0000000..ec44f21 --- /dev/null +++ b/plugins/battery/public/css/style.css @@ -0,0 +1,11 @@ +#battery { + display: block; + float: right; +} + +#battery .level { + vertical-align: 70%; + margin-left: -35px; + font-family: Arial; + font-size: 12px; +} diff --git a/plugins/battery/public/js/battery.js b/plugins/battery/public/js/battery.js new file mode 100644 index 0000000..63d3bd6 --- /dev/null +++ b/plugins/battery/public/js/battery.js @@ -0,0 +1,80 @@ +(function (window, undefined) { + 'use strict'; + + var Battery; + + Battery = function Battery(cockpit) { + console.log("Loading Bagttery indicator plugin."); + + // Instance variables + this.cockpit = cockpit; + this.level = 100; + + // Add required UI elements + $(".header-container .wrapper").prepend('
100%
'); + this.ctx = $('#battery .gauge').get(0).getContext('2d'); + + // Bind to navdata events on websockets + var self = this; + this.cockpit.socket.on('navdata', function(data) { + if (!jQuery.isEmptyObject(data)) { + requestAnimationFrame(function() { + self.render(data); + }); + } + }); + + // Initial draw + this.draw(); + }; + + Battery.prototype.render = function(data) { + this.level = data.demo.batteryPercentage; + $("#battery .level").text(this.level + '%'); + this.draw(); + } + + Battery.prototype.draw = function() { + var cw = this.ctx.canvas.width; + var ch = this.ctx.canvas.height; + + this.ctx.clearRect(0, 0, cw, ch); + this.ctx.save(); + this.ctx.strokeStyle = 'grey'; + this.ctx.fillStyle = 'grey'; + this.ctx.lineWidth = 2; + roundRect(this.ctx, 5, 1, 40, 20); + this.ctx.fillRect(45, 5, 4, 12); + + var width = Math.floor(this.level / 100 * 35); + this.ctx.fillStyle = this.getColor(); + roundRect(this.ctx, 8, 3, width, 15, 3, true, false); + + this.ctx.restore(); + } + + Battery.prototype.getColor = function() { + if (this.level > 90) { + return 'lightgreen'; + } else if (this.level > 80) { + return 'green'; + } else if (this.level > 70) { + return 'darkgreen'; + } else if (this.level > 60) { + return 'lightyellow'; + } else if (this.level > 50) { + return 'yellow'; + } else if (this.level > 40) { + return 'darkyellow'; + } else if (this.level > 30) { + return 'lightred'; + } else if (this.level > 20) { + return 'red'; + } else { + return 'darkred'; + } + } + + window.Cockpit.plugins.push(Battery); + +}(window, undefined)); diff --git a/plugins/battery/public/js/draw.js b/plugins/battery/public/js/draw.js new file mode 100644 index 0000000..72371c7 --- /dev/null +++ b/plugins/battery/public/js/draw.js @@ -0,0 +1,40 @@ +/** + * Draws a rounded rectangle using the current state of the canvas. + * If you omit the last three params, it will draw a rectangle + * outline with a 5 pixel border radius + * @param {CanvasRenderingContext2D} ctx + * @param {Number} x The top left x coordinate + * @param {Number} y The top left y coordinate + * @param {Number} width The width of the rectangle + * @param {Number} height The height of the rectangle + * @param {Number} radius The corner radius. Defaults to 5; + * @param {Boolean} fill Whether to fill the rectangle. Defaults to false. + * @param {Boolean} stroke Whether to stroke the rectangle. Defaults to true. + * + * Source: http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas + */ +function roundRect(ctx, x, y, width, height, radius, fill, stroke) { + if (typeof stroke == "undefined" ) { + stroke = true; + } + if (typeof radius === "undefined") { + radius = 5; + } + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + if (stroke) { + ctx.stroke(); + } + if (fill) { + ctx.fill(); + } +}