diff --git a/build/plotcss.js b/build/plotcss.js index f07b126de8c..f6e9e453cdd 100644 --- a/build/plotcss.js +++ b/build/plotcss.js @@ -32,6 +32,7 @@ var rules = { "X .cursor-ne-resize": "cursor:ne-resize;", "X .cursor-grab": "cursor:-webkit-grab;cursor:grab;", "X .modebar": "position:absolute;top:2px;right:2px;z-index:1001;", + "X .ease-bg": "-webkit-transition:background-color 0.3s ease 0s;-moz-transition:background-color 0.3s ease 0s;-ms-transition:background-color 0.3s ease 0s;-o-transition:background-color 0.3s ease 0s;transition:background-color 0.3s ease 0s;", "X .modebar--hover>:not(.watermark)": "opacity:0;-webkit-transition:opacity 0.3s ease 0s;-moz-transition:opacity 0.3s ease 0s;-ms-transition:opacity 0.3s ease 0s;-o-transition:opacity 0.3s ease 0s;transition:opacity 0.3s ease 0s;", "X:hover .modebar--hover .modebar-group": "opacity:1;", "X .modebar-group": "float:left;display:inline-block;box-sizing:border-box;margin-left:8px;position:relative;vertical-align:middle;white-space:nowrap;", diff --git a/src/components/modebar/modebar.js b/src/components/modebar/modebar.js index 39154ca24e9..b351a2946aa 100644 --- a/src/components/modebar/modebar.js +++ b/src/components/modebar/modebar.js @@ -52,21 +52,22 @@ proto.update = function(graphInfo, buttons) { this.element.setAttribute('id', modeBarId); this._uid = modeBarId; - if(context.displayModeBar === 'hover') { - this.element.className = 'modebar modebar--hover'; - } - else this.element.className = 'modebar'; + this.element.className = 'modebar'; + if(context.displayModeBar === 'hover') this.element.className += ' modebar--hover ease-bg'; if(fullLayout.modebar.orientation === 'v') { this.element.className += ' vertical'; buttons = buttons.reverse(); } + var style = fullLayout.modebar; + var bgSelector = context.displayModeBar === 'hover' ? '.js-plotly-plot .plotly:hover ' : ''; + Lib.deleteRelatedStyleRule(modeBarId); - Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId, 'background-color: ' + fullLayout.modebar.bgcolor); - Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn .icon path', 'fill: ' + fullLayout.modebar.color); - Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn:hover .icon path', 'fill: ' + fullLayout.modebar.activecolor); - Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn.active .icon path', 'fill: ' + fullLayout.modebar.activecolor); + Lib.addRelatedStyleRule(modeBarId, bgSelector + '#' + modeBarId, 'background-color: ' + style.bgcolor); + Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn .icon path', 'fill: ' + style.color); + Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn:hover .icon path', 'fill: ' + style.activecolor); + Lib.addRelatedStyleRule(modeBarId, '#' + modeBarId + ' .modebar-btn.active .icon path', 'fill: ' + style.activecolor); // if buttons or logo have changed, redraw modebar interior var needsNewButtons = !this.hasButtons(buttons); @@ -135,7 +136,6 @@ proto.updateButtons = function(buttons) { proto.createGroup = function() { var group = document.createElement('div'); group.className = 'modebar-group'; - return group; }; diff --git a/src/css/_modebar.scss b/src/css/_modebar.scss index d2aaf1fa51c..f648113e6ed 100644 --- a/src/css/_modebar.scss +++ b/src/css/_modebar.scss @@ -5,6 +5,10 @@ z-index: 1001; } +.ease-bg { + @include vendor('transition', background-color 0.3s ease 0s); +} + .modebar--hover > :not(.watermark) { opacity: 0; @include vendor('transition', opacity 0.3s ease 0s); diff --git a/test/jasmine/tests/modebar_test.js b/test/jasmine/tests/modebar_test.js index 33f25db999f..6a16e2c3236 100644 --- a/test/jasmine/tests/modebar_test.js +++ b/test/jasmine/tests/modebar_test.js @@ -1290,6 +1290,16 @@ describe('ModeBar', function() { expect(style.fill).toBe(color); } + function getStyleRule() { + var uid = gd._fullLayout._uid; + var ownerNode = document.getElementById('plotly.js-style-modebar-' + uid); + var styleSheets = document.styleSheets; + for(var i = 0; i < styleSheets.length; i++) { + var ss = styleSheets[i]; + if(ss.ownerNode === ownerNode) return ss; + } + } + it('create an associated style element and destroy it on purge', function(done) { var styleSelector, style; Plotly.plot(gd, [], {}) @@ -1313,7 +1323,7 @@ describe('ModeBar', function() { button = selectButton(gd._fullLayout._modeBar, targetBtn); checkButtonColor(button, colors[0]); }) - .then(function() {Plotly.relayout(gd, 'modebar.color', colors[1]);}) + .then(function() { return Plotly.relayout(gd, 'modebar.color', colors[1]); }) .then(function() { checkButtonColor(button, colors[1]); }) @@ -1336,16 +1346,35 @@ describe('ModeBar', function() { .then(done); }); - it('changes background color', function(done) { + it('changes background color (displayModeBar: hover)', function(done) { Plotly.plot(gd, [], {modebar: { bgcolor: colors[0]}}) + .then(function() { + style = window.getComputedStyle(gd._fullLayout._modeBar.element); + expect(style.backgroundColor).toBe('rgba(0, 0, 0, 0)'); + expect(getStyleRule().rules[3].style.backgroundColor).toBe(colors[0]); + }) + .then(function() { return Plotly.relayout(gd, 'modebar.bgcolor', colors[1]); }) + .then(function() { + style = window.getComputedStyle(gd._fullLayout._modeBar.element); + expect(style.backgroundColor).toBe('rgba(0, 0, 0, 0)'); + expect(getStyleRule().rules[3].style.backgroundColor).toBe(colors[1]); + }) + .catch(failTest) + .then(done); + }); + + it('changes background color (displayModeBar: true)', function(done) { + Plotly.plot(gd, [], {modebar: {bgcolor: colors[0]}}, {displayModeBar: true}) .then(function() { style = window.getComputedStyle(gd._fullLayout._modeBar.element); expect(style.backgroundColor).toBe(colors[0]); + expect(getStyleRule().rules[3].style.backgroundColor).toBe(colors[0]); }) - .then(function() {Plotly.relayout(gd, 'modebar.bgcolor', colors[1]);}) + .then(function() { return Plotly.relayout(gd, 'modebar.bgcolor', colors[1]); }) .then(function() { style = window.getComputedStyle(gd._fullLayout._modeBar.element); expect(style.backgroundColor).toBe(colors[1]); + expect(getStyleRule().rules[3].style.backgroundColor).toBe(colors[1]); }) .catch(failTest) .then(done); @@ -1360,7 +1389,7 @@ describe('ModeBar', function() { size = modeBarEl.getBoundingClientRect(); expect(size.width < size.height).toBeTruthy(); }) - .then(function() {Plotly.relayout(gd, 'modebar.orientation', 'h');}) + .then(function() { return Plotly.relayout(gd, 'modebar.orientation', 'h'); }) .catch(failTest) .then(function() { size = modeBarEl.getBoundingClientRect();