brenden / node-webshot

Easy website screenshots in Node.js
2.12k stars 285 forks source link

How to get the scrollheight of the page? #134

Closed pranny closed 8 years ago

pranny commented 8 years ago

I want to get the scrollHeight of the screenshot so that I can use it to display the image in a react native app. So far I am not sure how to get the height. This is what I am trying. But this implementation does not allow for a callback to happen when onLoadFinished's function is executed.

  options.screenSize = {
    width: viewport.width || DeviceProfiles[device].width,
    height: viewport.height || DeviceProfiles[device].height
  };
  options.shotSize = {
    width:  'all',
    height: 'all'
  };
  let _height = 0.9;
  options.userAgent = DeviceProfiles[device].UA || '';
  // this didn't seem to work for me
  //options.zoomFactor = viewport.pixelRatio;
  options.onLoadFinished = {
    fn: function() {
      document.body.style.webkitTransform = "scale(" + this.pixelRatio + ")";
      document.body.style.webkitTransformOrigin = "0% 0%";
      document.body.style.width = (100 / this.pixelRatio) + "%";
      document.body.style.height = (100 / this.pixelRatio) + "%";
      _height = document.body.scrollHeight;
    },
    context: { pixelRatio: viewport.pixelRatio }
  };
  return options;

I also tried attaching a callback like below, but this also does not work

  options.onLoadFinished = {
    fn: function() {
      document.body.style.webkitTransform = "scale(" + this.pixelRatio + ")";
      document.body.style.webkitTransformOrigin = "0% 0%";
      document.body.style.width = (100 / this.pixelRatio) + "%";
      document.body.style.height = (100 / this.pixelRatio) + "%";
      this.cb(document.body.scrollHeight);
    },
    context: { pixelRatio: viewport.pixelRatio, cb: function(height) {
         // do something
      } }
  };

What would be the best way to achieve this?

pranny commented 8 years ago

I got it working, but had to take a slightly different route. In my case, I am uploading the screenshots to S3 through a stream. So, I had to create two streams from the phantomjs stream. One stream does the s3 upload, while other stream is used to fetch the dimensions. In case, someone's wondering, here is the code.

var ws = require('webshot');
var Readable = require('stream').Readable;
var AWS = require('aws-sdk');
var Passthrough = require('stream').PassThrough;

 ws(message.url, _opts, (err, stream) => {
    if(err) return console.log(err);

    /*
     * Since `stream` is a Stream, and we can use
     * it only once, so we create passthroughs
     * so that it is split into two streams.
     * Once we have two streans, we send one stream
     * for S3 upload. We use the other stream to
     * get the image dimensions.
     */
    var a = new Passthrough();
    var b = new Passthrough();

    stream.pipe(a);
    stream.pipe(b);

    var readableStream = new Readable().wrap(a);
    var readableStreamForDimensions = new Readable().wrap(b);

    var _chunkSize = 0;

    var _height = 0;
    var _width = 0;

    readableStreamForDimensions.on('readable', function () {
      var chunk;
      if( _chunkSize < 1) {
        chunk = readableStreamForDimensions.read()
        _chunkSize += 1;
        /*
         * Refer PNG specifications
         * http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html
         */
        _height = chunk.readInt32BE(20);
        _width = chunk.readInt32BE(16);
      }
    });
        let s3 = new AWS.S3(
                        { params:
                            {
                                Bucket: 'BUCKET',
                                Key: 'KEY
                            }
                        });
    s3.upload({ Body: readableStream },
        function(err, data) {
            if(err) {
                return console.log(err);
            }
            else {
                console.log(_height, _width);
            }
       }
     );