CreateJS/Canvas text position changed after chrome version upgrade from 70 to 71 - google-chrome

Createjs text position changed after chrome version upgrade from 70 to 71. please guide me.

I didn't like the current proposed solutions (changing the lineHeight or the line count) because they're not very reliable with different fonts, styles and sizes ... so I rolled my own solution:
var cache = {}
createjs.Text.prototype._drawTextLine = function (ctx, text, y) {
this.textBaseline = ctx.textBaseline = "alphabetic";
if (!(this.font in cache)) {
var metrics = this.getMetrics();
cache[this.font] = metrics.vOffset;
}
var offset = cache[this.font];
if (this.outline) {
ctx.strokeText(text, 0, y - offset, this.maxWidth || 0xFFFF);
} else {
ctx.fillText(text, 0, y - offset, this.maxWidth || 0xFFFF);
}
};
The alphabetic value of textBaseline is the most reliable crossbrowser and generally the standard nowadays.
When it's set to both the Text instance and the CanvasRenderingContext2D, we can call getMetrics and have vOffset of the font from the top of it's bounding box to its baseline.
Apply that offset to the fillText call and you generally get a decent rendering of the font. The cache is there for good measure to avoid re-measuring the metrics of the same fonts on every frame.
From the (limited amount of) tests I ran so far, it seems to be:
pretty stable crossbrowser
performance conscious
very close to the expected font rendering (as seen in Animate) showing just some minor offsets at high font sizes
And yet, some fonts still sucks (ie. Poppins) but I suspect it's a "fault" of the font itself in this case.
Hopefully #lanny will have an official fix in createjs soon, but there's no guarantee when that will be included in Animate sadly.

This is an intentional change in Chrome to bring it inline with the "correct" behaviour (which Firefox has had all along). Here is more information. It looks like that Chrome 71 (and later releases) finally addresses that bug.
The only affected alignment is "top", which is the default. Here is a quick comparison between the two Chrome versions.
We are considering a built-in solution in EaselJS since this is more impactful then when it was just Firefox that was the outlier.

The issue can be solved similarly by overriding "_drawTextLine" in the same Text.js class as described here: https://forums.adobe.com/message/10845543#10845543.
The actual problem with this issue is that different fonts classic, google or adobe (former typekit) behave differently. I am looking for a solution that would normalize font alignment regardless its type or nature.
See an example below. Browser Chrome version 71
Without fix it is
With _drawTextLine fix

Just patched it (only tested with my team and with the Open Sans font) by a simple check on the current user agent and forcing the count property to 0.2 (just tested it with the logic of 1.2 * lineHeight in mind, and it works) instead of 0. Basicaly it will just push down the text by 20% of the lineHeight property.
Be careful, it's not an offical patch, it works for me but it's not battle tested.
Add this code at the begining of the file src/easeljs/display/Text.js (thanks to is.js for the browser detection code):
var userAgent = (navigator && navigator.userAgent || "").toLowerCase();
var vendor = (navigator && navigator.vendor || "").toLowerCase();
var isChrome = /google inc/.test(vendor) ? userAgent.match(/(?:chrome|crios)\/(\d+)/) : null;
And at the line 348, replace the next line:
var maxW = 0, count = 0;
By this one:
var maxW = 0, count = isChrome ? 0.2 : 0;
Of course i'm opened to suggestions and improvments ! :)
Thanks!

Related

input type number not showing arrows button in internet explorer [duplicate]

Although I'm pretty sure this was working yesterday or the day before, <input type="number" min="0" max="50" step="10" value="0" />, for example, no longer works in IE10. I've tested my browser with http://ie.microsoft.com/testdrive/HTML5/Forms/Default.html and it's just not working anymore. Anyone else having this issue? Or, did it never work?
Internet Explorer 10 supports the number input. This is evident from a cursory examination of their documentation, as well as an attempt to use it within the browser itself. For example, attempting to place a letter in a number input will result in the value being cleared when the control loses focus.
You can also feature-detect support for number by programmatically doing the aforementioned test:
// Create the element
var element = document.createElement( "input" );
// Give it the number property and invalid contents
element.type = "number";
element.value = "qwerty";
// Value should be empty
alert( element.value ? "Not Supported" : "Supported" );
Run this test: http://jsfiddle.net/VAZwT/
It may very well be that you're equating progressively-enhanced UI (the spinners) with support for the control itself. I've seen this confuse a few people already. Some browsers augment supplement the number input with additional controls, but this is not (to my knowledge) a requirement for support.
A few simple tests for min, max, and step on jsfiddle: http://jsfiddle.net/sDVK4/show/
Please prefer the answer below from Sampson as it's more appropriate
IE doesn't have support for input type="number" but you can use a polyfill to make it work.
Here is the solution : http://html5please.com/#number
IE10 does not have Number support. Source: Can I use ... yet?
Just verified on our Windows 8 test machine, there is no number spinner on their test drive site in IE10.
Microsoft has validation bugs/errors still with input type=number, this is in IE11 as well.
https://connect.microsoft.com/IE/feedback/details/850187/html5-constraint-validation-is-broken-in-ie11-for-input-type-number
Just as I was starting to like Internet Explorer again... Hopefully they can fix this in IE12, fingers crossed
Here's the solution I developed, it works pretty well I think, hope it helps someone 😁
function handleKeyPress(e) {
let newValue = e.target.value + e.key;
if (
// It is not a number nor a control key?
isNaN(newValue) &&
e.which != 8 && // backspace
e.which != 17 && // ctrl
newValue[0] != '-' || // minus
// It is not a negative value?
newValue[0] == '-' &&
isNaN(newValue.slice(1)))
e.preventDefault(); // Then don't write it!
}
Insert a number:
<input onKeyPress="handleKeyPress(event)"/>
IE doesn't have support for input type="number" but you can use jQueryUI Spinner widget. It is very simple to use and it has many API's that friendly for developers.
Demo of jQuery-UI Spinner:
https://jqueryui.com/spinner/
API of jQuery-UI Spinner
https://api.jqueryui.com/spinner/#event-change

Strange IE11 form fields bug after selecting from dropdown

I'm experiencing a major bug in IE 11 (latest version 11.0.9600.16521 on Windows 7). When on any form if I open a select dropdown all the other form fields on the page freeze. I can 'unfreeze' them by adjusting the Window size (causing a redraw). This seems to happen on any form what-so-ever.
To reproduce:
Open IE 11.0.9600.16521
Go to http://www.wikipedia.org/
Select any language from the language dropdown
Result:
language dropdown does not appear to get updated on the screen
the search box appears to be frozen - i.e. focus on select box and start typing but no text appears. However if you adjust the window size the form fields are updated and go back to working as normal (until you interact with another select element)
I can't find much in Google for this issue so maybe it's just something specific to my settings. Only thing that sounds somewhat similar to what I'm experiencing is this: http://connect.microsoft.com/IE/feedback/details/806679/ie-11-desktop-selecting-an-item-from-a-drop-down-list-on-a-webpage-causes-the-tab-to-crash. Anyone else able to reproduce this?
I had a similar issue with IE11 that turned out to be any modification to the .text property of an SELECT-option element. I eventually found the "hint" on stackoverflow here
How to fix IE select issue when dynamically changing options.
In my case I use straight JavaScript, and with so many inter-dependent SELECT boxes had to come up with a generic solution, so my solution was to intercept (defineGetter) assignment to any .text property of an HTMLOptionElement, and set a 1 ms timer to perform an add element and remove element as in the referenced post that is titled "I have the fix. We have to add and remove options list to trigger the rendering in IE8." Notice the reference to IE8, AFAIK IE has had several issues with SELECT boxes since at least IE7, possibly earlier.
So the code I added to one of my global scripts is as follows:
try { var IE11; // IE10 and IE11 removed ActiveXObject from the window object but it can still be instantiated
IE11 = new ActiveXObject('MSXML2.DOMDocument.6.0');
IE11 = null;
if (typeof(HTMLOptionElement) != "undefined") {
try { HTMLOptionElement.prototype.__defineSetter__(
'text',
function(original) {
return function(newValue) { var sel;
original.call(this, newValue);
if (!(sel=this.parentElement).fixIE) sel.fixIE = window.setTimeout(_fixIE_(sel), 1);
}
}(HTMLOptionElement.prototype.__lookupSetter__('text')));
} catch(e) {};
}
} catch(e) {}
}
// IE11 broke SELECT boxes again, modifying any options .text attribute "freezes" the SELECT so it appears disabled
function _fixIE_(selBox) {
return _fixIE_;
function _fixIE_(){ var lc = selBox.options.length;
selBox.options.add(new Option('',''));
selBox.options.remove(lc);
selBox.fixIE = undefined;
}
}
Phil
Go to programs
Then widdcom folder
Right click bttray
Go compatibility
Tick run as admin
Restart
I had the same problem in IE 11 on Dell Windows 7.
It was solved by turning off hardware rendering in IE, as you suggested in your link.

DropEffect semantic for HTML5 drag and drop

According to the HTML5 specs the dropEffect property on a drop target allows the drop target to select the desired drop effect. The drag and drop framework should combine this with the effectAllowed property set by the drag source to display the matching visual feedback (typically a specific cursor depending on the operation).
I was however not able to use this feature consistently across browsers. It seems to work for Chrome and Opera as expected but doe not for IE and FF (although the developer documentation for each browsers explicitly documents it).
I have put together a sample on JSFiddle: http://jsfiddle.net/cleue/zT87T/
function onDragStart(element, event) {
var dataTransfer = event.dataTransfer,
effect = element.innerText || element.textContent;
dataTransfer.effectAllowed = effect;
dataTransfer.setData("Text", effect);
dataTransfer.setDragImage(element, 0, 0);
}
function onDragEnter(element, event) {
var dataTransfer = event.dataTransfer,
effect = element.innerText || element.textContent;
dataTransfer.dropEffect = effect;
event.preventDefault();
}
function onDragOver(element, event) {
var dataTransfer = event.dataTransfer,
effect = element.innerText || element.textContent;
dataTransfer.dropEffect = effect;
event.preventDefault();
}
Is this sample incorrect or my understanding of the purpose of this feature or are these browser bugs?
i had exactly the same problem and came to the same conclusion as yourself, it just doesn't work. In addition to changing the mouse cursor there is the job of working out at the source element what took place - from the spec you can listen to dragend and e.g. remove the element if the drop effect was move and leave it if it were copy. That doesn't work consistently either. I asked the question here, i put a longish explanation with all my findings.
btw - i see it says that drag and drop is at risk from being removed due to a lack of implementation which is a pity.

Unable to select <linearGradient> with D3.js in Chrome

Chrome doesn't select <linearGradient> with D3.js. In the following code all selections are empty.
var defs = d3.select("body").append("svg").append("defs");
defs.append("linearGradient");
defs.append("linearGradient");
console.log(defs.selectAll("linearGradient")); // empty
console.log(defs.selectAll("lineargradient")); // empty
console.log(d3.selectAll("linearGradient")); // empty
If you replace <linearGradient> with say <mask> it's all right.
var defs = d3.select("body").append("svg").append("defs");
defs.append("mask");
defs.append("mask");
console.log(defs.selectAll("mask")); // 2 elements selected
Firefox works fine for both. I'm using Chrome 28.0.1500.95. Please suggest a way to select the gradients.
This is a bug in webkit -- see the bug report. The short answer is that for it's just broken. You may be able to work around this by keeping explicit references to the gradients you need to modify, e.g.
var grad1 = defs.append("linearGradient");

SVG line markers not updating when line moves in IE10?

I have some SVG lines with line markers on them, and I have a script that moves those lines around. This works fine on all browsers, including IE9.
However, I just tried it on IE10, and the line markers get left behind when the line moves.
An example of this can be seen here: http://jsfiddle.net/swYRK/8/
I have tried this on both Windows 7 and 8.
Anyone know what's going on? Is this an IE10 bug, or is there another way to move the line and markers?
(Note the actual application is very performance sensitive, so I very much want to avoid doing something like re-creating the lines every frame while I move them, or something.)
-
Edit: this seems like a real IE 10 bug. I've found one open issue in the IE bug tracker (which requires a Microsoft account to even see, which makes it not visible to Google. Hello?), which I have added information to. IE has yet to accept the issue.
If there are any other work-arounds that people can think of, that would be great to hear. Completely removing the end markers, rendering that, and then re-adding them works-ish (shows visible flashing), but would not be acceptable in my application, unfortunately.
This is a quick way of doing it, that works well.
I have not noticed any flickering or performance related issues.
Simply re-add the svg node in it's original place:
if (navigator.appVersion.indexOf("MSIE 10") != -1) {
svgNode.parentNode.insertBefore(svgNode, svgNode);
}
Of course, you could use any browser sniffing of choice..
I want to elaborate a little on the amazing answer given by #ChristianLund and how I used it successfully in my code
In my force animation, I have a tick function that looks like this:
force.on("tick", function() {
...
});
I also hold all of my graph links inside the link variable, defined like so:
var link = svg.selectAll(".link").data(links).enter() ...
Now, to implement the magic suggested by Christian, I've added this line in the beginning of my tick function:
force.on("tick", function() {
link.each(function() {this.parentNode.insertBefore(this, this); });
...
});
This seems to fix the IE 10 problems... of course it's recommended to add this patch only on IE 10
In ie10/11, I found that the line does not move when it with marker-start/marker-end atrribute, I tried to remove those atrributes in your example, and it works. So the idea is remove the atrributes before set the x/y, then reset the atrributes after all jobs done.
You may try this hack:
$("#button4").click(function () {
$("#line1")[0].setAttributeNS(null, "x1", 50);
$("#line1")[0].setAttributeNS(null, "y1", 50);
$("#line1")[0].setAttributeNS(null, "x2", 150);
$("#line1")[0].setAttributeNS(null, "y2", 50);
var oldAttValueDisplay = $("#line1")[0].getAttributeNS(null, "display");
$("#line1")[0].setAttributeNS(null, "display", "none");
setTimeout(function() {$("#line1")[0].setAttributeNS(null, "display", oldAttValueDisplay);}, 0);
// static: setTimeout(function() {$("#line1")[0].setAttributeNS(null, "display", "block");}, 0);
});