diff --git a/package.json b/package.json
index 7b25c0f1..08f070bb 100644
--- a/package.json
+++ b/package.json
@@ -36,5 +36,8 @@
"survey-vue": "^1.0.18",
"virtual-module-webpack-plugin": "^0.3.0",
"webpack": "^3.6.0"
+ },
+ "dependencies": {
+ "pako": "^1.0.6"
}
}
diff --git a/src/photocapture.js b/src/photocapture.js
new file mode 100644
index 00000000..41c26ac5
--- /dev/null
+++ b/src/photocapture.js
@@ -0,0 +1,159 @@
+//var Survey = require("surveyjs");
+
+function init(Survey) {
+ var widget = {
+ name: "photocapture",
+ title: "PhotoCapture",
+ iconName: "icon-video-player",
+ widgetIsLoaded: function() {
+ return true;
+ // return typeof Slider !== "undefined";
+ },
+ isFit: function(question) {
+ return question.getType() === "photocapture";
+ },
+ htmlTemplate: '
![The screen capture will appear in this box.]()
',
+ activatedByChanged: function(activatedBy) {
+ Survey.JsonObject.metaData.addClass("photocapture", [], null, "empty");
+ Survey.JsonObject.metaData.addProperties("photocapture", [
+ /*{
+ name: "width:number",
+ default: 1
+ },
+ {
+ name: "height:number",
+ default: 0
+ }*/
+ ]);
+ },
+ afterRender: function(question, el) {
+ var width = 320; // We will scale the photo width to this
+ var height = 0; // This will be computed based on the input stream
+
+ // |streaming| indicates whether or not we're currently streaming
+ // video from the camera. Obviously, we start at false.
+
+ var streaming = false;
+
+ // The various HTML elements we need to configure or control. These
+ // will be set by the startup() function.
+
+ var video = null;
+ var canvas = null;
+ var photo = null;
+ var startbutton = null;
+ var sendbutton = null;
+ function startup() {
+ console.log("error")
+ video = document.getElementById('video');
+ canvas = document.getElementById('canvas');
+ photo = document.getElementById('photo');
+ startbutton = document.getElementById('startbutton');
+ sendbutton = document.getElementById('sendbutton');
+ navigator.getMedia = ( navigator.getUserMedia ||
+ navigator.webkitGetUserMedia ||
+ navigator.mozGetUserMedia ||
+ navigator.msGetUserMedia);
+
+ navigator.getMedia(
+ {
+ video: true,
+ audio: false
+ },
+ function(stream) {
+ video.srcObject = stream;
+ video.play();
+ question.video = video;
+ },
+ function(err) {
+ console.log("An error occured! " + err);
+ }
+ );
+
+ video.addEventListener('canplay', function(ev){
+ if (!streaming) {
+ height = video.videoHeight / (video.videoWidth/width);
+
+ // Firefox currently has a bug where the height can't be read from
+ // the video, so we will make assumptions if this happens.
+
+ if (isNaN(height)) {
+ height = width / (4/3);
+ }
+
+ video.setAttribute('width', width);
+ video.setAttribute('height', height);
+ canvas.setAttribute('width', width);
+ canvas.setAttribute('height', height);
+ streaming = true;
+ }
+ }, false);
+
+ startbutton.addEventListener('click', function(ev){
+ takepicture();
+ ev.preventDefault();
+ }, false);
+
+ sendbutton.addEventListener('click', function(ev){
+ console.log('toto');
+ sendpicture();
+ ev.preventDefault();
+ }, false);
+
+ clearphoto();
+ }
+
+ // Fill the photo with an indication that none has been
+ // captured.
+
+ function clearphoto() {
+ var context = canvas.getContext('2d');
+ context.fillStyle = "#AAA";
+ context.fillRect(0, 0, canvas.width, canvas.height);
+
+ var data = canvas.toDataURL('image/png');
+ photo.setAttribute('src', data);
+ }
+
+ // Capture a photo by fetching the current contents of the video
+ // and drawing it into a canvas, then converting that to a PNG
+ // format data URL. By drawing it on an offscreen canvas and then
+ // drawing that to the screen, we can change its size and/or apply
+ // other changes before drawing it.
+
+ function takepicture() {
+ var context = canvas.getContext('2d');
+ if (width && height) {
+ canvas.width = width;
+ canvas.height = height;
+ context.drawImage(video, 0, 0, width, height);
+
+ var data = canvas.toDataURL('image/png');
+ photo.setAttribute('src', data);
+ question.value = photo.getAttribute('src');
+ } else {
+ clearphoto();
+ }
+ }
+
+ function sendpicture() {
+ question.value = photo.getAttribute('src');
+ }
+ startup();
+ },
+ willUnmount: function(question, el) {
+ question.video.pause();
+ question.video.srcObject.stop();
+ question.video.srcObject = "";
+ question.video = null;
+ }
+ };
+
+ Survey.CustomWidgetCollection.Instance.addCustomWidget(widget, "customtype");
+}
+
+if (typeof Survey !== "undefined") {
+ init(Survey);
+}
+
+export default init;
diff --git a/src/surveyjs-widgets.js b/src/surveyjs-widgets.js
index 81fd7062..c81a6c9e 100644
--- a/src/surveyjs-widgets.js
+++ b/src/surveyjs-widgets.js
@@ -13,3 +13,5 @@ export { default as prettycheckbox } from "./pretty-checkbox.js";
export { default as bootstrapslider } from "./bootstrap-slider.js";
export { default as microphone } from "./microphone.js";
export { default as emotionsratings } from "./emotionsratings.js";
+export { default as uml } from "./uml.js";
+export { default as photocapture } from "./photocapture.js";
diff --git a/src/uml.js b/src/uml.js
new file mode 100644
index 00000000..62f05d1e
--- /dev/null
+++ b/src/uml.js
@@ -0,0 +1,107 @@
+var pako = require('pako');
+
+function init(Survey) {
+ var widget = {
+ name: "uml",
+ title: "uml",
+ iconName: "icon-uml",
+ widgetIsLoaded: function () {
+ return true;
+ // return typeof Slider !== "undefined";
+ },
+ isFit: function (question) {
+ return question.getType() === "uml";
+ },
+ htmlTemplate: '
![The screen capture will appear in this box.]()
',
+ activatedByChanged: function (activatedBy) {
+ Survey.JsonObject.metaData.addClass("uml", [], null, "empty");
+ Survey.JsonObject.metaData.addProperties("uml", [
+ /*{
+ name: "width:number",
+ default: 1
+ },
+ {
+ name: "height:number",
+ default: 0
+ }*/
+ ]);
+ },
+ afterRender: function (question, el) {
+ //el.firstChild.firstChild.firstChild.value ='toto';
+ var textArea = el.firstChild.firstChild.firstChild;
+ var photo = el.firstChild.childNodes[1].firstChild.firstChild;
+ textArea.addEventListener('input', function() {
+ var value = textArea.value;
+ var s = decodeURIComponent(encodeURIComponent(value));
+ //$(this).attr("src", "http://www.plantuml.com/plantuml/img/"+encode64(value));
+ var res = encode64(pako.deflate(s, {
+ raw: true,
+ to: 'string'
+ }));
+ //console.log(res);
+ if (res != 'SyfFqYssSyp9J4vLi5B8ICt9oIy60000')
+ photo.setAttribute('src', "http://www.plantuml.com/plantuml/png/" + res);
+ question.value = value;
+ });
+
+
+ function encode64(data) {
+ var r = '';
+ for (var i = 0; i < data.length; i += 3) {
+ if (i + 2 == data.length) {
+ r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0);
+ } else if (i + 1 == data.length) {
+ r += append3bytes(data.charCodeAt(i), 0, 0);
+ } else {
+ r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), data.charCodeAt(i + 2));
+ }
+ }
+ return r;
+ }
+
+ function append3bytes(b1, b2, b3) {
+ var c1 = b1 >> 2;
+ var c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
+ var c3 = ((b2 & 0xF) << 2) | (b3 >> 6);
+ var c4 = b3 & 0x3F;
+ var r = '';
+ r += encode6bit(c1 & 0x3F);
+ r += encode6bit(c2 & 0x3F);
+ r += encode6bit(c3 & 0x3F);
+ r += encode6bit(c4 & 0x3F);
+ return r;
+ }
+
+ function encode6bit(b) {
+ if (b < 10) {
+ return String.fromCharCode(48 + b);
+ }
+ b -= 10;
+ if (b < 26) {
+ return String.fromCharCode(65 + b);
+ }
+ b -= 26;
+ if (b < 26) {
+ return String.fromCharCode(97 + b);
+ }
+ b -= 26;
+ if (b == 0) {
+ return '-';
+ }
+ if (b == 1) {
+ return '_';
+ }
+ return '?';
+ }
+ },
+ willUnmount: function (question, el) {}
+ };
+
+ Survey.CustomWidgetCollection.Instance.addCustomWidget(widget, "customtype");
+}
+
+if (typeof Survey !== "undefined") {
+ init(Survey);
+}
+
+export default init;
\ No newline at end of file