Skip to main content

2D pattern and dash materials

Shared material configuration, observed behavior, and bounded support

Frozen source and the matching development SDK have passed local public acceptance. Production HTTP/application Git are the final delivery steps; formal publication and external platforms remain pending.

Check commonMaterialCrossfades for support. The complete HTML includes CSS, initialization, and every button handler. The public script is an acceptance script with actual-frame gates.

fill-pattern, line-pattern, and line-dasharray use MapLibre-style property names. SqsMap independently implements its map core without MapLibre engine code. The external reference is an isolated public fixture using official MapLibre GL JS 6.14.0; other versions and untested combinations are not promised.

A manual pattern change displays the target image immediately, even with pattern duration and delay controls. A manual dash-array change switches discretely after delay + duration; duration: 0 still preserves the delay. These behaviors differ from continuous numeric, color, and vector paint transitions.

Integer zoom materials have separate history driven by the real map clock. In the observed fixture, zooming from 3.8 to 4.2 selects the target pattern directly, while 4.2 to 3.8 produces a linear material mix. Dash coverage has intermediate values in both directions. The implementation does not store arbitrary snapshots of past frames or promise symmetric behavior. Translucent materials are mixed in premultiplied form, then layer opacity is applied once. Existing target color conversions are preserved: raw RGB readback can differ between Native and browser targets and between fill and line paths. Acceptance predicts each actual color contract and retains raw RGBA and SHA values, without claiming identical bytes across hosts. The color contract is confirmed by frozen source.

materialFadeDuration is an explicit SqsMap shared extension with a 300 ms default. Set it through the map creation option or map.sqs.getMaterialFadeDuration() / map.sqs.setMaterialFadeDuration(ms). It configures the integer zoom material window, not manual pattern or dash timing. Values must be finite, nonnegative, and at most 3600000 ms. Invalid input or resource-limit failure preserves the previous configuration. This extension does not claim the standard label collision fadeDuration behavior, which remains incomplete.

getPaintProperty and getStyle return target declarations; sampled intermediate display never overwrites them. Each feature retains one geometry and at most two material descriptors, without duplicating feature identity or query results. Compatible style diffs preserve source, layer, and resource identities. Failed candidates preserve the prior frame and resource queue.

The initial scope is existing legal 2D Mercator combinations with zero pitch/roll, RGBA patterns, and dashes. SDF, missing-image, resource-candidate limits, and joint budgets are defined by the frozen contract below; actual host evidence appears below. This batch does not complete mobile GIS, iOS, complex 3D, the full style specification, or formal publication.

The complete HTML contains CSS, initialization, and button handlers and can be served beside the matching SDK dist/. Public acceptance uses one script with real frames across Native, main-thread, and Worker hosts at DPR1/2. Unexecuted drafts are not passing evidence.

Scripts and browser maps use the same setter and getter:

map.sqs.setMaterialFadeDuration(1200);
const milliseconds = await map.sqs.getMaterialFadeDuration();

DLL / SO clients send the following UTF-8 JSON through the existing shared sqsm_map_source_json channel. The getter returns a JSON number. Returned sqsm_map_bytes_t ownership is unchanged: callers release it with sqsm_map_bytes_free(out.allocation). There is no private clock or configuration semantics separate from the script API.

{"method":"sqs.setMaterialFadeDuration","args":[1200]}
{"method":"sqs.getMaterialFadeDuration","args":[]}

Source is frozen at core 44e909fd (local implementation, not a formal release). Shared configuration survives full style replacement and clearing. Same-value writes do not alter the clock; duration changes retain the original start time. Adjacent upward crossing selects the current integer material with period scales 2→1 and target weight frac + (1-frac) * progress. Adjacent downward crossing uses the previous higher material and the current material, scales 0.5→1, and target weight (1-frac) + frac * progress. Progress follows real linear time over the configured window. Larger jumps use the current single material; hidden material layers do not start a zoom window.

Only actually contributing image sides are resolved; no future unselected zoom branch is requested. A missing side contributes transparency while a ready side can remain visible. Both sides missing hide the feature. Image updates, removal, and re-registration use complete instance/revision candidates. Existing single-material SDF behavior remains; actual two-sided SDF fill-pattern contribution is rejected. Existing gap/blur/topology/pattern/animation restrictions remain.

Material state shares the existing paint history limits: 128 layers, 2048 slots, 16 MiB for current plus candidate state, with no separate unbounded pool. Accumulated normalized-expression work is limited to 2 million nodes; expression depth 32 / nodes 1024 / steps 8192 and 100000 displayed feature selections remain bounded, with at most two contributions per record. Fill descriptors and auxiliary geometry use descriptor_count * 4 * sizeof(PatternVertices) + unique_pairs * (80 + 256) within the existing 128 MiB layer cache and 64 MiB local auxiliary limit. Static patterns count vertices, unique padded texture pages, unique material pairs (80 uniform bytes + 256 binding reserve), and 64-byte sampler/record costs. Joint line/pattern/gradient/animation limits remain 32 layers, 4096 paths/records, 100000 vertices, 10 million CSS distance, and 256 MiB. GPU accounting additionally includes replaced old allocations and the complete candidate upload peak. Each nonzero dual-dash segment uses 184 instance bytes and 6 vertices. The existing 24 CSS width and 100 CSS width-adjusted pre-scale cycle limits remain; temporary 2/0.5/1 period scales do not alter line width. Existing image, atlas, source, and request limits remain.

Rejected ordinary candidates preserve configuration, identities, queues, caches, and the previous frame. A future sampling failure on an accepted timeline retains the last drawable material, freezes history, stops motion, and reports failed lifecycle state; the accepted target declaration remains. Frozen-source checks passed one CPU case and one serial real GPU case (Vulkan llvmpipe software adapter, SQS_REQUIRE_GPU=1), plus WASM, APP, contract WASM, TS/JS, formatting, and dependency boundaries. Public scripts across six host variants, independent complete HTML, and the matched SDK have passed. Production HTTP/application Git remain the final delivery step.

Core 44e909fd68467d3f0badf64196bb565e90b2a61b, development SDK 0.3.0-dev.44e909fd. Shared 2D pattern/dash materials and explicit materialFadeDuration are implemented locally. One comprehensive CPU and one serial real GPU case passed (final 0.36s, Vulkan llvmpipe software adapter, REQUIRE_GPU=1). The same 23-check/11-phase script passed Native, main-thread, and Worker at DPR1/2 with real clocks, totaling 1123 frames. Separate complete HTML acceptance used four real buttons, five trajectories, and an original ID72 click (39 frames). Raw RGBA/SHA evidence is retained; each preserved target color contract is predicted independently. This is not a byte-identical cross-host claim or an all-style GPU matrix.

Archive SqsMap-SDK-0.3.0-dev.44e909fd-resumed.tar.gz: 612 inventory files plus bundle.json, 37776333 bytes, SHA256 ecdca698445d0736059d11aaf317bd6300086e66fbbd8a9c2c1566a31cfdd225. The tar was independently reopened to verify every size/SHA, including the current script/full HTML and all historical resources. Native, core/application/script WASM and Android API24 ARM64/JNI match this core. The changed script contract has rebuilt WASM. Production HTTP/application Git delivery is verified in the final step; external platforms/devices, mobile GIS/iOS, formal publication, and deployment remain pending.