Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide two new surveyjs widgets #88

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
159 changes: 159 additions & 0 deletions src/photocapture.js
Original file line number Diff line number Diff line change
@@ -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: '<div class="container"><div class="row"><div class="col"> <div class="camera"><video id="video">Video stream not available.</video><button id="startbutton">Take photo</button></div><canvas id="canvas"></canvas></div><div class="col"><div class="output"><img id="photo" alt="The screen capture will appear in this box."><button id="sendbutton">Select photo</button></div></div></div>',
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;
2 changes: 2 additions & 0 deletions src/surveyjs-widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
107 changes: 107 additions & 0 deletions src/uml.js
Original file line number Diff line number Diff line change
@@ -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: '<div class="container"><div class="row"><div class="col"><textarea/></div><div class="col"><div class="output"><img id="photo" alt="The screen capture will appear in this box."><button id="sendbutton">Select this diagram</button></div></div></div>',
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;