Add outlines around shapes, text, and graphics to enhance visual definition and create decorative effects.
Strokes add visual outlines that define block boundaries. You can customize their color, width, line style (solid, dashed, dotted), position relative to the block edge, and corner treatment. You can also paint a stroke with a gradient fill. CE.SDK provides programmatic APIs for complete stroke management in headless workflows.
This guide covers how to apply and manage strokes programmatically using the block API.
Checking Stroke Support#
Before applying strokes programmatically, verify the block supports them using supportsStroke(). Not all block types have stroke capabilities.
// Check if the block supports strokes before applyingconst canHaveStroke = engine.block.supportsStroke(graphic);console.log('Block supports strokes:', canHaveStroke);Enabling Strokes#
Enable strokes on a block using setStrokeEnabled(). You can check the current state with isStrokeEnabled().
// Enable stroke on the blockengine.block.setStrokeEnabled(graphic, true);
// Verify stroke is enabledconst strokeEnabled = engine.block.isStrokeEnabled(graphic);console.log('Stroke enabled:', strokeEnabled);Setting Stroke Color#
Control stroke color using setStrokeColor() with an RGBA color object. Color values range from 0.0 to 1.0. Retrieve the current color with getStrokeColor().
// Set stroke color to blue (RGBA values from 0.0 to 1.0)engine.block.setStrokeColor(graphic, { r: 0.2, g: 0.4, b: 0.9, a: 1.0 });
// Read the current stroke colorconst strokeColor = engine.block.getStrokeColor(graphic);console.log('Stroke color:', strokeColor);Setting Stroke Width#
Set stroke thickness in design units using setStrokeWidth(). Larger values create more prominent outlines. Get the current width with getStrokeWidth().
// Set stroke width in design unitsengine.block.setStrokeWidth(graphic, 8);
// Read the current stroke widthconst strokeWidth = engine.block.getStrokeWidth(graphic);console.log('Stroke width:', strokeWidth);Stroke Styles#
Control the line pattern using setStrokeStyle(). Available styles include:
- Solid - Continuous line
- Dashed - Square-ended dashes with gaps
- DashedRound - Round-ended dashes with gaps
- Dotted - Circular dots
- LongDashed - Longer square-ended dashes
- LongDashedRound - Longer round-ended dashes
// Set stroke style to dashed// Available styles: 'Solid', 'Dashed', 'DashedRound', 'Dotted',// 'LongDashed', 'LongDashedRound'engine.block.setStrokeStyle(graphic, 'Dashed');
// Read the current stroke styleconst strokeStyle = engine.block.getStrokeStyle(graphic);console.log('Stroke style:', strokeStyle);Stroke Position#
Control where the stroke renders relative to the block edge using setStrokePosition():
- Center - Stroke centered on the edge (default)
- Inner - Stroke rendered inside the block boundary
- Outer - Stroke rendered outside the block boundary
Position affects how strokes interact with adjacent elements and overall layout dimensions. Inner strokes stay within the block bounds, while outer strokes extend beyond them.
// Set stroke position relative to block edge// Available positions: 'Center', 'Inner', 'Outer'engine.block.setStrokePosition(graphic, 'Outer');
// Read the current stroke positionconst strokePosition = engine.block.getStrokePosition(graphic);console.log('Stroke position:', strokePosition);Stroke Corner Geometry#
Control how stroke corners are rendered using setStrokeCornerGeometry(). This is particularly visible on rectangular shapes:
- Miter - Sharp pointed corners, up to the miter limit (default)
- Round - Smoothly curved corners
- Bevel - Flat cut corners
// Set stroke corner geometry// Available geometries: 'Miter', 'Round', 'Bevel'engine.block.setStrokeCornerGeometry(graphic, 'Round');
// Read the current corner geometryconst cornerGeometry = engine.block.getStrokeCornerGeometry(graphic);console.log('Corner geometry:', cornerGeometry);Miter Limit#
A mitered corner extends to a point. On a sharp corner, this point can reach far beyond the shape. The stroke/miterLimit property limits the length of the miter as a multiple of the stroke width. A corner whose miter is longer than this limit gets a bevel.
Set the limit with setFloat() and read it with getFloat(). The limit only changes corners that use the Miter corner geometry.
- Graphic blocks and pages use a default limit of 35.
- Text blocks use a default limit of 4.
- The value must be 1 or greater. A smaller value throws an error.
// Bevel each corner whose miter is longer than 1.5 times the stroke widthengine.block.setStrokeCornerGeometry(star, 'Miter');engine.block.setFloat(star, 'stroke/miterLimit', 1.5);const miterLimit = engine.block.getFloat(star, 'stroke/miterLimit');console.log('Stroke miter limit:', miterLimit);Painting Strokes with a Fill#
A stroke uses its stroke color by default. To paint the stroke with a gradient instead, create a fill and set it with setStrokeFill(). getStrokeFill() returns this fill, or null when the stroke uses its color.
// Paint the stroke with a linear gradient instead of the stroke colorconst strokeGradient = engine.block.createFill('gradient/linear');engine.block.setGradientColorStops(strokeGradient, 'fill/gradient/colors', [ { color: { r: 0.2, g: 0.4, b: 0.9, a: 1.0 }, stop: 0 }, { color: { r: 0.9, g: 0.2, b: 0.5, a: 1.0 }, stop: 1 }]);engine.block.setStrokeFill(star, strokeGradient);const strokeFill = engine.block.getStrokeFill(star);console.log('Stroke fill:', strokeFill);The stroke fill replaces only the color. Width, style, position and corner settings stay the same. Keep these rules in mind:
- Graphic blocks and pages support stroke fills. Text blocks do not.
- Color, gradient and stripe fills are supported. Image and video fills are rejected.
- The block’s own fill cannot also paint its stroke. Create a separate fill block.
- A stroke color with an alpha of 0 still hides the stroke.
- Call
setStrokeFill(block, null)to paint the stroke with its color again. This does not destroy the previous fill block.
Troubleshooting#
If strokes don’t appear as expected, check these common issues:
- Stroke not visible - Verify stroke is enabled with
isStrokeEnabled()and width is greater than 0 - Stroke color appears wrong - Ensure color values are in the 0.0-1.0 range, not 0-255
- Stroke affects layout unexpectedly - Use Inner position to keep strokes within bounds, or Outer if you want strokes to extend beyond the block
- Block doesn’t support strokes - Use
supportsStroke()to verify capability before applying stroke properties - Sharp corners look cut off - The miter is longer than the miter limit. Raise
stroke/miterLimit, or use Round corners - Miter limit is rejected - The value is below 1 or not finite (
BLOCK.STROKE_MITER_LIMIT_INVALID) - Stroke fill is rejected - The block is a text block (
BLOCK.STROKE_FILL_UNSUPPORTED), the fill draws an image or video (BLOCK.STROKE_FILL_TYPE_UNSUPPORTED), or the fill is the block’s own fill (BLOCK.FILL_ALREADY_USED_BY_BLOCK)
API Reference#
| Method | Description |
|---|---|
block.supportsStroke(block) |
Check if a block supports strokes |
block.setStrokeEnabled(block, enabled) |
Enable or disable stroke on a block |
block.isStrokeEnabled(block) |
Check if stroke is enabled |
block.setStrokeColor(block, color) |
Set stroke color (RGBA, values 0.0-1.0) |
block.getStrokeColor(block) |
Get current stroke color |
block.setStrokeWidth(block, width) |
Set stroke thickness in design units |
block.getStrokeWidth(block) |
Get current stroke width |
block.setStrokeStyle(block, style) |
Set line pattern (Solid, Dashed, Dotted, etc.) |
block.getStrokeStyle(block) |
Get current stroke style |
block.setStrokePosition(block, position) |
Set stroke position (Center, Inner, Outer) |
block.getStrokePosition(block) |
Get current stroke position |
block.setStrokeCornerGeometry(block, type) |
Set corner rendering (Miter, Round, Bevel) |
block.getStrokeCornerGeometry(block) |
Get current corner geometry |
block.setFloat(block, 'stroke/miterLimit', limit) |
Set the miter limit as a multiple of the stroke width (experimental) |
block.getFloat(block, 'stroke/miterLimit') |
Get the current miter limit (experimental) |
block.setStrokeFill(block, fill) |
Paint the stroke with a fill, or pass null to use the stroke color (experimental) |
block.getStrokeFill(block) |
Get the fill that paints the stroke, or null (experimental) |