Skip to content

Joker/Faker stroke color is always Hostile (red) when a custom frameColor object is provided #350

Description

@JohnPHowe

Summary

When a custom frameColor object is passed to Symbol() (e.g. for no-fill rendering), Joker and Faker symbols always stroke in the Hostile (red) color instead of the expected orange/joker color. The root cause is that getcolors.js applies baseFrameColor.Friend = baseFrameColor.Hostile on the raw frameColor object without going through any color-mode redirect.

Affected file

src/ms/symbol/getcolors.js lines 31–34

What happens

The joker/faker branch does:

if (this.metadata.joker || this.metadata.faker) {
baseFillColor.Friend = baseFillColor.Hostile;
baseFrameColor.Friend = baseFrameColor.Hostile; // ← uses raw Hostile
baseIconColor.Friend = baseIconColor.Hostile;
}

When style.colorMode is an object (e.g. a custom color-mode table that remaps Hostile → orange), baseFillColor.Hostile resolves to orange and the fill is correct. But baseFrameColor is resolved independently from style.frameColor, which is a separate object that still holds the raw Hostile (red) value. The fill and stroke therefore disagree.

Reproduction

import ms from 'milsymbol';

const orangeMode = { ...ms.getColorMode('Light'), Hostile: '#FF6600' };
const frameColor = { ...ms.getColorMode('FrameColor') }; // Hostile = red

// Joker SIDC (standard identity digit = 4 → 'J')
const sidc = '10034000001101000000';

new ms.Symbol(sidc, {
fill: false,
colorMode: orangeMode, // fill uses Hostile → orange ✓
frameColor, // stroke uses Hostile → red ✗
}).asSVG();

The symbol's stroke is red even though the color mode specifies orange for joker/hostile affiliations.

Fix

In the joker/faker branch, resolve the stroke color through the same color-mode mapping used for the fill, rather than reading baseFrameColor.Hostile directly:

if (this.metadata.joker || this.metadata.faker) {
baseFillColor.Friend = baseFillColor.Hostile;
baseFrameColor.Friend = baseFrameColor.Hostile;
baseIconColor.Friend = baseIconColor.Hostile;
}

One approach is to apply the joker mapping after resolving the effective Hostile color from the active color mode, so both frameColor and colorMode branches use a consistent value. Alternatively, accept a jokerColor style property (analogous to the modifierColor proposal in #PR) so callers can explicitly override it.

Related

This bug is compounded by the in-place mutation issue described in [issue #351 ] — the frameColor object is mutated as a side-effect, which can corrupt shared objects across renders.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions