스네이크 케이스(snake case) 속성
- After Effects 사용 안내서
- Beta 릴리스
- 시작하기
- 작업 영역
- 프로젝트 및 컴포지션
- 푸티지 가져오기
- 텍스트 및 그래픽
- 그리기, 페인트, 패스
- 레이어, 마커, 카메라
- 애니메이션, 키프레임, 동작 추적, 키잉
- 투명도 및 합성
- 색상 조정
- 효과 및 애니메이션 사전 설정
- 표현식 및 자동화
- 몰입형 비디오, VR 및 3D
- After Effects에서 VR 환경 만들기
- 몰입형 비디오 효과 적용
- VR/360 비디오용 합성 툴
- 고급 3D 렌더러
- 컴포지션에 3D 모델 가져오기 및 추가
- Creative Cloud Libraries에서 3D 모델 가져오기
- 이미지 기반 조명
- 3D 모델에서 조명과 카메라 추출 및 애니메이션 적용
- 3D 카메라 움직임 추적
- 그림자 표시 및 허용
- 포함된 3D 모델 애니메이션
- 그림자 캐처
- 3D 심도 데이터 추출
- 3D 레이어의 질감 속성 수정
- 3D 디자인 공간에서 작업하기
- 3D 변형 기즈모
- 3D 애니메이션을 사용하여 더 많은 작업 수행
- Mercury 3D 엔진으로 3D 디자인 변경 사항 실시간 미리 보기
- 그래픽에 반응형 디자인 추가
- 보기 및 미리 보기
- 렌더링 및 내보내기
- 기타 애플리케이션으로 작업
- 공동 작업: Frame.io, Team Projects
- 메모리, 저장소, 성능
- 기술 자료
이 문서에서는 JavaScript와 After Effects 16.0의 레거시 ExtendScript 표현식 엔진 간 표현식 언어 구문 차이에 대해 설명합니다.
JavaScript 표현식 엔진에 맞게 표현식을 개선하는 방법 또는 이전 After Effects 릴리스용으로 작성된 표현식이 JavaScript 표현식 엔진에서 평가되지 않을 때 발생하는 오류를 수정하는 방법에 대해 자세히 알아보려면 다음 문서를 참조하십시오.
After Effects의 표현식 언어는 ECMAScript의 구현인 JavaScript를 기반으로 합니다. After Effects 16.0의 JavaScript 표현식 엔진은 ECMAScript 2018을 기반으로 합니다. 레거시 ExtendScript 표현식 엔진은 ECMAScript 3(1999)를 기반으로 합니다. (Adobe ExtendScript는 After Effects 및 기타 Adobe 애플리케이션에서 스크립팅에 사용되는 언어이기도 합니다.)
아래 제공된 예를 그대로 사용하거나 JavaScript 및 레거시 ExtendScript 표현식 엔진 모두에서 작동하는 표현식을 작성하기 위한 지침으로 사용할 수 있습니다.
JavaScript와 레거시 ExtendScript 표현식 엔진 간의 주요 차이는 다음과 같습니다.
- 최신 JavaScript 구문: ECMAScript 2018까지의 ECMAScript 5 JavaScript에 추가된 기능을 통해 JavaScript 표현식 엔진 사용 시 표현식에 최신 구문과 메서드를 사용할 수 있습니다. 또한 JavaScript 표현식 엔진 사용 시 표현식 구문에 몇 가지 소소한 개선이 이루어졌습니다. 다음은 몇 가지 주요 차이입니다.
- 호환되지 않는 레거시 구문: 일부 레거시 구문은 JavaScript 표현식 엔진과 호환되지 않습니다. 이 문서에는 이러한 예외적 구문 및 해당 구문이 JavaScript 엔진과 호환되도록 하는 데 필요한 변경 사항이 설명되어 있습니다. 다음은 몇 가지 주요 차이입니다.
- .jsx 표현식 라이브러리 및 eval()에 대한 구문 요구 사항: .jsx 표현식 함수 라이브러리 내에 표현식을 사용할 때 또는 eval() 내에서 표현식이 호출될 때 thisLayer. 및 thisProperty.는 명시적으로 호출되어야 하고 배열에 대한 수학 연산자는 벡터 수학 함수로 대체되어야 합니다. 다음은 몇 가지 주요 차이입니다.
최신 JavaScript 구문: 표현식 언어가 개선됨
표현식에 ECMAScript 2018의 JavaScript 구문 사용 가능
ECMAScript 3 이후 JavaScript 언어에 많은 기능이 추가되었습니다. 문자열, 배열 및 개체에 사용 가능한 더 간결하고 쉽게 읽을 수 있는 메서드가 새로 추가되었습니다. 또한 변수와 함수, 기본 매개 변수, 스프레드 연산자 등을 선언하는 새로운 방법이 추가되었습니다. 이러한 변경 내용은 JavaScript 언어에 일반적인 사항이므로 이 문서에서 다루지 않습니다. 추가된 많은 구문에 대한 자세한 내용은 다음 링크에서 제공하는 리소스를 참조하십시오.
- JavaScript ES5 가이드(일명 ECMAScript 5)
- 새로운 배열 메서드
- 새로운 개체 메서드
- JSON.stringify() & JSON.parse()
JavaScript에 대해 자세히 알아볼 수 있는 추가 권장 리소스:
소스 텍스트의 다른 속성에 연결할 때 더 이상 .value가 필요하지 않음
소스 텍스트 속성에서 다른 속성 값을 참조할 때 레거시 ExtendScript 엔진에서는 속성의 끝에 .value가 추가되어야 합니다. JavaScript 엔진은 .propertyIndex 또는 .name과 같은 다른 특성이 명시적으로 사용되지 않으면 기본적으로 속성의 값을 표시합니다.
예를 들면 다음과 같습니다.
thisComp.layer("Solid 1").transform.position // 레거시 엔진에서는 소스 텍스트 속성에 적용될 때 "[개체 속성]"으로 평가됩니다. // JavaScript 엔진에서는 소스 텍스트 속성에 적용될 때 layer "Solid 1"의 Position 속성 값으로 평가됩니다.
posterizeTime(0)을 사용하여 속성 값 고정
After Effects 16.0에서는 posterizeTime(0)이 컴포지션의 시간 0에 속성 값을 고정합니다. 이 사항은 JavaScript와 레거시 ExtendScript 엔진 모두에 적용됩니다.
이전 버전과 호환되지 않으므로 16.0 이전의 After Effects 버전에서는 예기치 않은 결과를 야기할 수 있습니다.
호환되지 않는 레거시 구문
레거시 ExtendScript 표현식 엔진의 거의 모든 표현식 구문은 JavaScript 표현식 엔진과 호환됩니다. 그러나 JavaScript 표현식 엔진과 호환되지 않는 일부 레거시 구문이 있습니다. 이는 최신 JavaScript의 구문 변경으로 인해 야기될 수 있습니다. 사용되지 않거나 오래된 구문이 제거되었기 때문일 수도 있습니다. 아래에는 작동하지 않는 구문과 작동하는 구문의 예가 나와 있습니다.
대부분의 구문 차이는 표현식을 다시 작성하는 애플리케이션 스크립팅을 통해 수정할 수 있습니다.
if...else 구문 차이
일반적으로 if...else 문은 MDN 지침에 따라 항상 줄 바꿈과 대괄호를 사용하여 작성하는 것이 좋습니다. 레거시 ExtendScript 엔진은 if...else 문의 느슨한 구문에 관대하지만 JavaScript 엔진은 엄격합니다. JavaScript 엔진을 사용할 때는 if...else 문이 평가되지 않습니다.
else 없는 if 문으로 표현식을 끝내는 것이 허용되지 않음
표현식이 else 문이 없는 if 문으로 끝날 경우 JavaScript 엔진이 표현식을 평가하지 못하고 "정의되지 않은 값이 표현식에 사용되었습니다(범위를 벗어나는 배열 하위 스크립트일 수 있습니까?)"와 같은 오류가 표시됩니다. 레거시 ExtendScript 엔진에서는 시간이 1초보다 크면 다음 표현식이 100으로 평가되고 그렇지 않으면 50으로 평가됩니다.
var x = 50; if ( time > 1 ) { x = 100 } // 여기에서 "else"는 묵시적이며 명시되지 않습니다.
JavaScript 엔진을 사용할 때는 명령문의 else 부분이 표현식의 마지막 명령문일 경우 명시적으로 표현되어야 합니다.
var x = 50; if ( time > 1 ) { x = 100; } else { x; }
이 경우 JavaScript 엔진과 레거시 ExtendScript 엔진 모두에서 표현식이 올바르게 평가됩니다.
if와 else가 대괄호 없이 같은 줄에 나올 수 없음
if...else 문이 대괄호 없이 같은 줄에 나올 경우 레거시 ExtendScript 엔진에서는 문이 평가되지만 JavaScript 엔진에서는 문이 평가되지 않고 "구문 오류: 예기치 않은 토큰 " 또는 "정의되지 않은 값이 표현식에 사용되었습니다(범위를 벗어나는 배열 하위 스크립트일 수 있습니까?)"와 같은 오류가 표시됩니다. 표시되는 오류는 컨텍스트 및 속성 유형에 따라 달라질 수 있습니다.
레거시 ExtendScript 엔진에서는 시간이 1초보다 크면 다음 표현식이 100으로 평가되고 그렇지 않으면 50으로 평가됩니다.
if ( time > 1 ) 100 else 50;
JavaScript 엔진에서는 if...else 문이 평가되려면 줄 바꿈이나 대괄호를 사용해야 합니다. 단순한 예로, 삼항 연산자를 대신 사용할 수 있습니다. 다음은 JavaScript 엔진에 사용할 수 있는 구문입니다.
// 솔루션 A: "else" 앞에 줄 바꿈을 추가하면 두 엔진이 모두 올바르게 평가됩니다. if ( time > 1 ) 100 else 50; // 솔루션 B: 올바른 괄호를 추가하면 두 엔진이 모두 올바르게 평가될 수 있습니다. if ( time > 1 ) { 100 } else { 50 }; // 솔루션 C: if...else문 대신 삼항 연산자를 사용하면 두 엔진에서 모두 올바르게 평가됩니다. time > 1 ? 100 : 50;
위의 해결 방법을 사용하면 JavaScript 엔진과 레거시 ExtendScript 엔진 모두에서 표현식이 올바르게 평가됩니다.
표현식이 함수 선언으로 끝날 수 없음
표현식이 함수 선언으로 끝나면 JavaScript 엔진이 표현식을 평가하지 못하고 "숫자, 배열 또는 속성이 필요한 개체 유형이 있습니다."와 같은 오류가 표시됩니다. JavaScript 엔진에서는 평가된 마지막 항목이 값을 선언하는 대신 반환해야 합니다.
다음 예는 레거시 엔진에서는 작동하지만 JavaScript 엔진에서는 작동하지 않습니다.
tiimesTen( value ); // 레거시 엔진은 함수가 아래에 선언되어 있더라도 이 라인을 평가합니다. function timesTen ( val ) { return val * 10 }
함수가 (선언 대신) 마지막 줄로 호출되면 표현식이 두 엔진에서 올바르게 평가됩니다.
function timesTen ( val ) { return val * 10 } timesTen( value ); // JavaScript 엔진에서는 올바른 값을 반환하기 위해 선언 아래에 함수 호출이 발생해야 합니다.
this() 약식 구문이 허용되지 않음 (대신 thisLayer() 사용)
레거시 ExtendScript 엔진에서 this는 thisLayer에 대한 약식 구문으로 사용할 수 있었습니다.JavaScript 엔진에서는 this가 전체 개체를 참조하므로 대신 thisLayer를 사용해야 합니다. JavaScript 엔진에서 this를 사용하면 일반적으로 "함수가 아닙니다."와 같은 오류가 표시됩니다.
다음 레거시 ExtendScript 예에서는 this가 소스 텍스트 속성의 텍스트 레이어 위치 속성에 대한 압축 링크를 만드는 데 사용됩니다.
this(5)(2).value;
JavaScript 엔진에서 this는 thisLayer로 대체해야 합니다.
thisLayer(5)(2).value;
thisLayer 사용은 두 표현식 엔진 모두에서 호환됩니다.
문자에 대한 소스 텍스트 속성 배열-색인 액세스에 .value 필요
레거시 ExtendScript 표현식 엔진에서는 배열처럼 대괄호 표기를 사용하여 텍스트 속성의 문자에 액세스할 수 있었습니다.
text.sourceText[0] // 소스 텍스트 속성의 텍스트 값에서 첫 번째 문자를 반환합니다.
JavaScript 엔진에서는 문자에 액세스하려면 .value를 추가해야 합니다.
text.sourceText.value[0] // 소스 텍스트 속성의 텍스트 값에서 첫 번째 문자를 반환합니다.
이 구문은 두 엔진 모두와 호환됩니다.
속성 및 메서드 스네이크 케이스(snake case)가 허용되지 않음
사용되지 않는 스네이크 케이스(snake case) 속성 및 메서드(카멜 케이스 대신 밑줄을 사용하여 작성됨)는 JavaScript 엔진에서 지원하지 않습니다. 두 엔진 모두와 호환되는 카멜 케이스 버전을 사용해야 합니다. 다음은 사용되지 않는 스네이크 케이스(snake case) 및 해당하는 카멜 케이스의 목록입니다.
|
카멜 케이스 속성 |
스네이크 케이스(snake case) 메서드 |
카멜 케이스 메서드 |
---|---|---|---|
this_comp this_layer this_property color_depth has_parent in_point out_point start_time has_video has_audio audio_active anchor_point audio_levels time_remap casts_shadows light_transmission accepts_shadows accepts_lights frame_duration shutter_angle shutter_phase num_layers pixel_aspect point_of_interest depth_of_field focus_distance blur_level cone_angle cone_feather shadow_darkness shadow_diffusion active_camera |
thisComp thisLayer thisProperty colorDepth hasParent inPoint outPoint startTime hasVideo hasAudio audioActive anchorPoint audioLevels timeRemap castsShadows lightTransmission acceptsShadows acceptsLights frameDuration shutterAngle shutterPhase numLayers pixelAspect pointOfInterest depthOfField focusDistance blurLevel coneAngle coneFeather shadowDarkness shadowDiffusion activeCamera |
value_at_time() velocity_at_time() speed_at_time() nearest_key() posterize_time() look_at() seed_random() gauss_random() ease_in() ease_out() rgb_to_hsl() hsl_to_rgb() degrees_to_radians() radians_to_degrees() from_comp_to_surface() to_comp_vec() from_comp_vec() to_world_vec() from_world_vec() to_comp() from_comp() to_world() from_world() temporal_wiggle() loop_in_duration() loop_out_duration() loop_in() loop_out() |
valueAtTime() velocityAtTime() speedAtTime() nearestKey() posterizeTime() lookAt() seedRandom() gaussRandom() easeIn() easeOut() rgbToHsl() hslToRgb() degreesToRadians() radiansToDegrees() fromCompToSurface() toCompVec() fromCompVec() toWorldVec() fromWorldVec() toComp() fromComp() toWorld() fromWorld() temporalWiggle() loopInDuration() loopOutDuration() loopIn() loopOut() |
이진 인코딩(.jsxbin) 표현식에 eval() 사용
ExtendScript 이진 형식으로 인코딩된 표현식(ExtendScript ToolKit CC에서 이진 .jsxbin 파일로 저장됨)은 JavaScript 엔진에서 지원하지 않습니다.
표현식을 난독화하려면 레거시 ExtendScript 엔진을 사용하거나 ECMAScript 2018과 호환되는 다른 난독화 메서드를 사용하십시오. 몇몇 난독화 메서드는 두 표현식 엔진 중 하나와 호환되지 않을 수 있습니다.
$.(달러) 개체에 대한 지원 제한
$.(달러) 개체의 메서드와 속성은 ExtendScript에 고유하며 JavaScript 엔진에서는 대부분 지원되지 않습니다. 다음 표에는 $.(달러) 개체의 지원되지 않는 용례 및 지원되는 용례가 나와 있습니다.
지원되지 않는 $. |
지원되는 $. |
---|---|
$.fileName $.hiResTimes $.stack $.evalFile() $.list() $.setenv() $.getenv() $.appEncoding $.buildDate $.decimalPoint $.dictionary $.error $.flags $.includePath $.level $.line $.locale $.localize $.memCache $.os $.screens $.strict $.version |
$.build $.engineName(레거시 ExtendScript 엔진에서는 지원되지 않음) $.global |
...reflect.properties, ...reflect.methods 및 toSource()가 지원되지 않음
reflect.properties 및 reflect.methods는 JavaScript 엔진에서 지원되지 않습니다. ExtendScript에 고유한 메서드이며 JavaScript에는 직접적으로 해당하는 메서드가 없습니다.
toSource() JavaScript에서는 사용도지 않으며 표준 트랙의 일부가 아닙니다.
특정 After Effects 속성에 대해 위 메서드가 제공한 것과 유사한 사용 가능한 속성 및 메서드의 목록을 보려면 소스 텍스트 속성에 다음 표현식을 사용하고 원하는 속성에 연결하십시오. 예를 들어, 줄 1에서 thisProperty 대신 pick whip을 사용합니다.
let obj = thisProperty; // "thisProperty"를 원하는 속성에 대한 속성 링크로 대체합니다. let props = []; do { Object.getOwnPropertyNames(obj).forEach(prop => { if (props.indexOf(prop) === -1) { props.push(prop); } }); } while (obj = Object.getPrototypeOf(obj)); props.join("\n"); // 사용 가능한 속성과 메서드를 나열하는 스트링 어레이를 반환합니다.
위의 표현식은 레거시 ExtendScript 엔진과 호환되지 않습니다. 위 표현식에는 ECMAScript 3에서 사용할 수 없는 구문과 메서드가 사용되었습니다.
JavaScript 엔진을 사용한 .jsx 표현식 라이브러리 및 eval()에 대한 구문 요구 사항
.jsx 표현식 함수 라이브러리 내에서 표현식을 사용할 경우 또는 eval() 내에서 표현식이 호출될 경우 특정 구문을 수정해야 합니다.
명시적 thisLayer. 또는 thisProperty.레이어 또는 속성에 대해 명시적으로 호출되지 않는 기본 메서드 또는 특성에 접두사가 추가되어야 합니다. 접두사는 메서드 또는 특성을 호출하는 대상 개체가 무엇인지를 JavaScript 엔진에 알립니다.
Position과 같은 배열 값에 대한 수학 연산의 경우, 배열의 모든 항목에서 수학 연산이 작동하려면 벡터 함수나 루프 함수를 사용하여 계산되어야 합니다. position + [100,100]과 같은 오버로드된 수학 연산자는 평가되지 않습니다.
JavaScript 엔진을 사용할 경우, 일부 레거시 ExtendScript 표현식 구문을 새로운 엔진이 읽을 수 있으려면 평가 전에 표현식이 사전 처리되어야 합니다. 그러나 .jsx 표현식 함수 라이브러리의 표현식을 평가할 때나 표현식이 eval() 내에서 호출될 때는 이러한 사전 처리 작업이 수행되지 않습니다. 이러한 경우 위의 구문 수정이 수동으로 이루어져야 합니다. 이러한 모든 구문 수정은 레거시 ExtendScript 엔진과 호환되므로 JavaScript 엔진에서 작동하도록 작성된 .jsx 표현식 라이브러리는 레거시 ExtendScript 엔진에서도 작동합니다.
성능 팁: 사전 처리가 수행되지 않으므로 이 구문 및 JavaScript 엔진을 사용하여 .jsx 라이브러리에서 복잡한 표현식을 호출할 경우 동일한 표현식을 속성에 대해 직접 호출할 때와 비교해 성능이 향상될 수 있습니다.
기본 메서드 및 특성에 명시적으로 thisLayer. 또는 thisProperty. 접두사 지정
다음 표에는 접두사가 필요한 메서드 및 특성이 나와 있습니다. 예를 들어, 시간은 thisLayer.time으로 작성하고 wiggle()은 thisProperty.wiggle()로 작성해야 합니다.
이러한 접두사는 특성이나 메서드가 이미 다른 레이어 또는 속성에 대해 명시적으로 호출되지 않은 경우에만 필요합니다. 예를 들어, thisComp.layer(1).hasParent를 호출할 때 thisLayer.를 추가하지 않아도 됩니다. 이미 .hasParent가 layer(1)에서 명시적으로 호출되었기 때문입니다.
thisLayer.가 필요한 메서드 |
thisLayer.가 필요한 특성 |
thisProperty.가 필요한 메서드 |
thisProperty.가 필요한 특성 |
---|---|---|---|
comp() |
time |
valueAtTime() |
velocity |
수학 연산자를 벡터 수학 함수로 대체
JavaScript와 LegacyExtendScript 엔진 모두 배열에 대해 position + [100,100]과 같은 구문을 사용하여 수학 연산자를 오버로드하는 것을 허용하지만 .jsx 표현식 함수 라이브러리 내의 식이나 eval() 내의 식에 대해서는 작동하지 않습니다.
Position, Scale 등과 같은 배열 속성에 대해 수학 연산을 수행하려면 더하기, 빼기, 곱하기 및 나누기를 위해 각각에 해당하는 벡터 수학 함수를 사용해야 합니다. 벡터 수학 함수는 일반 숫자에 대해서도 작동하므로 두 데이터 유형 중 하나의 속성에 대해 호출될 수 있는 함수는 벡터 수학 함수를 사용해야 합니다.
thisLayer. 접두사는 벡터 수학 함수와 함께 사용해야 합니다.
- 더하기: thisLayer.add(vec1, vec2)
- 빼기: thisLayer.sub(vec1, vec2)
- 곱하기: thisLayer.mul(vec, amount)
- 나누기: thisLayer.div(vec, amount)
다음은 표준 수학 함수와 업데이트된 벡터 함수를 사용한 표현식의 예입니다. 또한 벡터 수학 함수는 필요한 경우 적절한 thisLayer.또는 thisProperty. 접두사를 사용합니다.
Position 속성의 wiggle()과 값 간의 차이를 찾으려면:
// 표준 수학: wiggle() - value; // 벡터 수학: thisLayer.sub( thisProperty.wiggle(), value );
linear()와 유사하지만 확장 범위가 정의된 최소 및 최대를 넘도록 두 값 간을 보간하려면:
// 표준 수학: value1 + ( ( t - tMin ) / ( tMax - tMin ) ) * ( value2 - value1 ); // 벡터 수학: thisLayer.add( value1, thisLayer.mul( thisLayer.div( thisLayer.sub( t, tMin ), thisLayer.sub( tMax, tMin ) ), thisLayer.sub( value2, value1 ) ) );
Position 속성을 안과 밖으로 루프하려면:
// 표준 수학: loopIn( "cycle" ) + loopOut( "cycle" ) - value; // 벡터 수학: thisLayer.sub( thisLayer.add( thisProperty.loopIn( "cycle" ), thisProperty.loopOut( "cycle" ) ), value );