I'm still gathering the pieces needed to understand a web 2 print editor in HTML5. I'm using FabricJS and a bunch of other 3rd party tools to make it a possibility.
My latest roadblock is my Samsung Chromebook Pro, which has a HiDPI/retina display. The window.devicePixelRatio
is different, and I'm trying to figure out how to cope with this higher DPI using FabricJS. I followed what everybody else has been saying is successful, but it doesn't seem to work or help me. Plus my canvas becomes extremely large, and objects are no longer movable.
I'm also using another 3rd party library, PetitoJPEG, which I am using to encode the raw pixel data from the FabricJS canvas. Because of the different devicePixelRatio from my other laptop, running the encoder causes the red dot on the right side of the canvas to not show on the proof image.
I'm wondering how I can encode the entirety of the canvas on a HiDPI display.
Because of all the 3rd party assets, I'm willing to provide a direct link instead of a JSFiddle: http://xbit.x10host.com/editor2.php
I think I understand what the scaling method people are saying is successful does, but I'm wondering if it isn't working properly because of my CSS transform on the canvas container. I've tried adjusting scaling and the canvas widths/heights and CSS width/heights through the console to no avail though.
Any help would be appreciated. I'll paste the snippet that everybody is saying is working below.
Note: My Samsung Chromebook Pro is logging 26562 bytes written, and my Lenovo x230 Windows laptop is logging 27586 bytes.
if( window.devicePixelRatio !== 1 ){
var c = canvas.getElement(); // canvas = fabric.Canvas
var w = c.width, h = c.height;
// Scale the canvas up by two for retina
// just like for an image
c.setAttribute('width', w*window.devicePixelRatio);
c.setAttribute('height', h*window.devicePixelRatio);
// then use css to bring it back to regular size
// or set it here
c.setAttribute('style', 'width="'+w+'"; height="'+h+'";')
// or jQuery $(c).css('width', w);
// $(c).css('width', w);
// $(c).css('height', h);
// finally set the scale of the context
c.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
canvas.renderAll();
}
I know the above chunk of code seems to work for most people, but isn't the following line incorrect?
c.setAttribute('style', 'width="'+w+'"; height="'+h+'";')
That isn't how you define inline styles. You need a ":" instead of "=" and there's no unit of measurement, so I'm wondering how this works.
Here is a screenshot of the new isolation page I've created to more effectively isolate the issue: And here is the direct URL: http://xbit.x10host.com/isolation.php
You can see how using the method everybody else is saying works isn't working. The CSS property values are invalid. Maybe I'm just confused, but even if I set the CSS width and height correctly, am I using the 1125x675 for getImageData or the new 4500x1200? Using the latter causes the proof image to be too large; the 4500x1200 contains all the data I want but then there's all this black space. Below is a screenshot of that result.
Now, the 2250x1350 (output using the goto method with correct inline CSS syntax) seems to be correct, but I thought the canvas fix was supposed to help to output the same as my other laptop. Would this mean people with HiDPI displays will get higher quality proof images (and prints) than people who don't have a HiDPI display? I want the dimensions and pixel count to the be same regardless of device DPI.
I've found out how to make images the same number of pixels regardless of DPI.
It involves using an off-screen canvas and re-drawing the on-screen canvas onto it at the desired width and height, and re-encoding the off-screen canvas at 300dpi so that regardless of screen resolution, the output file will always be the same.