signature pad in modal not working (ink is offset from mouse) - javascript

I am trying to use signaturepad in a bootstrap modal, I have a canvas in a div:
<div class="modal-body">
<div class='signature-container' >
<canvas id="signature"></canvas>
</canvas>
</div>
On init, I do (coffeescript):
canvas = $("canvas#signature")[0]
signature_pad = new SignaturePad(canvas, backgroundColor: 'rgb(255, 255, 255)')
My css for the canvas is (because I want the canvas to fill the div)
width:100%;
height:100%;
Everything works, but the "ink" is offset from the mouse pointer. When I first click, the initial ink appears to the right and below of the mouse pointer. The farther down I move the mouse, the farther the vertical offset, same with horizontal (i.e. the offset appears to scale linearly). I tried implementing the resize function in the demo but chrome evaluates offsetWidth to 0 and the canvas just shrinks to 0x0.
Anyone have any ideas what I'm doing wrong?

I was having this same exact problem, adding height and width of 100% to the canvas was causing the signature to appear offset horizontally to the right.
This is what was happening:
Screenshot of signature issue
Found this elsewhere on stack - make canvas as wide and as high as parent ... the answer by Phrogz is key.
"3.The width and height attributes on a Canvas specify the number of pixels of data to draw to (like the actual pixels in an image), and are separate from the display size of the canvas."
He provided this bit of jQuery code to make canvas as wide and as high as its parent:
var canvas = document.querySelector('canvas');
fitToContainer(canvas);
function fitToContainer(canvas){
// Make it visually fill the positioned parent
canvas.style.width ='100%';
canvas.style.height='100%';
// ...then set the internal size to match
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
I also wanted to remove the line that appears across the sigpad when you clear it... and to do that I added these options to jquery:
signaturePad = $('.sigPad').signaturePad({
drawOnly: true,
bgColour: '#FFF',
defaultAction: 'drawIt',
penColour: '#2c3e50',
lineWidth: 0,
});
The last line (lineWidth) controls the line across the sigpad.
Happy coding!

Check #media screen zoom
/* Root */
html {
#media screen and (min-width: 1441px) {
zoom: 97%;
}
#media screen and (max-width: 1440px) {
zoom: 95%;
}
#media screen and (max-width: 1540px) {
zoom: 93%;
}
#media screen and (max-width: 1280px) {
zoom: 91%;
}
}

Related

How can I change the blotter canvas size?

For some reason the blotter.js canvas size is not cangable. Blotter seems to generate a canvas named b-canvas by default? But I can't find where it gets it width and height from? And I am not able to set a new width and size by .style in js. Help?!
I've tried all the techniques I could find.
I've also tried to set a Overflow: visible to the parent (Text) in js and in the css file, but the render is still crashing with the bounds of the canvas. What am I doing wrong?
var text = new Blotter.Text("Hello", {
weight: 800,
size: 80,
fill: 'lightgray',
paddingLeft: 80,
paddingRight: 80,
paddingBottom: 80,
paddingTop: 80
});
/*
* https://blotter.js.org
*/
var blotter = new Blotter(material, {
texts: text
});
var canvas = blotter.forText(text).domElement;
canvas.style.visibility = 'visible!important';
canvas.style = "width: 100vh !important";
canvas.style = "height: 100vw !important";
canvas.style = "z-index: -3 !important";
container.appendChild(canvas);
You can simply wrap it inside a div and resize that. The canvas size is probably calculated based on the font-size and it is as big as the drawing itself.
<div id="wrap">
<canvas></canvas>
</div>
<style>
#wrap canvas {
width: 50px !important
}
</style>
Take a look at the "Blotter.js" website itself and inspect its logo, see that it has this same code and how you can resize it.

How to center an overflowing image inside of a constraining div

I have a 240x240px div which contains a fading slideshow of images differing in sizes. I have each image set to a height: 240px with the width being automatic in proportion to its height. Some images are taller than they are wide (in proportion) so I center them inside the div using position: relative; margin: 0 auto This works well except for images which overflow the 240px div. How could I go about centering images inside the div which overflow? I tried this (jQuery) but it doesn't work for some reason I'm sure I can't figure out:
if( $("div img").width() > 240 ) {
$(this).css("margin-left", rv);
var rv = -1 * ($(this).width() / 4) + "px";
}
The logic being, if the image expands the div in width, then shift it to the left by rvpx, rv being 1/4 of the image's width (as 1/2 would clip the image in half on the left, so 1/2 of 1/2 effectually centering it?) My first guess would be that I can't reference $(this) as I am trying to, though I have no idea.
I know I could go and add individual inline CSS styles but that's messy and mundane. I'd rather have a script which can automatically calculate the center of the image then move it accordingly. Any ideas?
I'd recommend something like this:
div.center-img { background:url('/path/img.jpg') center center no-repeat; }
But your question would be answered with something like this:
$('div img').each(function() {
if( this.width > 240 )
$(this).css("margin-left", ((this.width - 240) / -2) + "px");
});
You can use CSS only:
LIVE DEMO
.imgHolder{
border:1px solid #000;
width:240px;
height:240px;
line-height:240px; /* same as element height */
font-size:0; /* to perfectly vertical align middle the image */
text-align:center; /* to horizontally align middle the image */
}
.imgHolder > img{
max-width:100%;
max-height:100%;
vertical-align:middle;
}
Iterate over the images and when they have loaded get the image width and the parent element width, compare the width, and if the image is wider than the parent get half of the difference and subtract that from the left margin to center the image horizontally.
$("div.centered img").each(function(_,el) {
var img = new Image(),
parent = $(el).parent();
img.onload = function() {
var ma = this.width - $(parent).width();
if ( ma > 0 ) {
$(el).css('margin-left', ((ma/2) * -1));
}
}
img.src = this.src;
if (img.complete) img.onload();
});
FIDDLE

Calculating offset for HTML5 video

I am tracing a point in an HTML5 video using canvas overlay. The canvas is on top of the video tag with the following style:
#my-canvas { width: 100%; height: 100%; position:absolute !important; z-index:100000; margin: 0 auto; background-color:rgba(68, 170, 213, 0.0); }
The points were captured via separate (Android) app. Here's how I plot the points on the canvas:
MyClass.prototype.drawLine = function(_context, _ctr, _color) {
_context.lineWidth = 2;
_context.lineJoin = 'round';
_context.strokeStyle = _color;
_context.moveTo(this.data["xs"][_ctr]*this.xOffset, this.data["ys"][_ctr]*this.yOffset);
_context.lineTo(this.data["xs"][_ctr+1]*this.xOffset, this.data["ys"][_ctr+1]*this.yOffset);
_context.stroke();
_context.closePath();
}
I multiply the data points with an offset value to compensate for the screen size. This is how I calculate the offset:
MyClass.prototype.calculateOffsets = function() {
this.yOffset = this.video.offsetHeight/parseFloat(this.data["height"]);
this.xOffset = this.video.offsetWidth/parseFloat(this.data["width"]);
}
This code works fine in a landscape video but not in portrait. I might be missing something with the offset calculation. I would appreciate if you can point me to the proper direction.
Thanks in advance.
When you set canvas size using CSS your canvas will actually always be 300x150 pixels. What you draw to it will be relative to that size.
Try instead to remove the 100% width and height from the CSS rule and set the canvas size for its bitmap every time you get an onresize event etc. CSS sets the element size; this will set the bitmap size (element will follow if no CSS is overriding):
_context.canvas.width = window.innerWidth;
_context.canvas.height = window.innerHeight;
and
#my-canvas {width: 100%; height: 100%;position:absolute...
Notice though that changing the canvas size will also clear it so you will have to redraw everything up to that point if that is needed.

How do you reduce the scrollable height of a div with scaled content?

I have a scrollable div that I zoom/scale the content of using css3 transform. It works fine if I'm zooming in (scaling up the content) but I've noticed that when scaling down, below 100%, the amount that you can scroll vertically of the container div does not reduce.
I've made a jsfiddle to illustrate this
CSS:
.scrollable
{
height: 250px;
width: 250px;
overflow: auto;
background-color: green;
}
.content
{
height :500px;
width : 500px;
background: linear-gradient(red, blue);
...
}
JS/jquery:
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
//var height = (newScale<1)? $("#content").height()/scale*newScale : originalHeight;
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
//'height' : height +'px'
});
scale=newScale;
}
The actual scaling and the amount that you can scroll horizontally works perfectly, but the amount you can scroll vertically doesn't change below 100%.
Note: the amount you can scroll vertically appears to change on the first scaledown/zoomout, but this is simply because the horizontal scrollbar is removed.
I tried to manually change the height of the content, but this just messed with the content dimensions (duh). That's the commented-out height code.
The ellipses are where I've repeated things for other browsers.
I've managed to come up with one solution, though it's probably not the best. I introduced another div around the content, which I call the view wrapper. I set its overflow to "hidden" and manually set its width and height to match what the scaled content should be.
CSS:
.viewwrapper{
height :500px;
width : 500px;
overflow: hidden
}
JS:
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
var $viewwrapper = $("#viewwrapper");
var height = $content.height()/newScale;
var width = $content.width()/newScale;
$viewwrapper.height(height);
$viewwrapper.width(width);
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
});
}
JS Fiddle
Update:
This won't work if you're using jQuery 3.0 or 3.1. The read behaviour of the height and width functions has changed, so they return the scaled values. To fix the above code for those versions you can just say.
function scaleContent(newScale){
var $content = $("#content");
var scaleString = "scale("+newScale+")";
var $viewwrapper = $("#viewwrapper");
$viewwrapper.height($content.height());
$viewwrapper.width($content.width());
$content.css({
'-webkit-transform' : scaleString,
'-webkit-transform-origin' : '0 0',
...
});
}
JSFiddle using jQuery 3.0
However this probably won't make it into future versions of jQuery.
Update 2:
You might see unnecessary scrollbars in Chrome when you zoom out of the content. This is down to a Chrome bug.
you're applying transformations to your #content div, but the outside div, #scrollable has also a fixed height and is not reducing. You have to apply transformations to it too.
Because if you're zooming in, the outside div adapts to the inside content, whereas if you're reducing it does not.

How to reliably get screen width WITH the scrollbar

Is there a way to reliably tell a browser's viewport width that includes the scrollbar, but not the rest of browser window)?
None of the properties listed here tell me the width of the screen INCLUDING the scrollbar (if present)
I figured out how to accurately get the viewport width WITH the scrollbar using some code from: http://andylangton.co.uk/blog/development/get-viewport-size-width-and-height-javascript
Put this inside your $(document).ready(function()
$(document).ready(function(){
$(window).on("resize", function(){
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
});
// Get the correct window sizes with these declarations
windowHeight = viewport().height;
windowWidth = viewport().width;
});
What it Does:
When your page is 'ready' or is resized, the function calculates the correct window height and width (including scrollbar).
I assume you want to know the viewport width with scrollbar included, because the screen it self does not have a scrollbar. In fact the Screen width and heigth will be the computer screen resolution itself, so I'm not sure what you mean with screen width with the scroll bar.
The viewport however, the area where only the page (and scroll bars) is presented to the user, meaning, no browser menus, no bookmarks or whatever, only the page rendered, is where such scroll bar may be present.
Assuming you want that, you can measure the client browser viewport size while taking into account the size of the scroll bars this way.
First don't forget to set you body tag to be 100% width and height just to make sure the measurement is accurate.
body {
width: 100%;
// if you wish to also measure the height don't forget to also set it to 100% just like this one.
}
Afterwards you can measure the width at will.
Sample
// First you forcibly request the scroll bars to be shown regardless if you they will be needed or not.
$('body').css('overflow', 'scroll');
// Viewport width with scroll bar.
var widthWithScrollBars = $(window).width();
// Now if you wish to know how many pixels the scroll bar actually has
// Set the overflow css property to forcibly hide the scroll bar.
$('body').css('overflow', 'hidden');
// Viewport width without scroll bar.
var widthNoScrollBars = $(window).width();
// Scroll bar size for this particular client browser
var scrollbarWidth = widthWithScrollBars - widthNoScrollBars;
// Set the overflow css property back to whatever value it had before running this code. (default is auto)
$('body').css('overflow', 'auto');
Hope it helps.
As long as body is 100%, document.body.scrollWidth will work.
Demo: http://jsfiddle.net/ThinkingStiff/5j3bY/
HTML:
<div id="widths"></div>
CSS:
body, html
{
margin: 0;
padding: 0;
width: 100%;
}
div
{
height: 1500px;
}
Script:
var widths = 'viewport width (body.scrollWidth): '
+ document.body.scrollWidth + '<br />'
+ 'window.innerWidth: ' + window.innerWidth + '<br />';
document.getElementById( 'widths' ).innerHTML = widths;
I put a tall div in the demo to force a scroll bar.
Currently the new vw and vh css3 properties will show full size including scrollbar.
body {
width:100vw;
height:100vh;
}
There is some discussion online if this is a bug or not.
there is nothing after scrollbar so "rest of the window" is what?
But yes one way to do it is make another wrapper div in body where everything goes and body has overflow:none; height:100%; width:100%; on it, wrapper div also also has 100% width and height. and overflow to scroll. SO NOW...the width of wrapper would be the width of viewport
See Example: http://jsfiddle.net/techsin/8fvne9fz/
html,body {
height: 100%;
overflow: hidden;
}
.wrapper {
width: 100%;
height: 100%;
overflow: auto;
}
With jQuery you can calculate the browser's scrollbar width by getting the width difference when overflow: hidden is set and overflow: scroll is set.
The difference in width will be the size of the scrollbar.
Here is a simple example that shows how you could do this.
You can get the window width with scrollbar , that way:
function scrollbar_width() {
if (jQuery('body').height() > jQuery(window).height()) {
/* Modified from: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php */
var calculation_content = jQuery('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
jQuery('body').append(calculation_content);
var width_one = jQuery('div', calculation_content).innerWidth();
calculation_content.css('overflow-y', 'scroll');
var width_two = jQuery('div', calculation_content).innerWidth();
jQuery(calculation_content).remove();
return (width_one - width_two);
}
return 0;
}
Check out vw: http://dev.w3.org/csswg/css-values/#viewport-relative-lengths
body {
width: 100vw;
}
http://caniuse.com/#search=vw
This is my solution for removing the 'scrollbar shadow', because scrollWidth didn't work for me:
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
canvas.width = element.offsetWidth;
canvas.height = element.offsetHeight;
It's easy, but it works. Make sure to add a comment explaining why you assign the same value twice :)

Categories