Difference in Behavior Between Firefox and Chrome for HTML Canvas fillRect operation and fontBoundingBoxAscent - firefox

I am working on a bug in a library for Leaflet and I cannot figure out how to work around a difference in how Firefox and Chrome implement HTML Canvas. It revolves around the ctx.fillRect function -- it does not appear to be working in Firefox. On Chrome, the application works properly and the labels are properly coloured:
Chrome
However with Firefox it appears as such:
Firefox
The code in my library which draws the labels is:
drawLabel(labelText, textColor, backgroundColor, labelPosition) {
const textWidth = this.ctx.measureText(labelText).width;
const textHeight = this.ctx.measureText(labelText).fontBoundingBoxAscent;
// Calculate label xy position
const labelX = labelPosition.x;
const labelY = labelPosition.y;
this.ctx.fillStyle = backgroundColor;
// Magic numbers will centre the rectangle over the text
this.ctx.fillRect(labelX - textWidth / 2 - 1, labelY - textHeight + 1, textWidth + 3, textHeight + 2);
this.ctx.fillStyle = textColor;
this.ctx.fillText(labelText, labelX - textWidth / 2, labelY);
}
I've tried to leverage ctx.rect and ctx.fill as a substitute but that does not work. Logging the ctx object did show that Chrome and Firefox implement Canvas context a little differently, but the fields that I am modifying do not appear to be different.

The problem is that fontBoundingBoxAscent is not enabled in Firefox by default and requires the user to turn it on in about:config under dom.textMetrics.fontBoundingBox.enabled.

Related

KonvaJs - Shape.FillPatternImage not scalled on firefox

I have a shape rendered in with Konva, when set a fillPatternImage, this one is well rendered with Chrome and stretched with firefox.
Good rendering in Chrome
False rendering in Firefox*
The image file is a *.png.
Have somebody any reason why ?
MORE INFORMATIONS :
In the following code element is Konva.Rect() object, I set an image for filling in center of the element :
const imageObj = new Image();
const filename = zone.visual;
imageObj.onload = function() {
element.fillPatternImage(imageObj);
element.fillPatternRepeat('no-repeat');
element.fillPatternOffsetX((imageObj.width - zone.sizeX) / 2);
element.fillPatternOffsetY((imageObj.height - zone.sizeY) / 2);
element.draw();
};
imageObj.src = this.utils.getImgUrl(filename, 'configurator_zone');
I found a solution this afternoon.
In order to reproduce the problem, the edge of the image must be in contact with the cross. By reducing the size of the cross compared to the size of the image, the problem disappears.
Problematic cross : cross reproducing error
Correct cross : correct cross

d3.brush does not work in Firefox or Edge when embedded

I'm using the Swiper API. When there's any d3 Chart embedded, the brush receives senseless mouse coordinates, in any case not relative to the container where the click occurs. (That's in fact at least the surrounded svg.)
I'm trying to find a solution but I don't know how I can force d3.brushX to use mouse coordinates which are really relative.
I don't know whether this is a bug or not, it has probably not really to do with the brush itself, rather how the browser pass mouse clicks top-down the DIV's until the SVG will be reached.
Here's the Fiddle.
(just for the annoying code rule:)
// Add brushing
var brush = d3.brushX()
The second slide contains an embedded d3 line chart example, taken from here.
The fiddle works only in Chrome 75+.
Not in Firefox 68+ nor in Edge 44+.
Running the chart example standalone, it works in all available browsers. So I designate this post for Swiper and D3 hopefully to get a hint for an solution.
According to the problem here I found out, that I can change the behavior in the point.js routines an an workaround.
If a D3 chart makes use of an brush **and ** the SVG of the chart element is embedded by a surrounding DIV with an explicite width, mouse clicks will not be interpreted correctly in Firefox or Edge. In Chrome it works perfectly.
I changed the code like this to achieve that it works in FF and Edge, but lose functionality with Chrome:
function reverseTraversal(node,targetTagName) {
var p = node;
while(p.tagName != targetTagName) p = p.parentNode;
return p;
}
function point(node, event) {
var svg = node.ownerSVGElement || node;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
var p = reverseTraversal(node,"DIV");
var rect = p.getBoundingClientRect();
point.x = event.clientX + rect.width, point.y = event.clientY;
point = point.matrixTransform(node.getScreenCTM().inverse());
return [point.x, point.y];
}
var rect = node.getBoundingClientRect();
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
}
As you can see, I have to traverse backwards until the closest DIV will be reached, get the bounding and add its width to the clientX coordinate.
Without adding the fixed width, the brush is unusable in the particular case.
To get working with all the browsers, maybe a switch is necessary.
It's not a perfect solution, just a workaround for d3.brushX behavior.

Cocos2d-x label font color unable to set

rect = Sprite::create();
rect->setTextureRect(Rect(0, 0, 180, 80));
rect->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height + 80));
auto grad = LayerGradient::create(arr[randSayi][0], arr[randSayi][1]);
grad->changeHeight(rect->getContentSize().height);
grad->changeWidth(rect->getContentSize().width);
label = Label::createWithTTF(arrRenk[randRenk], "fonts/font.ttf", 54);
label->setPosition(rect->getContentSize().width / 2, rect->getContentSize().height / 2);
label->setColor(/*(Color3B)arr[randSayi][0]*/Color3B(arr[randSayi][0]));
grad->addChild(label);
rect->setTag(i);
rect->addChild(grad);
This is how i crete a rectangular sprite with a gradient color and a label added on top of it. My problem is that i can't set font color properly.
label->setColor(/*(Color3B)arr[randSayi][0]*/Color3B(arr[randSayi][0]));
arr[][] is an array of colors Color4B. I both tried casting and the uncommented out but the result is:
Which means color isn't set. Can anybody identify the problem?
i tried in my code, both setColor and setTextColor work for me
my cocos2dx engine version is v3.2
you may take a try with setTextColor

firefox svg transform not working

I am trying to use transform - translateX on the mask in in svg to animate it. But it doesnt work in firefox, however it works in chrome.
The javascript used to add styling
var a = document.getElementById("masker");
a.style.cssText += "-webkit-transform: translate(954px);"
a.style.cssText += "transform: translate(954px);"
Working fiddle for chrome http://jsfiddle.net/557UK/3/

Draw Element's Contents onto a Canvas Element / Capture Website as image using (?) language

I asked a question on SO about compiling an image file from HTML. Michaƫl Witrant responded and told me about the canvas element and html5.
I'm looked on the net and SO, but i haven't found anything regarding drawing a misc element's contents onto a canvas. Is this possible?
For example, say i have a div with a background image. Is there a way to get this element and it's background image 'onto' the canvas? I ask because i found a script that allows one to save the canvas element as a PNG, but what i really want to do is save a collection of DOM elements as an image.
EDIT
It doesn't matter what language, if it could work, i'm willing to attempt it.
For the record, drawWindow only works in Firefox.
This code will only work locally and not on the internet, using drawWindow with an external element creates a security exception.
You'll have to provide us with a lot more context before we can answer anything else.
http://cutycapt.sourceforge.net/
CutyCapt is a command line utility that uses Webkit to render HTML into PNG, PDF, SVG, etc. You would need to interface with it somehow (such as a shell_exec in PHP), but it is pretty robust. Sites render exactly as they do in Webkit browsers.
I've not used CutyCapt specifically, but it came to me highly recommended. And I have used a similar product called WkHtmlToPdf, which has been awesome in my personal experience.
After many attempts using drawWindow parameters, that were drawing wrong parts or the element, I managed to do it with a two steps processing : first capture the whole page in a canvas, then draw a part of this canvas in another one.
This was done in a XUL extension. drawWindow will not work in other browsers, and may not work in a non-privileged context due to security reasons.
function nodeScreenshot(aSaveLocation, aFileName, aDocument, aCSSSelector) {
var doc = aDocument;
var win = doc.defaultView;
var body = doc.body;
var html = doc.documentElement;
var selection = aCSSSelector
? Array.prototype.slice.call(doc.querySelectorAll(aCSSSelector))
: [];
var coords = {
top: 0,
left: 0,
width: Math.max(body.scrollWidth, body.offsetWidth,
html.clientWidth, html.scrollWidth, html.offsetWidth),
height: Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight)
var canvas = document.createElement("canvas");
canvas.width = coords.width;
canvas.height = coords.height;
var context = canvas.getContext("2d");
// Draw the whole page
// coords.top and left are 0 here, I tried to pass the result of
// getBoundingClientRect() here but drawWindow was drawing another part,
// maybe because of a margin/padding/position ? Didn't solve it.
context.drawWindow(win, coords.top, coords.left,
coords.width, coords.height, 'rgb(255,255,255)');
if (selection.length) {
var nodeCoords = selection[0].getBoundingClientRect();
var tempCanvas = document.createElement("canvas");
var tempContext = tempCanvas.getContext("2d");
tempCanvas.width = nodeCoords.width;
tempCanvas.height = nodeCoords.height;
// Draw the node part from the whole page canvas into another canvas
// void ctx.drawImage(image, sx, sy, sLargeur, sHauteur,
dx, dy, dLargeur, dHauteur)
tempContext.drawImage(canvas,
nodeCoords.left, nodeCoords.top, nodeCoords.width, nodeCoords.height,
0, 0, nodeCoords.width, nodeCoords.height);
canvas = tempCanvas;
context = tempContext;
}
var dataURL = canvas.toDataURL('image/jpeg', 0.95);
return dataURL;
}

Resources