# Shape & Mask

## General tips

### Maintain stroke width

```javascript
// from campkeyframe
sf = transform.scale[0]/100; ov = value;nv = ov / sf

// for parented shapes 
value / length(toComp([0,0]), toComp([0.7071,0.7071])) || 0.001;


// https://battleaxe.tumblr.com/post/101945073972/maintain-stroke-weight-expression
```

### Looping paths (loopOut() doesn't work for paths)

{% tabs %}
{% tab title="Pingpong" %}

```javascript
if (numKeys >1 && time > key(numKeys).time){
 t1 = key(1).time;
 t2 = key(numKeys).time;
 span = t2 - t1;
 delta = time - t2;
 seg = Math.floor(delta/span);
 t = delta%span;
 valueAtTime((seg%2) ? (t1 + t) : (t2 - t));
}else
 value
```

{% endtab %}

{% tab title="cycle" %}

```javascript
if (numKeys >1 && time > key(numKeys).time){
 t1 = key(1).time;
 t2 = key(numKeys).time;
 span = t2 - t1;
 delta = time - t2;
 t = delta%span;
 valueAtTime(t1 + t)
}else
 value
```

{% endtab %}
{% endtabs %}

## Accessing Shape parameters

Reference: <https://ae-expressions.docsforadobe.dev/group.html?highlight=shape%20property#group>

### Syntax & Usage

```javascript
thisProperty.propertyGroup(1).numProperties
thisProperty.propertyGroup(1).propertyIndex
```

### Shape Property Index

Let's say if you have multiple Ellipses or other shapes within a Shape Layer Contents, and you want to retrieve the index of each Shape:

```javascript
content("Ellipse 1").propertyIndex
```

```javascript
thisProperty.propertyGroup(3).propertyIndex
```

If you want to use parse the index via the property name:

```javascript
// using name as index eg. line_1
parseInt(thisProperty.propertyGroup(3).name.split("_")[1]); // method 1

parseInt(content(1).name.split("_")[1]) // method 2
```

### Shape Property Group and Index

```javascript
// shape group index
thisProperty.propertyGroup(2).propertyIndex // change num accordingly


```

### Examples

* [Property Group Index Expression + Free Preset](https://youtu.be/xgUNncvKXY8)

{% embed url="<https://youtu.be/xgUNncvKXY8>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nosleepcreative.com/after-effects/expressions/shape-and-mask-paths.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
