Planar solid line translation
When the matching SDK provides commonLineGradients, its noncluster GeoJSON lineMetrics:true gradient channel supports the stable caps/joins, filtering/sorting and offset/translate described here. Historical solid/animation gradient rejection limits do not reject these combinations in the new gradient channel. Check matching capability and the gradient guide; other unsupported combinations still reject.
The shared planar solid-line paint property line-translate defaults to [0,0] and requires two finite CSS-pixel numbers. Positive x points right and positive y points down. line-translate-anchor accepts map or viewport, defaulting to map. Capability: commonLineTranslateSolid.
A map anchor rotates with the map: at bearing 90°, [0,12] moves 12 screen pixels right. A viewport anchor retains screen directions, so the same vector moves 12 pixels down. Translation moves the complete offset line, caps, joins, polygon rings and holes without changing source coordinates or identities. DPR is applied once when drawing physical pixels.
import { map } from 'sqsmap';
map.setStyle(null);
await map.sqs.flush();
map.setProjection({type:'mercator'});
map.jumpTo({center:[116.4,39.9], zoom:13, pitch:0, bearing:30});
await map.sqs.flush();
map.addSource('route', {type:'geojson', data:{type:'Feature', id:1, properties:{},
geometry:{type:'LineString',coordinates:[[116.38,39.9],[116.42,39.9]]}}});
map.addLayer({id:'route', type:'line', source:'route', paint:{
'line-color':'#1677ff', 'line-width':6,
'line-translate':[0,12], 'line-translate-anchor':'viewport'
}});
await map.sqs.flush({render:true});
map.setGlobalStateProperty('shift',[12,0]);
map.setPaintProperty('route','line-translate',['global-state','shift']);
await map.sqs.flush({render:true});
Both properties use one uniform value for the whole layer. Constants, global-state, existing type/lexical/lazy combinations and continuous zoom are supported. A translation expression may be ['interpolate',['linear'],['zoom'],10,['literal',[0,8]],11,['literal',[0,16]]]. Expressions that read feature properties or feature-state are unsupported. An explicit object lookup, such as ['get','shift',['global-state','uniform']], remains uniform and can read a vector from a global object. Set a paint property to null to restore its default.
Project budgets limit each translation component to an absolute128 CSS pixels and the total actual vertex extrusion, including caps, joins and line-offset, to2048 CSS pixels. Rotation does not further restrict an otherwise valid diagonal vector. Exceeding a budget fails explicitly instead of silently clamping. These are SqsMap limits, not MapLibre specification limits.
Actual nonzero translation does not yet combine with dash, gradient, animation, pitch/3D, globe or media. Zero retains previous paths and boundaries. Translation can combine with supported solid line-offset, caps/joins and sorting.
Screen queries inverse-transform each layer's actual displacement before using existing hit testing and conservative offset envelopes. queryRenderedFeatures may hit nearby unpainted pixels and is not per-pixel picking. Source/feature IDs, properties, filter mapping and MVT logical identities remain unchanged. Coverage and resource planning must include geometry and tiles entering from outside the original viewport, rather than moving only already displayed fragments.
Invalid vectors, anchors, unsupported combinations and budgets retain the previous camera, globals, source, display and identities. Unselected future branches remain lazy; result budgets apply upon actual entry.
The shared script and complete HTML cover signed directions, rotated anchors, fractional zoom, rollback and actual incoming geometry pixels. Core d72b6eb6 passes six CPU checks, one serial actual GPU case and the same 36-check script with real pixels on Linux, browser main thread and Worker. The previous 30-check offset script passes all three paths. Matching SDK/WASM files were verified; see SDK acceptance for version and archive SHA. Devices, external platforms and formal release remain separate.
Semantics follow the official MapLibre translation specification, with an independent SqsMap implementation.