Beauty iFrame is an in-browser real-time augmented reality make-up web-app. The web-app allows for a fast, realistic live try-on experience on mobile or desktop directly from a brand’s web page.
Holition Beauty’s virtual makeup engine (FaceSDK) depends on many modern Web-APIs which are not implemented by all browsers. The AR experience also depends on access to the device camera to operate.
The following are the minimum specifications required to operate:
Apple: OSX Sierra+, Safari 11+, Chrome 44+, Firefox 47+
Microsoft: Windows 10, Chrome 44+, Firefox 47+
WebGL 1+
The user must grant the web-app access to their camera to allow the experience to operate. A pop-up provided by the browser will be presented to the user upon initialisation.
The user can sign in to our Beauty Portal and use it for iFrame setup or choose manul way.
Follow our Video Tutorial for installation
To install the experience onto an existing web-page simply cut and paste the following HTML snippet into your page:
<iframe frameBorder="0" style="width: 100%;height: 100%;" allow="camera" src="https://<DEPLOYMENT-URL>?cms-client-id=<CMS-CLIENT-ID>&license=<LICENSE>"</iframe>
The HTML code inserts a configurable iFrame element into the page. In effect placing a virtual makeup experience into a resizable window onto your site.
There are two parts to setting up your virtual make-up experience. First the look and feel of the experience. Second the make up products and looks available to the users within.
The iFrame element allows for direct control over certain features and launch configurations of the web-app. These configurations are performed via URL parameters provided to the iFrame src attribute as follows:
<iframe frameBorder="0" style="width: 100%;height: 100%;" allow="camera" src="https://<DEPLOYMENT-URL>?cms-client-id=<CMS-CLIENT-ID>&configuration-id=<CONFIG-ID>&license=<LICENSE>&locale=<LOCALE>&identifier-type=<TYPE>&identifier-value=<VALUE>&range-id=<RANGE-ID>&looks=<BOOLEAN>&features=<OPTION>&carousel=<BOOLEAN>&filter=<BOOLEAN>&product-info=<BOOLEAN>&look-info=<BOOLEAN>&add-basket=<BOOLEAN>&watermark=<BOOLEAN>&vtoggle=<BOOLEAN>&cta-activated=<BOOLEAN>&info-button=<BOOLEAN>&ga-tracking=<BOOLEAN>&static-start=<BOOLEAN>&allow-upload=<BOOLEAN>&hide-scan=<BOOLEAN>&auto-scan=<BOOLEAN>&hide-photo=<BOOLEAN>&model-warmup=<BOOLEAN>&simplify-carousel-info=<BOOLEAN>&range-name=<RANGE-NAME>&beautify=<FILTER-NAME>&timeout=<NUMBER>&photo-start=<BOOLEAN>&light-scan=<BOOLEAN>&crop-thumbnails=<BOOLEAN>"</iframe>
[NB. URL parameters take priority over CMS settings]
To control the look and feel of the virtual experience either:
DEPLOYMENT-URL
- (required)
Link to a release you want, please see the release tab for these.cms-client-id
- (required)
This is the id of your client on the calibration portal cms. This is where product information is pulled from. Info can be found in the Portal Guidelicense
- (required)
The sdk requires a license to use.identifier-type
- (optional)
The type of product or look identifier "cms-id" | "SKU" | "EAN" | "UPC" | "GTIN" | "ASIN" | "Shade" | "Range" | "Other"
identifier-value
- (optional)
The product or look identifier valuerange-id
- (optional)
The product or look range identifier (found in CMS) used to limit product displayrange-name
- (optional)
Lookup the product or look range by name field filteringlooks
- (optional)
Switch between using looks and products (true | false)features
- (optional)
enable control buttons (all | photo | slider | image | scan | shade)carousel
- (optional)
enable product carousel (true | false)filter
- (optional)
enable product type filter swiper (true | false)configuration-id
- (optional)
overrides the default ui config with one from the holition beauty portal, url parameters still take priority over this configproduct-info
- (optional)
show product information panel and button in carousel (true | false)look-info
- (optional)
show look information panel and button in carousel (true | false)add-basket
- (optional)
show “add to basket” button on product information panel (true | false)watermark
- (optional)
show the Holition Beauty watermark (true | false)vtoggle
- (optional)
toggle visibility of looks and products filter bar (true | false)info-button
- (optional)
toggle general info button display (true | false)ga-tracking
- (optional)
toggle inclusing of Google Analytics tracking (true | false)simplify-carousel-info
- (optional)
toggle simplification of product info display (true | false)static-start
- (optional)
toggle launch option for static or live camera view (true | false)allow-upload
- (optional)
toggle additional Upload Image button in video source (true | false)hide-photo
- (optional)
toggle hiding of the display of the take-a-photo result (true | false)hide-scan
- (optional)
toggle to hide on-screen face-scan results (true | false)hide-scan-message
- (optional)
toggle to hide on-screen face-scan instruction message (true | false)auto-scan
- (optional)
force face-scan at start of experience (true | false)beautify
- (optional)
show beautify filter at selected intensity (excluded on foundations & looks) (natural | bright | heavy’)timeout
- (optional)
set idle timeout, measured in seconds (defaults to 10 minutes or 600 seconds)cta-activated
- (optional)
use call-to-action idle screen (defaults to false) (true | false)photo-start
- (optional)
toggle launch option for static photo capture start (true | false)model-warmup
- (optional)
do all AI warmup during loading (defaults to false unless scan feature is activated) (true | false)light-scan
- (optional)
use lightweight scan without image quality checkscrop-thumbnails
- (optional)
crop thumbnails to user face (true | false)locale
- (optional)
if not set the locale is automatically detected from the browser. When applied it overrides auto-detection and sets the locale for the experience. Defaults if no match found in cms to “en”, can be any of:"aa" | "ab" | "ae" | "af" | "af-za" | "ak" | "am" | "am-et" | "an" | "ar" | "ar-ae" | "ar-bh" | "ar-dz" | "ar-eg" | "ar-iq" | "ar-jo" | "ar-kw" | "ar-lb" | "ar-ly" | "ar-ma" | "ar-om" | "ar-qa" | "ar-sa" | "ar-sy" | "ar-tn" | "ar-ye" | "as" | "av" | "ay" | "az" | "az-cyrl-az" | "az-latn-az" | "ba" | "be" | "be-by" | "bg" | "bg-bg" | "bh" | "bi" | "bm" | "bn" | "bn-in" | "bo" | "br" | "br-fr" | "bs" | "bs-cyrl-ba" | "bs-latn-ba" | "ca" | "ca-es" | "ce" | "ch" | "co" | "cr" | "cs" | "cs-cz" | "cu" | "cv" | "cy" | "da" | "da-dk" | "de" | "de-at" | "de-ch" | "de-de" | "div-mv" | "dv" | "dz" | "ee" | "el" | "el-gr" | "en" | "en-au" | "en-bz" | "en-ca" | "en-gb" | "en-ie" | "en-jm" | "en-nz" | "en-ph" | "en-tt" | "en-us" | "en-za" | "en-zw" | "eo" | "es" | "es-ar" | "es-bo" | "es-cl" | "es-co" | "es-cr" | "es-do" | "es-ec" | "es-es" | "es-gt" | "es-hn" | "es-mx" | "es-ni" | "es-pa" | "es-pe" | "es-pr" | "es-py" | "es-sv" | "es-uy" | "es-ve" | "et" | "et-ee" | "eu" | "eu-es" | "fa" | "fa-ir" | "ff" | "fi" | "fi-fi" | "fj" | "fo" | "fo-fo" | "fr" | "fr-be" | "fr-ca" | "fr-ch" | "fr-fr" | "fr-lu" | "fr-mc" | "fy" | "ga" | "gd" | "gl" | "gl-es" | "gn" | "gu" | "gu-in" | "gv" | "ha" | "he" | "he-il" | "hi" | "hi-in" | "ho" | "hr" | "hr-hr" | "ht" | "hu" | "hu-hu" | "hy" | "hy-am" | "hz" | "ia" | "id" | "id-id" | "ie" | "ig" | "ii" | "ik" | "io" | "is" | "is-is" | "it" | "it-ch" | "it-it" | "iu" | "ja" | "ja-jp" | "jv" | "ka" | "ka-ge" | "kg" | "ki" | "kj" | "kk" | "kk-kz" | "kl" | "km" | "km-kh" | "kn" | "kn-in" | "ko" | "ko-kr" | "kok-in" | "kr" | "ks" | "ku" | "kv" | "kw" | "ky" | "ky-kz" | "la" | "lb" | "lg" | "li" | "ln" | "lo" | "lo-la" | "lt" | "lt-lt" | "lu" | "lv" | "lv-lv" | "mg" | "mh" | "mi" | "mi-nz" | "mk" | "mk-mk" | "ml" | "mn" | "mn-mn" | "mr" | "mr-in" | "ms" | "ms-bn" | "ms-my" | "mt" | "my" | "na" | "nb" | "nb-no" | "nd" | "ne" | "ng" | "nl" | "nl-be" | "nl-nl" | "nn" | "nn-no" | "no" | "nr" | "nv" | "ny" | "ny-mw" | "oc" | "oj" | "om" | "or" | "os" | "pa" | "pa-in" | "pi" | "pl" | "pl-pl" | "ps" | "pt" | "pt-br" | "pt-pt" | "qu" | "rm" | "rn" | "ro" | "ro-ro" | "ru" | "ru-ru" | "rw" | "sa" | "sa-in" | "sc" | "sd" | "se" | "sg" | "si" | "sk" | "sk-sk" | "sl" | "sl-sl" | "sm" | "sn" | "so" | "sq" | "sq-al" | "sr" | "sr-cyrl-rs" | "sr-latn-rs" | "ss" | "st" | "su" | "sv" | "sv-fi" | "sv-se" | "sw" | "sw-tz" | "syr-sy" | "ta" | "ta-in" | "te" | "te-in" | "tg" | "th" | "th-th" | "ti" | "tk" | "tl" | "tn" | "to" | "tr" | "tr-tr" | "ts" | "tt" | "tt-ru" | "tw" | "ty" | "ug" | "uk" | "uk-ua" | "ur" | "ur-pk" | "uz" | "uz-cyrl-uz" | "uz-latn-uz" | "ve" | "vi" | "vi-vn" | "vo" | "wa" | "wo" | "xh" | "yi" | "yo" | "za" | "zh" | "zh-chs" | "zh-cht" | "zh-cn" | "zh-hk" | "zh-mo" | "zh-sg" | "zh-tw" | "zu" | "zu-za"
configuration-id
iFrame parameter, described above, must be supplied with a valid config ID (found from the CMS administration control panel)_[NB. URL parameters take priority over CMS settings.
The second step is to set-up the virtual products in our CMS. This includes setting product images (thumbnails and packshots), names, descriptions and also the colour calibrations of the products themselves. To access the CMS please goto the portal cms. For assistance with calibration please see our Portal Guide]_
The web-app allows for both dynamic control (actions) and real-time event reporting (events) to and from the parent host page.
To listen to all internal events from the iframe just add the following script to your page, which will subscribe to events from the iFrame:
// Add window event listener functions
if (window.addEventListener) {
window.addEventListener('load', handleForm, false);
window.addEventListener('message', handleMessage, false);
}
// Subscribe to events when iFrame has loaded
function handleForm() {
// Subscribe to events
var win = document.getElementById('facesdk').contentWindow;
win.postMessage(
'subscribe',
'https://holition-beauty-projects.holitionbeauty.com'
);
}
// Handle events messages
function handleMessage(e) {
if (e.origin !== 'https://holition-beauty-projects.holitionbeauty.com') {
return;
}
const event = e.data;
// [Respond to event messages here]
console.log(
`FaceSDK Event: component[${event.component}] type[${event.type}] data:`,
event.data
);
}
Upon subscription an event will be returned with the current SDK version number as follows:
interface Event {
version: string;
}
Event responses are JSON formated as follows:
interface Event {
component:
| 'shade_finder'
| 'face_scan'
| 'slider'
| 'photo'
| 'products'
| 'sdk'
| 'image_upload';
type:
| 'shade_finder_button_click'
| 'shade_result'
| 'shade_match'
| 'recommended_products'
| 'image_quality_completed'
| 'select_range'
| 'scan_progress'
| 'scan_results'
| 'scan_button_click'
| 'slider_button_click'
| 'slider_thumb_drag'
| 'close_photo_button_click'
| 'save_photo_button_click'
| 'photo_button_click'
| 'photo_captured'
| 'select_product'
| 'select_look'
| 'select_filter'
| 'initialised'
| 'face_tracked'
| 'camera_access'
| 'feed_error'
| 'critical_error'
| 'error'
| 'add_basket'
| 'info_view_all'
| 'info_view'
| 'info_close'
| 'info_button'
| 'image_select'
| 'live_launch'
| 'image_align_click'
| 'finish_image_align'
| 'static_launch'
| 'filtered_products'
| 'data_loaded'
| 'select_vtoggle'
| 'dwell_product'
| 'dwell_look'
| 'take_photo_launch'
| 'thumbnails_generated'
| 'loading_complete';
data: any | null;
}
All face-scan related events have event_component
set to face_scan
.
The result of the face scan
interface Event {
component: 'face_scan';
type: 'scan_results';
data: {
results: {
eyeColor: 'black' | 'blue' | 'brown' | 'green' | 'grey';
eyeShape: 'almond' | 'downturned' | 'rounded' | 'upturned';
eyebrowShape: 'high_arch' | 'straight' | 'thick';
faceShape: 'heart' | 'oval' | 'rounded' | 'square';
lipCoverage: 'full' | 'medium' | 'thin';
percentage: number;
skinTone: 'fair' | 'light' | 'light_medium' | 'medium' | 'medium_tan' | 'tan_deep' | 'deep' |
};
};
}
The progress of the face-scan
interface Event {
component: 'face_scan';
type: 'scan_progress';
data: {
progress: number;
};
}
User has started the face scan experience
interface Event {
component: 'face_scan';
type: 'scan_button_click';
data: null;
}
User has started the shade finder experience.
interface Event {
type: 'shade_finder_button_click';
component: 'shade_finder';
data: null;
}
User has started shade finder and image quality has detected a good quality frame.
interface Event {
type: 'image_quality_completed';
component: 'shade_finder';
data: null;
}
Image quality and shade finder have completed and the ai model has returned its prediction
interface Event {
type: 'shade_result';
component: 'shade_finder';
data: { itaValue: number };
}
Image quality and shade finder have completed and found a foundation match
interface Event {
type: 'shade_match';
component: 'shade_finder';
data: {
// List of ordered list of filtered products
products: [
{
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
}
];
// Index to matched product
match: number;
// Index to lighter matched product
lighter: number;
// Index to darker matched product
darker: number;
};
}
User completing the shade finder experience and has been recommended products
interface Event {
type: 'recommended_products';
component: 'shade_finder';
data: {
// User recommended multiple products
product: [
{
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
}
];
};
}
All slider related events have event_component
set to slider
.
User activating slider
interface Event {
component: 'slider';
type: 'slider_button_click';
data: {
enabled: boolean;
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
};
}
User sliding the slider
interface Event {
component: 'slider';
type: 'slider_thumb_drag';
data: {
// slider position (ranging from 0 - 1 | left - right)
position: number;
};
}
All photo related events have event_component
set to photo
.
User activating take-a-photo
interface Event {
component: 'photo';
type: 'photo_button_click';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
};
}
User closed photo display overlay
interface Event {
component: 'photo';
type: 'close_photo_button_click';
data: null;
}
User saved photo to device
interface Event {
component: 'photo';
type: 'save_photo_button_click';
data: null;
}
Photo captured
interface Event {
component: 'photo';
type: 'photo_captured';
data: base64;
}
User thumbnails were generated
interface Event {
component: 'photo';
type: 'thumbnails_generated';
data: {
images: [// List of 9 base64 images];
};
}
All product, range or look selection events have event_component
set to products
.
User selected a product
interface Event {
component: 'products';
type: 'select_product';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
};
}
User dwell time on selected product
interface Event {
component: 'products';
type: 'dwell_product';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
dwell: number;
};
}
User selected a range
interface Event {
component: 'products';
type: 'select_range';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
};
}
Filtered product list based on face-scan results
interface Event {
component: 'products';
type: 'filtered_products';
data: {
products: [];
};
}
User activated product info view
interface Event {
component: 'products';
type: 'info_view';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
};
}
User closed product info view
interface Event {
component: 'products';
type: 'info_close';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
};
}
Return to the virtual try on and view all products
interface Event {
component: 'products';
type: 'info_view_all';
data: null;
}
User chose to add current product to basket
interface Event {
component: 'products';
type: 'add_basket';
data: {
product: {
// Unique CMS ID
id: string;
status: 'active' | 'inactive';
schema: {};
set: {};
group: {};
meta: {};
region: {};
data: {};
rendering: {};
};
};
}
User selected a product filter
interface Event {
component: 'products';
type: 'select_filter';
data: {
filter:
| 'blusher'
| 'bronzer'
| 'lipstick'
| 'lipliner'
| 'eyeshadow'
| 'eyeliner'
| 'foundation'
| 'concealer'
| 'eyebrow'
| 'masacara';
};
}
User selected to toggle between product and looks
interface Event {
component: 'products';
type: 'select_vtoggle';
data: {
vtoggle: 'products' | 'looks';
};
}
All product, range or look selection events have event_component
set to products
.
User activated look info view
interface Event {
component: 'products';
type: 'info_view';
data: {
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
};
}
User closed look info view
interface Event {
component: 'products';
type: 'info_close';
data: {
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
};
}
User chose to add current look to basket
interface Event {
component: 'products';
type: 'add_basket';
data: {
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
}
User selected a look
interface Event {
component: 'products';
type: 'select_look';
data: {
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
};
}
User dwell time for selected look
interface Event {
component: 'products';
type: 'dwell_look';
data: {
look: {
self: {
// Unique CMS ID for look
id: string;
schema: {};
set: {};
group: {};
meta: {};
region: {};
status: 'active' | 'inactive';
data: {};
rendering: {};
};
// List of products included in look
products: [];
};
dwell: number;
};
}
All SDK related events have event_component
set to sdk
.
SDK has initialised
interface Event {
component: 'sdk';
type: 'initialised';
data: {
status: boolean;
};
}
User face detected and tracked
interface Event {
component: 'sdk';
type: 'face_tracked';
data: {
status: boolean;
};
}
Has user camera access been aquired
interface Event {
component: 'sdk';
type: 'camera_access';
data: {
status: boolean;
};
}
Camera has failed to start correctly
interface Event {
component: 'sdk';
type: 'feed_error';
data: null;
}
All internal FaceSDK errors - see SDK docuementation for more information
interface Event {
component: 'sdk';
type: 'error';
data: {
error: any;
};
}
FaceSDK has experienced a critical error relating to hardware/browser incompatability.
interface Event {
component: 'sdk';
type: 'critical_error';
data: {
error: any;
};
}
General information button clicked
interface Event {
component: 'sdk';
type: 'info_button';
data: null;
}
All image upload related events have event_component
set to image_upload
.
User asked to select an image to upload
interface Event {
component: 'image_upload';
type: 'image_select';
data: null;
}
SDK was launched with live camera view
interface Event {
component: 'image_upload';
type: 'live_launch';
data: null;
}
SDK was launched to take a photo
interface Event {
component: 'image_upload';
type: 'take_photo_launch';
data: null;
}
User clicked to button to align uploaded image (scale | flip | rotate)
interface Event {
component: 'image_upload';
type: 'image_align_click';
data: {
scale: number;
flipV: boolean;
flipH: boolean;
rotate: number;
};
}
User has finished aligning the image
interface Event {
component: 'image_upload';
type: 'finish_image_align';
data: null;
}
SDK was launched with a static image
interface Event {
component: 'image_upload';
type: 'static_launch';
data: null;
}
FaceSDK has loaded product data correctly
interface Event {
component: 'sdk';
data: null;
type: 'data_loaded';
}
FaceSDK has completed loading code and aquired camera
interface Event {
component: 'sdk';
data: null;
type: 'loading_complete';
}
The iframe can be remotely controlled by sending actions in to it.
interface Action {
command: string;
data: any | null;
}
Send the below action to set the active product
interface Action {
command: 'set_product';
data: {
id: string;
idType:
| 'cms-id'
| 'SKU'
| 'EAN'
| 'UPC'
| 'GTIN'
| 'ASIN'
| 'Shade'
| 'Range'
| 'Other';
secondary: boolean; // optional
};
}
Example:
// Set active product
function setProduct(productId, idType) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_product',
data: {
id: productId,
idType: idType,
secondary: false,
},
});
}
Send the below action to set the active product via product variant id
interface Action {
command: 'set_product_variant';
data: {
id: string;
region: 'us' | 'eu';
secondary: boolean; // optional
};
}
Example:
// Set active product by variant id
function setProductVariant(productId, regionType) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_product_variant',
data: {
id: productId,
region: regionType,
secondary: false,
},
});
}
Send the below action to set the active look
interface Action {
command: 'set_look';
data: {
id: string;
secondary: boolean; // optional
};
}
Example:
// Set active look
function setLook(lookId) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_look',
data: {
id: lookId,
secondary: false,
},
});
}
Send the below action to build a look from a set of products
type IdentifierType =
| 'cms-id'
| 'sku'
| 'ean'
| 'upc'
| 'gtin'
| 'asin'
| 'shade'
| 'range'
| 'other';
interface ItemIdentifier {
readonly type: IdentifierType;
readonly value: string;
}
interface Action {
command: 'build_look';
data: {
ids: ItemIdentifier[];
secondary: boolean; // optional
};
}
Example:
// Set dynamic look
function buildLook(items: ItemIdentifier[]) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'build_look',
data: {
ids: items,
secondary: false,
},
});
}
Request picture be taken
interface Action {
command: 'take_picture';
data: {};
}
Example:
// Take picture
function takePicture() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'take_picture',
data: {},
});
}
Request SDK stop processing and go into idle state
interface Action {
command: 'pause';
data: {};
}
Example:
// Pause SDK
function pauseSDK() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'pause',
data: {},
});
}
Request SDK restart processing and leave idle state
interface Action {
command: 'play';
data: {};
}
Example:
// PLay SDK
function playSDK() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'play',
data: {},
});
}
Request SDK start using live camera feed
interface Action {
command: 'set_camera';
data: {};
}
Example:
// Set to live camera
function liveCamera() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_camera',
data: {},
});
}
Change applied foundation thickness. Thickness value ranges from -1 to 1, such that -1 is no foundation and 1 is maximum product thickness. A thickness of 0.0 equates to the original calibrated foundation product thickness
interface Action {
command: 'set_foundation_thickness';
data: {
thickness: number;
secondary: boolean; // optional
};
}
Example:
// Set currently applied foundation thickness
function setFoundation(thickness) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_foundation_thickness',
data: {
thickness: thickness,
secondary: false,
},
});
}
Change applied mascara mask. The mask is provided as a URL to an mask image
interface Action {
command: 'set_mascara_mask';
data: {
mask: string;
secondary: boolean; // optional
};
}
Example:
// Set currently applied mascara mask
function setMascaraMask(mask) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_mascara_mask',
data: {
mask: mask,
secondary: false,
},
});
}
Request SDK start shade-finder
interface Action {
command: 'shade_finder';
data: [
// List of strings to filter CMS foundation catalogue
// * If enpty [] all foundation products are included
// * Filtering based on custom Auxiliary field in CMS named "Product Line"
// * Not case sensitive
'example'
];
}
Example:
// Start shade-finder
function shadeFinder() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'shade_finder',
data: ['Example Foundation Line Name'],
});
}
Request SDK start face-scan
interface Action {
command: 'scan_start';
data: {};
}
Example:
// Start face-scan
function startScan() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'scan_start',
data: {},
});
}
Request SDK stop face-scan
interface Action {
command: 'scan_stop';
data: {};
}
Example:
// Stop face-scan
function stopScan() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'scan_stop',
data: {},
});
}
Colour tint the output visualisation
interface Action {
command: 'set_tint';
data: {
tint: {
colour: {
red: number; // 0-255
green: number; // 0-255
blue: number; // 0-255
};
intensity: number; // 0-1
};
};
}
Example:
// Tint output colour
function colourTint() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_tint',
data: {
tint: {
colour: {
red: 255,
green: 0,
blue: 0,
},
intensity: 0.2,
},
},
});
}
Resets state of experience to the static start options
interface Action {
command: 'reset_static_start';
data: {}
};
}
Example:
// Reset static start
function resetStaticStart() {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'reset_static_start',
data: {},
});
}
Generates 9 swatches using users image and 90 different look
type IdentifierType =
| 'cms-id'
| 'sku'
| 'ean'
| 'upc'
| 'gtin'
| 'asin'
| 'shade'
| 'range'
| 'other';
interface ItemIdentifier {
readonly type: IdentifierType;
readonly value: string;
}
interface Action {
command: 'set_thumbnail';
data: {
products: [
ItemIdentifier[];
];
};
}
Example:
// Generate Thumbnails
function generateThumbnails(products: [ItemIdentifier[]]) {
var win = document.getElementById('facesdk').contentWindow;
const sendToFaceSdk = (action) =>
win.postMessage(
JSON.stringify(action),
'https://holition-beauty-projects.holitionbeauty.com'
);
sendToFaceSdk({
command: 'set_thumbnail',
data: {
products: products,
},
});
}