@@ -18,6 +18,50 @@ var LINE_SPACING = alignmentConstants.LINE_SPACING;
1818
1919var labelClass = 'heatmap-label' ;
2020
21+ // Pixelated image rendering
22+ // The actual declaration is prepended with fallbacks for older browsers.
23+ // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering
24+ // https://caniuse.com/?search=image-rendering
25+ var pixelatedImageCSS = [
26+ 'image-rendering: optimizeSpeed' ,
27+ 'image-rendering: -moz-crisp-edges' ,
28+ 'image-rendering: -o-crisp-edges' ,
29+ 'image-rendering: -webkit-optimize-contrast' ,
30+ 'image-rendering: optimize-contrast' ,
31+ 'image-rendering: crisp-edges' ,
32+ 'image-rendering: pixelated'
33+ ] ;
34+
35+ var _supportsPixelated = null ;
36+ function supportsPixelatedImage ( ) {
37+ if ( _supportsPixelated !== null ) { // only run the feature detection once
38+ return _supportsPixelated ;
39+ }
40+ if ( Lib . isIE ( ) ) {
41+ // `-ms-interpolation-mode` works only with <img> not with SVG <image>
42+ _supportsPixelated = false ;
43+ } else {
44+ var declarations = Array . from ( pixelatedImageCSS ) . reverse ( ) ;
45+ var supports = window . CSS && window . CSS . supports || window . supportsCSS ;
46+ if ( typeof supports === 'function' ) {
47+ _supportsPixelated = declarations . some ( function ( d ) {
48+ return supports . apply ( null , d . split ( ': ' ) ) ;
49+ } ) ;
50+ } else {
51+ var image3 = Drawing . tester . append ( 'image' ) ;
52+ var cStyles = window . getComputedStyle ( image3 . node ( ) ) ;
53+ image3 . attr ( 'style' , pixelatedImageCSS . join ( '; ' ) + ';' ) ;
54+ _supportsPixelated = declarations . some ( function ( d ) {
55+ var value = d . split ( ': ' ) [ 1 ] ;
56+ return cStyles . imageRendering === value ||
57+ cStyles . imageRendering === value . toLowerCase ( ) ;
58+ } ) ;
59+ image3 . remove ( ) ;
60+ }
61+ }
62+ return _supportsPixelated ;
63+ }
64+
2165function selectLabels ( plotGroup ) {
2266 return plotGroup . selectAll ( 'g.' + labelClass ) ;
2367}
@@ -112,7 +156,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
112156 var drawingMethod = 'default' ;
113157 if ( zsmooth ) {
114158 drawingMethod = zsmooth === 'best' ? 'smooth' : 'fast' ;
115- } else if ( trace . _islinear && xGap === 0 && yGap === 0 ) {
159+ } else if ( trace . _islinear && xGap === 0 && yGap === 0 && supportsPixelatedImage ( ) ) {
116160 drawingMethod = 'fast' ;
117161 }
118162
@@ -358,10 +402,13 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
358402 width : imageWidth ,
359403 x : left ,
360404 y : top ,
361- 'image-rendering' : drawingMethod === 'fast' && ! zsmooth ? 'pixelated' : 'auto' ,
362405 'xlink:href' : canvas . toDataURL ( 'image/png' )
363406 } ) ;
364407
408+ if ( drawingMethod === 'fast' && ! zsmooth ) {
409+ image3 . attr ( 'style' , pixelatedImageCSS . join ( '; ' ) + ';' ) ;
410+ }
411+
365412 removeLabels ( plotGroup ) ;
366413
367414 var texttemplate = trace . texttemplate ;
0 commit comments