diff --git a/src/graphic/Path.ts b/src/graphic/Path.ts index ac2098f17..1c8f7d603 100644 --- a/src/graphic/Path.ts +++ b/src/graphic/Path.ts @@ -266,8 +266,13 @@ class Path extends Displayable { protected getInsideTextFill() { const pathFill = this.style.fill; if (pathFill !== 'none') { - if (isString(pathFill)) { - const fillLum = lum(pathFill, 0); + if (isString(pathFill) + || (pathFill && 'colorStops' in pathFill && pathFill.colorStops.length)) { + // Match the average-stop luminance used for gradient backgrounds. + const fillLum = isString(pathFill) + ? lum(pathFill, 0) + : pathFill.colorStops.reduce((sum, stop) => sum + lum(stop.color, 0), 0) + / pathFill.colorStops.length; // Determin text color based on the lum of path fill. // TODO use (1 - DARK_MODE_THRESHOLD)? if (fillLum > 0.5) { // TODO Consider background lum? diff --git a/test/ut/spec/graphic/Path.test.ts b/test/ut/spec/graphic/Path.test.ts index 5dfda2e77..f037f11b5 100644 --- a/test/ut/spec/graphic/Path.test.ts +++ b/test/ut/spec/graphic/Path.test.ts @@ -1,4 +1,4 @@ -import {Rect, util} from '../zrender'; +import {Rect, util, LinearGradient, RadialGradient} from '../zrender'; import { PathState } from '../../../../src/graphic/Path'; describe('Path', function () { @@ -310,4 +310,35 @@ describe('Path', function () { // TODO more getBoundingRect test on different shapes. // TODO pathContain test + + describe('inside labels on gradient fills', function () { + class LabelRect extends Rect { + labelFill() { + return this.getInsideTextFill(); + } + } + + [() => new LinearGradient(0, 0, 1, 0), () => new RadialGradient(0.5, 0.5, 0.5)].forEach(function (createGradient) { + ['#eeeeee', '#777777', '#111111'].forEach(function (fill) { + it(createGradient().type + ' uses the same label contrast as an equivalent solid fill ' + fill, function () { + const gradient = createGradient(); + gradient.addColorStop(0, fill); + gradient.addColorStop(1, fill); + const solid = new LabelRect({ style: { fill } }); + const shaded = new LabelRect({ style: { fill: gradient } }); + expect(shaded.labelFill()).toBe(solid.labelFill()); + expect(gradient.colorStops).toEqual([ + { offset: 0, color: fill }, + { offset: 1, color: fill } + ]); + }); + }); + }); + + it('keeps the fallback for empty gradients and patterns', function () { + const gradient = new LabelRect({ style: { fill: new LinearGradient(0, 0, 1, 0) } }); + const pattern = new LabelRect({ style: { fill: { image: 'tile.png' } } }); + expect(gradient.labelFill()).toBe(pattern.labelFill()); + }); + }); }); \ No newline at end of file