Nightmarejs screenshot doesn't clip at the bottom of long pages - node.js

I am trying to make a screenshot at the bottom of the long page (e.g. http://www.taoism.net/ttc/complete.htm) like so:
Nightmare({ show: false })
.viewport(1024, 30000)
.goto('http://www.taoism.net/ttc/complete.htm')
.wait()
.screenshot(sImagePath, {
x : 0,
y : 27711,
width : 1024,
height : 133
});
Screenshot file size is 0 bytes.
Tested with different y values, it works until ~8000px.
Tried using .scrollTo, it did not help.
Does anybody know a workaround?
P.S. Nightmarejs wraps around electron browser.

This might be what you've looking for https://github.com/segmentio/nightmare/issues/328#issuecomment-159311982
Basically you dynamically adjust the viewport dimensions based on the content to grab size.

Related

SVG getScreenCTM() on FireFox

GOAL
I am trying to build a signature pad in SVG. You can view
Sample project here.
Description
So far, it works in Chrome, Edge and Opera as desired but, in Firefox, getScreenCTM() doesn't account for the scale.
Research
I went through a bunch of documentation from bugzilla and a couple of posts here in SO such as SVG: GetScreenCTM() for nested SVG is different in Firefox but, still couldn't figure out how to fix my issue.
Problem
I've added a browse check to handle only Firefox (since all other browsers provides the desired result) which allows me to add extra code to fix the problem but, thus far, had no success. (SPSignature:416)
Reproduce the error
To reproduce the error, open the sample link in FireFox than, resize the box so it is at least 20% smaller as in fullscreen. You will see the mouseX/Y position change as scale changes.
I've tried to get the matrix transform from the group tag but, it returns similar result from the SVG. How do I calculate the CTM, so its result is similar/equal to Chrome?
Code
Source code here SPSignature:416
_getCursorPoint(event)
{
const svg = document.querySelector('.spsignature svg');
let pt = svg.createSVGPoint();
pt.x = event.clientX;
pt.y = event.clientY;
// firefox workaround:
if (this._checkBrowser() === 'Firefox') {
const matrix = this._decomposeMatrix(svg.getScreenCTM());
let cood = {
x: event.layerX,
y: event.layerY
};
if (matrix.scaleX < 0.9 || matrix.scaleY < 0.9) {
console.log('%c #todo: fix mouse position for FF on getScreenCTM().', 'background:#c00;color:#fff;padding:3px;');
}
return cood;
}
return pt.matrixTransform(svg.getScreenCTM().inverse());
}
To "fix" the mouse XY problem on FF, I've used the root scale value to allow for the calculation of the cursor XY position.
The scale can be retrieved from the matrix based on https://gist.github.com/2052247.
Also, in FF, I've used the event.layerX and event.layerY instead of event.clientX and event.clientY for the initial mouse coordinate values.
So, instead of using matrixTransform(svg.getScreenCTM().inverse()) to return the calculated XY relative to the SVG, I've used the scale and layerXY to calculate the right XY position.

Using rotate for images leads to blank pdf with pdfkit

I have asked the question on the repository directly, but in my experience SO is more reactive.
Hey there,
I am trying to create a pdf from photos using pdfkit.
Depending on whether an image is in landscape or portait mode, I want to turn the image around.
This basically means the following (in typescript) :
function toPostscriptPoint(mm: number) {
return mm * 2.8346456693;
}
const document = new PDFDocument({
size: [toPostscriptPoint(156), toPostscriptPoint(106)],
});
document.pipe(fs.createWriteStream('output.pdf'));
document.save();
document.rotate(90);
document.image(
'photos/sample.jpeg',
{ width: toPostscriptPoint(150), fit: [toPostscriptPoint(150), toPostscriptPoint(100)] });
document.restore();
document.end();
What happens though is that the pdf renders completely white. I do see however that something is happening, because the pdf has the size of the input image.
Is rotation for images not supported? What would be possible alternatives? I would like to avoid having to rewrite my files before putting them in the pdf.
Thanks
Alright, after investigation, I can answer my own question :).
I could see that the images were in the pdf somehow because of the size of the file so I dived deeper.
What happened was that the image was rendered out of the viewport. This was due to multiple things:
By default, the origin of a page after rotation in pdfkit is the center of the page! ( See the doc for more info)
The origin is rotated together with the transformation.
The x and y in the image method are actually inverted.
So after getting all this right, the following code shows the image as expected :
function toPostscriptPoint(mm: number) {
return mm * 2.8346456693;
}
const document = new PDFDocument({
size: [toPostscriptPoint(156), toPostscriptPoint(106)],
});
document.pipe(fs.createWriteStream('output.pdf'));
document.save();
document.rotate(90, {origin : [0, 0]});
document.image(
'photos/sample.jpeg',
toPostscriptPoint(0),
toPostscriptPoint(-150),
{ width: toPostscriptPoint(150), height: toPostscriptPoint(100) });
document.restore();
document.end();
Note the :
origin argument in the rotation
toPostscriptPoint(-150) actually takes into account the position of the origin, and corresponds to the X axis.
Hope that helps some later on :).
Its because taking picture from camera , if picture ISO is less than 100 it will be automatically rotated , take picture with iso more than or equal to 100 to avoid autorotation.

Chrome capture visible tab gives messy result

I have a Chrome extension, where I'm using the captureVisibleTab method of the chrome.tabs API to capture screenshots. I have tested the extension on 3 devices (Chromebooks) and I'm getting mixed results. Two of them work perfectly, but one always returns a completely malformed screenshot.
My code:
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab){
chrome.tabs.get(tabId, function (_tab) {
if (_tab.status == "complete" && _tab.active ) {
chrome.tabs.captureVisibleTab( function(dataUrl){
});
}
});
});
Any ideas what could be the issue on that one device?
EDIT
Example of a bad screenshot:
I suspect that the device pixel ratio is higher on your 3rd device. This was an issue I was having with Retina displays when building a screenshot app. Basically, certain high-resolution displays have a higher ratio pixels per square inch. You're going to want to find window.devicePixelRatio and divide the context scale by that amount.
Assuming that you are using Canvas to draw the screenshot and capture it into an image, this little snippet should help show what you're going to want to do:
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
if(window.devicePixelRatio > 1){
context.scale(1/window.devicePixelRatio, 1/window.devicePixelRatio);
}
context.drawImage(image, 0, 0);
Let me know if that works for you.

How to control the loading order of multiple images in openseadragon

In my situation, I have 10 images loaded in a viewer with the same bounds. each image is arranged one behind other.
// source is an array of url images.
for(i=0;i < source.length-1;i++){
this.viewer.addTiledImage({
tileSource: source[i],
index: i,
opacity:0
});
}
My intention is to control opacity of each image using a slider (range input), the slider set the correspondent image opacity to 1, and let the others with no opacity. This works well.
The idea is preload images and change images smoothly.
The problem
All images are loaded at same time when zooming or panning, so I want to control the load order and give priority to the visible image then load the next image, and so on.
How can I do that? I can't find any method to pause the loading of tiles.
Thanks for your help.
You can try using the 'open' event and adding the next image once the previous one has loaded. Something like:
var i =0, viewer = this.viewer;
viewer.addTiledImage({
tileSource: source[i],
index: i,
opacity:0
});
viewer.addHandler('open', function() {
i++;
if (source[i]) {
viewer.addTiledImage({
tileSource: source[i],
index: i,
opacity:0
});
} else {
viewer.removeAllHandlers('open');
}
});
Note that this is untested sample code but you should get the idea. And you should actually use removeHandler() instead of removeAllHandlers(), but this is just an example.
I can fix my issue by controlling opacity instead of control network download, openseadragon has no method to control the download order at dzi image level, so the way is control the opacity because 0 opacity don't do any download. Thanks to the openseadragon contributors for help me to solve this issue.
https://github.com/openseadragon/openseadragon/issues/971

Cycle Divs of text with images

I'm trying to sync up my image slides with their textblocks. I've found that Cycle 2 is a great jQuery plug-in and a simple code got me quite far. There's one issue, however. Whenever the text slides for the first time the transition is really bad. The letters of the current and next block "morph" into eachother for a second. After the first cycle everything works as it should.
Here's the cycle code:
$("#slideshow").cycle({
timeout:0, // no autoplay
fx: 'scrollHorz',
randomizeEffects: false,
next: '#next',
prev: '#prev',
});
$("#text").cycle({
timeout:0, // no autoplay
fx: 'scrollHorz',
next: '#next',
prev: '#prev',
});
U can see everything in this fiddle: http://jsfiddle.net/lucb792/85TCZ/1/ (just click arrow left or right)
Is this something that can be fixed, or do I need to search for other solutions to make something like this?
It looks like the plugin is changing the width of the text the first time you use the prev/next controls. Instead of setting the width to the #text, set the width to the divs inside #text slideshow. Changing the CSS to this fixed it for me:
#text div{
width:600px;
}
Here is the fiddle: http://jsfiddle.net/bbernar1/85TCZ/3/

Resources