Asked  6 Months ago    Answers:  5   Viewed   32 times

How can I determine the height of a horizontal scrollbar, or the width of a vertical one, in JavaScript?

 Answers

63

From Alexandre Gomes Blog I have not tried it. Let me know if it works for you.

function getScrollBarWidth () {
  var inner = document.createElement('p');
  inner.style.width = "100%";
  inner.style.height = "200px";

  var outer = document.createElement('div');
  outer.style.position = "absolute";
  outer.style.top = "0px";
  outer.style.left = "0px";
  outer.style.visibility = "hidden";
  outer.style.width = "200px";
  outer.style.height = "150px";
  outer.style.overflow = "hidden";
  outer.appendChild (inner);

  document.body.appendChild (outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;
  if (w1 == w2) w2 = outer.clientWidth;

  document.body.removeChild (outer);

  return (w1 - w2);
};
Tuesday, June 1, 2021
 
Parfait
answered 6 Months ago
100

There is no way to extract the Bitmap out of a Canvas. The only way you can access it is to pass it yourself when creating the canvas like this new Canvas(myBitmap) and keep the reference.

EDIT2: see @Alex comment blow - the approach of passing a Bitmap to the Canvas does not seem to work for more recent versions of Android.

EDIT : If you don't create the Canvas yourself, you could create a screen-sized Bitmap (or whatever size you need) and then pass it to the Canvas in onDraw calls like this: canvas.setBitmap(myBitmap).

Friday, August 6, 2021
 
stand
answered 4 Months ago
51

As seen in the specs for window.open, your parameters are wrong. Try this:

function popUpCal()
{
    var url = "calendar_flight_maint.php";
    var width = 700;
    var height = 600;
    var left = parseInt((screen.availWidth/2) - (width/2));
    var top = parseInt((screen.availHeight/2) - (height/2));
    var windowFeatures = "width=" + width + ",height=" + height +   
        ",status,resizable,left=" + left + ",top=" + top + 
        "screenX=" + left + ",screenY=" + top + ",scrollbars=yes";

    window.open(url, "subWind", windowFeatures, "POS");
}

Here is a jsFiddle

Monday, October 4, 2021
 
coderaider
answered 2 Months ago
36

After running into flicker problems with the scrolling version proposed by David in some browsers (Safari and IE), I've settled on this code that does not have the flicker problem:

function getScrollBarState() {
    var result = {vScrollbar: true, hScrollbar: true};
    try {
        var root = document.compatMode=='BackCompat'? document.body : document.documentElement;
        result.vScrollbar = root.scrollHeight > root.clientHeight;
        result.hScrollbar = root.scrollWidth > root.clientWidth;
    } catch(e) {}
    return(result);
}

It's a derivative of what I was using and the general technique was referenced in the post that fanfavorite posted. It seems to work in every browser I've tried even in IE6. For my purposes, I wanted any failure to return that there was a scrollbar so I've coded the failure condition that way.

Note: this code does not detect if a scrollbar has been forced on or off with CSS. This code detects if an auto-scrollbar is called for or not. If your page might have CSS settings that control the scrollbar, then you can get the CSS and check that first.

Sunday, November 7, 2021
 
Amitai Fensterheim
answered 3 Weeks ago
64

Compositing can do this.

The trick is to process each compositing on a second off-screen canvas, and then merge them using the default source-over mode.

const canvas = document.getElementById( "canvas" );
const ctx = canvas.getContext( "2d" );
// we create an off-screen copy of the canvas to perform our clippings
const copy = canvas.cloneNode();
const off = copy.getContext( "2d" );

// declares our shapes
const circle = new Path2D();
circle.arc( 0, 0, 145, 0, Math.PI * 2 );
const blue_circle = new Path2D();
blue_circle.addPath( circle, { e: 260, f: 160 } );
const red_circle = new Path2D();
red_circle.addPath( circle, { e: 160, f: 310 } );
const yellow_circle = new Path2D();
yellow_circle.addPath( circle, { e: 340, f: 310 } );

// get common area of blue & red
off.fill( blue_circle );
off.globalCompositeOperation = "source-in";
off.fill( red_circle );
// save to visible canvas
ctx.drawImage( copy, 0, 0 )

// clear
off.globalCompositeOperation = "source-over";
off.clearRect( 0, 0, 500, 500 );
// get common area of blue & yellow
off.fill( blue_circle );
off.globalCompositeOperation = "source-in";
off.fill( yellow_circle );
// save to visible canvas
ctx.drawImage( copy, 0, 0 )

// clear
off.globalCompositeOperation = "source-over";
off.clearRect( 0, 0, 500, 500 );
// get common area of red & yellow
off.fill( red_circle );
off.globalCompositeOperation = "source-in";
off.fill( yellow_circle );
// save to visible canvas
ctx.drawImage( copy, 0, 0 );

// last pass to blend the colors
off.globalCompositeOperation = "source-over";
off.clearRect( 0, 0, 500, 500 );
off.globalAlpha = 0.6;
off.fillStyle = "blue";
off.fill( blue_circle );
off.fillStyle = "red";
off.fill( red_circle );
off.fillStyle = "yellow";
off.fill( yellow_circle );

// draw only where we did draw previously
ctx.globalCompositeOperation = "source-in";
ctx.drawImage( copy, 0, 0 );
canvas { background: white }
<canvas id="canvas" width="500" height="500"></canvas>

Using lines instead:

const canvas = document.getElementById( "canvas" );
const ctx = canvas.getContext( "2d" );
// we create an off-screen copy of the canvas to perform our clippings
const copy = canvas.cloneNode();
const off = copy.getContext( "2d" );
off.lineWidth = 30;

const bottom_left_top_center = new Path2D("M0,300L300,0");
const top_left_bottom_right = new Path2D("M0,0L300,300");
const bottom_left_bottom_right = new Path2D("M0,200L300,200");

off.stroke( bottom_left_top_center );
off.globalCompositeOperation = "source-in";
off.stroke( top_left_bottom_right );

// save to visible canvas
ctx.drawImage( copy, 0, 0 )

// clear
off.globalCompositeOperation = "source-over";
off.clearRect( 0, 0, 500, 500 );

off.stroke( bottom_left_top_center );
off.globalCompositeOperation = "source-in";
off.stroke( bottom_left_bottom_right );
// save to visible canvas
ctx.drawImage( copy, 0, 0 )

// clear
off.globalCompositeOperation = "source-over";
off.clearRect( 0, 0, 500, 500 );

off.stroke( top_left_bottom_right );
off.globalCompositeOperation = "source-in";
off.stroke( bottom_left_bottom_right );
// save to visible canvas
ctx.drawImage( copy, 0, 0 )
canvas { background: white }
<canvas id="canvas" width="300" height="300"></canvas>
Saturday, November 13, 2021
 
CM99
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share