Hi everyone,
I would like to include a question that allows respondents to draw on an image using a brush with some transparency.
A Signature question would be useful here as the canvas size could be customized and a background image could be added through editing the JS/CSS. However, may I know if anyone knows how to change the the colour/ opacity of the pen's ink or how to reference the pen/brush in this type of question?
Thank you very much!
Hi clarrre ,
So I kept looking around and I found a canvas drawing implementation that I am pretty satisfied with. I believe it is just drawing a new line on top of the default black signature line so I am still not sure about the opacity piece. I added HTML in the question text for Color picker and Line Width. I grabbed code from here and here. The size of this can be tweaked using the CSS I posted at the bottom of the other thread about using the Signature question to draw on images. All together, the question could look something like the below:
QSF is below:
Signature_DrawImage_Custom.qsf
JavaScript:
var qid = this.questionId;
const canvas = document.getElementById(qid+'-Signature')
const context = canvas.getContext("2d");
canvas.height = 300;
canvas.width = 800;
const colorPicker = document.querySelector( '.js-color-picker');
colorPicker.addEventListener( 'change', event => {
context.strokeStyle = event.target.value;
} );
const lineWidthRange = document.querySelector( '.js-line-range' );
const lineWidthLabel = document.querySelector( '.js-range-value' );
lineWidthRange.addEventListener( 'input', event => {
const width = event.target.value;
lineWidthLabel.innerHTML = width;
context.lineWidth = width;
} );
context.lineCap = "round";
context.lineJoin = "round";
let drawing = false;
function startDrawing(e) {
drawing = true;
context.beginPath();
}
window.addEventListener("mousedown", startDrawing);
window.addEventListener("touchstart", startDrawing);
function endDrawing(e) {
drawing = false;
}
window.addEventListener("mouseup", endDrawing);
window.addEventListener("touchend", endDrawing);
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect(),
scaleX = canvas.width / rect.width,
scaleY = canvas.height / rect.height;
return {
x: (evt.clientX - rect.left) * scaleX,
y: (evt.clientY - rect.top) * scaleY
}
}
function draw(e) {
if (!drawing) return;
let { x, y } = getMousePos(canvas, e);
context.lineTo(x, y);
context.stroke();
}
window.addEventListener("mousemove", draw);
window.addEventListener("touchmove", draw);
function startDrawing(e) {
drawing = true;
context.beginPath();
draw(e);
}
jQuery("#"+this.questionId+"-Signature").css({"background":"url('https://png.pngtree.com/thumb_back/fw800/background/20190223/ourmid/pngtree-bright-sunny-landscape-civilized-city-background-material-homesgreen-citylow-carbonenvironmental-image_82202.jpg')",
"background-size": "100% 100%",
"background-repeat": "no-repeat",
"background-position": "center center"});
jQuery("#"+this.questionId+"-ClearSignature").css({"background-color": "white"});
Question Text HTML:
Px
Please draw below:
CSS:
@media (min-width: 480px) {
.SignatureBox {
width: 1200px !important;
height: 450px !important;
}
}
Hi Tom_1842
Thank you so much for your generous help! This truly helped a lot.
Since I would not need the respondents to choose the colour themselves (which is a really awesome feature btw!) in the current project that I am working on, I simply added/changed the line to fixate the brush colour to one that has some transparency. The default black signature line is still there but I will try to see if I could remove it.
context.strokeStyle = "#00000033";
colorPicker.addEventListener( 'change', event => {
context.strokeStyle = "#00000033";
However, even with the direct import of the QSF question file, the brush strokes seem have long "tails" on my end. While there are only very small issues with lines at the upper left corner, the "tails" grow longer moving towards the lower right corner (as observed from the image above). Would you happen to know what the issue might be? Thank you so much again!
clarrre re sorry about that! I think it was working for me because my screens were slightly larger, but I made a tweak to the JS that sets the canvas width/height and it seems to be working on my smaller screens as well. I've also updated the previously posted QSF it helps anyone.
I liked your idea about including transparency within the hex code and finding a way to remove the event listener that draws the signature line, but I came across another post that I think does what yo're looking to do pretty neatly. This approach involves using z-ordering to stack the image underneath the drawing canvas and making the whole canvas transparent. I also updated the JS so that the pen color and width are set directly. Red in the below example.
QSF:
Signature_DrawImage_Transparent.qsfJS:
var qid = this.questionId;
const canvas = document.getElementById(qid+'-Signature')
const context = canvas.getContext("2d");
canvas.height = 300;
canvas.width = 800;
context.lineCap = "round";
context.lineJoin = "round";
context.strokeStyle = '#ff0000';
context.fillStyle = '#ff0000';
context.lineWidth = '30';
let drawing = false;
function startDrawing(e) {
drawing = true;
context.beginPath();
}
window.addEventListener("mousedown", startDrawing);
window.addEventListener("touchstart", startDrawing);
function endDrawing(e) {
drawing = false;
}
window.addEventListener("mouseup", endDrawing);
window.addEventListener("touchend", endDrawing);
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect(),
scaleX = canvas.width / rect.width,
scaleY = canvas.height / rect.height;
return {
x: (evt.clientX - rect.left) * scaleX,
y: (evt.clientY - rect.top) * scaleY
}
}
function draw(e) {
if (!drawing) return;
let { x, y } = getMousePos(canvas, e);
context.lineTo(x, y);
context.stroke();
}
window.addEventListener("mousemove", draw);
window.addEventListener("touchmove", draw);
function startDrawing(e) {
drawing = true;
context.beginPath();
draw(e);
}
jQuery("#"+this.questionId+"-SignatureBox").css({"background":"url('https://png.pngtree.com/thumb_back/fw800/background/20190223/ourmid/pngtree-bright-sunny-landscape-civilized-city-background-material-homesgreen-citylow-carbonenvironmental-image_82202.jpg')",
"background-size": "100% 100%",
"background-repeat": "no-repeat",
"background-position": "center center",
"z-order":"1"});
jQuery("#"+this.questionId+"-SignLine").css({"display":"none"});
jQuery("#"+this.questionId+"-X").css({"display":"none"});
jQuery("#"+this.questionId+"-ClearSignature").css({"background-color": "white"});
jQuery("#"+this.questionId+"-Signature").css({"opacity": "0.25",
"z-order":"2"});
});
Tom_1842 Thank you so much, this does what I wanted perfectly and is even beyond what I expected!
For anyone who is interested, the pen's colour/ opacity and line width can be customized on lines 8-10.
context.strokeStyle = '#FF000008';
context.fillStyle = '#FF000008';
context.lineWidth = '3';
Using Tom_1842's script with the configuration above and by customizing the opacity as "0.85", respondents can now colour "under" a provided outline with a half-transparent brush, achieving the effect below:
Although the exported images will be stretched to the default signature box size (800 px length x 300 px height), they can easily be resized back to the desired image size.
Thank you very much for your kind assistance again!
Leave a Reply
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.