Redrawing background using ResizeObserver causes flashing in FireFox - javascript

I'm using Trianglify to create backgrounds for a div element. I wanted to write the function to regenerate the background anytime the window is resized.
Here is the function that adds the generated png to the div.
const header = document.querySelector('#header');
const addBackground = target =>{
const dimensions = target.getClientRects()[0];
const pattern = Trianglify({
width: dimensions.width,
height: dimensions.height,
cell_size: Math.random()*200 + 40
});
target.style['background-image'] = 'url(' + pattern.png() + ')';
}
addBackground(header);
And here is the ResizeObserver
const ro = new ResizeObserver( () => {
addBackground(header);
});
ro.observe(header);
This works fine in chrome and edge but it creates an effect in FireFox where the background image isn't generated until the user is done resizing. This would be fine if it didn't clear the background during the resizing.
I've created a fiddle that recreates the issue.
Link to Fiddle

Related

How to set img attributes with JS

So I am trying to set attributes (width and height) of my all images on page.
So i do something like that:
const images = document.querySelectorAll('img');
const setImagesAttributes = () => {
images.forEach(img => {
img.setAttribute('width', img.clientWidth);
img.setAttribute('height', img.clientHeight);
})
}
window.onload = () => {
setImagesAttributes();
window.addEventListener('resize', debounce(setImagesAttributes));
}
And now something weird happen. So I think 90% of images work correct, the behave in same way like before adding script. But some images have very low height, idk what happend. Why one image behave normally, others not.
Before adding script:
After script:
But as i sad over 90% of images works correct. After adding script they have W & H attributes and work fine

DOM element to image generates only white image

I'm using html2canvas to create images from the DOM element.
The code looks like this.
const node = document.getElementById('domElement')
html2canvas(node, {
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight,
}).then(canvas => {
const image = canvas.toDataURL()
})
But its only rendering an image that is fully white. The image size (l*b) is accurate.
But when I try to render the image of the full body it shows the image but with blank white screen on top.
i.e. when,
const node = document.body
How will the elements be added properly and not the blank white screen on the image?
The code is inside an antd design modal.
This statement solved my problem.
window.scrollTo(0, 0)
The final code looks like
window.scrollTo(0, 0)
const node = document.getElementById('domElement')
html2canvas(node, {
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight,
}).then(canvas => {
const image = canvas.toDataURL()
})

Unexpected border pattern in a grid with rectangles in p5.js

I am trying to generate a square grid like pattern in p5js that covers as much of the browser window as possible.I am using p5js in instance mode as I using this with react and I am using chrome in Win10.
Here is my code:-
var size = 15;
var height = window.innerHeight;
var width = window.innerWidth;
Sketch = (p) => {
p.setup = () => {
p.createCanvas(width,height)
p.frameRate(60);
p.noLoop();
}
p.draw = () => {
p.background(250);
p.stroke(0);
p.noFill();
for(let i =0;i*size +size <width;i++) {
for(let j=0;j*size +size<height;j++) {
p.rect(i*size,j*size,size,size);
}
}
}
p.mouseDragged = (e) => {
p.stroke(0);
let x = Math.floor(e.clientY/size);
let y = Math.floor(e.clientX/size);
p.fill(220);
p.rect(y*size,x*size,size,size);
}
}
I call p.noLoop() so it doesnt refreshes everytime and I also have a button that calls p.redraw() to change everything to default. Here is the grid and behaviour I get:
The borders of grids are of varying sizes, first they decrease then increase then decrease and so on. Also, the area around which I drag my mouse has even more weird borders(This gets resolved when I click somewhere else so is this a GPU Aliasing rendering issue?). How do I create grid with same borders throughout my screen?
Edit: When I render even a single box, it has issues. The left and upper border are fine. However the right and down borders have an extra pixel of grayish borders which seems to be the problem. How do I fix this?
Also, How does strokeWeight and rect work in p5js? If I do strokeWeight(10) and rect(3,2,50,50), does that create a 50 by 50 rectangle with 10 pixels borders all around or the borders are included in the rectangle size?

Weird stuttering when generating animated gifs using gifshot.js on ios

Ok, so a little bit of background... I'm trying to generate animated gifs from animations done on an HTML5 canvas using JavaScript. Specifically, I'm adding data layers to a Mapbox GL JS map and looping through them.
On each iteration, I save the canvas element and transform it to a blob before calling URL.createObjectURL(blob) and setting that as the source to a new image. After the loop is finished I generate a gif using gifshot (https://github.com/yahoo/gifshot) and the images I previously created.
This process works perfectly in all browsers (mobile too!) EXCEPT on iPhone ios. On ios the gif has weird stutters and transparency issues. I have tried other gif creation libraies but all have the same issue on ios. Could it be a memory problem or something? I'm at my wit's end on this, so any help is greatly appreciated!
This is the code inside each loop:
var cv = map.getCanvas()
var oneImage = new Image();
cv.toBlob(function(blob) {
url = URL.createObjectURL(blob);
oneImage.src = url
images_arr.push(oneImage)
i++;
setTimeout(function(){
gifLoop(images_arr);
},1000)
})
and this is the code I call when the loop is finished:
var w = window.innerWidth;
var h = window.innerHeight;
recalculated_size = calculateAspectRatioFit(w, h, maxWidth, maxHeight)
w = recalculated_size.width
h = recalculated_size.height
gifshot.createGIF({
'images': images_arr,
'gifWidth': w,
'gifHeight':h,
},function(obj) {
if(!obj.error) {
var image = dataURItoBlob(obj.image)
image = URL.createObjectURL(image);
var animatedImage = document.getElementById('gif');
animatedImage.src = image
var link = $('#gif-link');
link.attr('href',image);
filename = curr_layer_id + '_' + curr_time +'.gif'
link.attr('download', filename);
}
});

Using jspdf to save html page as pdf, saved pdf contains incomplete page content if browser is zoomed, Why?

I am using jspdf and html2canvas combination to save html page as pdf. A pdf copy of current page is saved the moment you click a button. The problem is, if you zoom in the page, and then click the button, the saved pdf contains incomplete portion of the current page. Most of the part not visible on page due to zooming, gets cut off in the saved pdf page. What is the solution?
Below is the js code being invoked upon click of save button-
var pdf = new jsPDF('l', 'pt', 'a4');
var source = $('#someId')[0];
var options = {
background : '#eee'
};
pdf.addHTML(source, options, function(){
pdf.save('abcd.pdf');
});
EDIT
Taking idea from Saurabh's approach, I tried quite a similar thing, but without writing code for any extra div element. Before saving to pdf I made the screen size of a fixed width, and after printing I brought back the width back to default normal. It is working fine for, if it fails, we can always fix the height of the screen too, so that it appears fine in generated pdf despite zooming. Below is the code used by me:-
var pdf = new jsPDF('l', 'pt', 'a4');
var source = $('#someId')[0];
var options = {
background : '#eee'
};
var width = source.clientWidth;
source.style.width = '1700px';
pdf.addHTML(source, options,
function(){
pdf.save('abcd.pdf');
source.style.width = width+'px';
});
Here is how I managed to get the full page pdf while the page is zoomed in using jsPDF's new .html() method. First, I force the page zoom level back to 100% before converting it to pdf. It's important to reset the scale in html2canvas option after that, otherwise it'll returns a blank page.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js"
integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/"
crossorigin="anonymous"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<!-- html2canvas 1.0.0-alpha.11 or higher version is needed -->
<script>
function download() {
// Bring the page zoom level back to 100%
const scale = window.innerWidth / window.outerWidth;
if (scale != 1) {
document.body.style.zoom = scale;
}
let pdf = new jsPDF('p', 'pt', 'a4');
pdf.html(document.getElementById('idName'), {
html2canvas: {
scale: 1 // default is window.devicePixelRatio
},
callback: function () {
// pdf.save('test.pdf');
window.open(pdf.output('bloburl')); // to debug
}
});
}
</script>
Update: A better way is to adjust the html2canvas.scale according to the scale factor.
function download() {
let pWidth = pdf.internal.pageSize.width; // 595.28 is the width of a4
let srcWidth = document.getElementById('idName').scrollWidth;
let margin = 18; // narrow margin - 1.27 cm (36);
let scale = (pWidth - margin * 2) / srcWidth;
let pdf = new jsPDF('p', 'pt', 'a4');
pdf.html(document.getElementById('idName'), {
x: margin,
y: margin,
html2canvas: {
scale: scale,
},
callback: function () {
window.open(pdf.output('bloburl'));
}
});
}
I was going through the same problem,
To do this what I did is I made a copy of printing div and while clicking print button I attached div copy to my dom with margin-top:500px
After I got its image then I hide this copy of the div, and set margin-top:0px
I hope this will work for you.

Categories

Resources