@chateleon/sdk-public
Version:
Chateleon sdk public packages
370 lines (321 loc) • 13.5 kB
JavaScript
(function (win, doc) {
const loadCustomScript = function (config) {
(function (win, d, t, s, obj, oe, st) {
win['chateleonCustomObject'] = obj;
oe = d.createElement(t);
st = d.getElementsByTagName('script')[0];
oe.async = 1;
oe.src = s;
oe.id = "chateleon-custom-script"
st.parentNode.insertBefore(oe, st);
})(window, document, 'script', config.filePath, 'chateleonCustom');
var customScript = document.querySelector('#chateleon-custom-script');
customScript.addEventListener('load', function () {
ChateleonCustom(config);
});
}
const Chateleon = function (params) {
let chameleonContainer = document.getElementById('chameleon-anim-image');
let chateleonContainer = document.createElement('div');
chateleonContainer.id = ['chateleon-container', params.id].join('-') ? ['chateleon-container', params.id].join('-') : 'chateleon-container';
// chateleonContainer.className = 'justify-end w-2/4 left-2/3';
const config = {
id: params.id,
apiId: params.apiId,
event: params.event,
iframeData: params.iframeData || null,
isCustom: params.isCustom || false,
filePath: params.path,
customImpl: params.customImpl
};
if (config.isCustom) {
loadCustomScript(config);
return {
subscribe: () => { },
unsubscribe: () => { }
};
}
const BASE_URL = "https://sdk-api.qa.chateleon.com";
const SERVE_PATH = "/serve";
const TRACK_SERVE_PATH = "/track/serve";
const TRACK_INTERACTION_PATH = "/track/interaction";
const TOKEN_HEADER_NAME = "x-api-key";
var MASCOT_CONTAINER_ID = config.id ? ["chateleon-container", config.id].join("-") : "chateleon-container";
var mascotContainer;
let gif;
console.info("Chatleon SDK loaded");
const subscribe = function (callback) {
if (config.isCustom) {
console.warn("The method subscribe is not allowed here. Please use it inside the custom file.");
return;
}
var that = this;
switch (config.event) {
case "move":
moveGif(config.apiId, MASCOT_CONTAINER_ID)
break;
case "create":
// Do an API call with the key and validate
var xhr = new XMLHttpRequest();
xhr.withCredentials = true; // to send cookies
xhr.open('POST', BASE_URL + SERVE_PATH, true);
xhr.setRequestHeader(TOKEN_HEADER_NAME, config.apiId);
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (this.readyState === XMLHttpRequest.DONE) {
// Request finished. Do processing here.
if (this.status === 200) {
var responseData = JSON.parse(this.responseText);
var gifs = responseData.data.gifs;
if (params.animationType === 'multiple') {
for (let i = 0; i < params.meta.length; i++) {
let MASCOT = params.meta[i];
let MASCOT_CONTAINER_ID = params.meta[i].id ? params.meta[i].id : config.id;
let DURATION = params.meta[i].duration ? params.meta[i].duration : null;
MASCOT.id = MASCOT.id ? MASCOT.id : "mascot";
var responseData = JSON.parse(this.responseText);
var gifs = responseData.data.gifs;
if (gifs.length) {
if (config.customImpl) {
config.customImpl(gifs[i], MASCOT_CONTAINER_ID, trackEvent);
} else {
animation(gifs, MASCOT, DURATION);
}
trackServe()
console.log(
'Subscribed the ' + `${MASCOT.id}` + " " + MASCOT.order + '!!!'
)
}
}
return callback(mascotContainer, that)
} else {
var gifBasedOnCurrentTime = gifs.filter(filterGifOnCurrentTime);
if (gifBasedOnCurrentTime.length) {
if (config.customImpl) {
config.customImpl(gifBasedOnCurrentTime[0], MASCOT_CONTAINER_ID, trackEvent);
} else {
mascotContainer = createMascotContainer(gifs[0], MASCOT_CONTAINER_ID, config.iframeData);
}
trackServe();
console.log("Subscribed the mascot!!!");
return callback(mascotContainer, that);
}
}
} else {
console.warn("Chateleon Warning: Invalid API Key")
}
}
};
xhr.send();
// Get the user Gif pack and store it locally
break;
default:
console.warn("Chateleon Warning : Invalid event " + config.event);
}
};
const unsubscribe = function () {
const container = doc.getElementById(MASCOT_CONTAINER_ID);
container.remove();
console.log("Unsubscribed the mascot!!!");
};
const filterGifOnCurrentTime = function (_gif) {
var date = new Date();
var hour = date.getHours();
var minute = date.getMinutes();
var settings = _gif.settings;
var startTime = settings.startTime;
var endTime = settings.endTime;
var startHourMin = startTime.split(":");
var endHourMin = endTime.split(":");
if (_gif.active && (hour >= parseInt(startHourMin[0]) && hour <= parseInt(endHourMin[0])) && (minute >= parseInt(startHourMin[1]) && minute <= parseInt(endHourMin[1]))) {
return _gif;
}
};
const animation = function (gifs, MASCOT, DURATION) {
MASCOT.id = MASCOT.id ? MASCOT.id : "mascot";
let mascotId = `${MASCOT.id}` + MASCOT.order;
let Gifs;
const mascotUrlMap = {};
for (var i = 0; i < gifs.length; i++) {
mascotUrlMap[`${MASCOT.id}${i + 1}`] = gifs[i].original;
};
const metaList = params.meta;
for (var meta of metaList) {
var url = mascotUrlMap[`${mascotId}`];
meta.url = url;
};
const GifUrl = [];
GifUrl.push(MASCOT.url);
for (var i = 0; i < metaList.length; i++) {
Gifs = GifUrl.map(url => {
const img = new Image();
img.src = metaList[i].url;
return img;
});
};
const gifPromises = Gifs.map(gif => new Promise(resolve => {
gif.onload = () => {
resolve();
};
}));
Promise.all(gifPromises).then(() => {
var start = new Date().getTime(),
time = 0;
function instance() {
time += 10;
var diff = new Date().getTime() - start - time;
let timeout = window.setTimeout(instance, 100 - diff);
mascotContainer = animate(MASCOT, gifs, params);
clearTimeout(timeout);
}
setTimeout(instance, DURATION);
});
};
const animate = function (mascot, gifs, configs) {
mascot.id = mascot.id ? mascot.id : "mascot";
let mascotId = `${mascot.id}` + mascot.order;
let END_DURATION = mascot.endDuration ? mascot.endDuration : null;
const mascotUrlMap = {};
for (var i = 0; i < gifs.length; i++) {
mascotUrlMap[`${mascot.id}${i + 1}`] = gifs[i].original;
};
const metaList = configs.meta;
for (var meta of metaList) {
var url = mascotUrlMap[`${mascotId}`];
meta.url = url;
};
let img = document.createElement('img');
img.id = mascotId;
img.setAttribute('src', mascot.url);
img.onload = () => {
img.setAttribute('loading', "lazy");
img.setAttribute('alt', 'chameleon');
img.onmouseover = trackEvent;
img.onclick = trackEvent;
// img.className = 'h-64 w-full';
img.style.position = configs.position.type ? configs.position.type : 'absolute';
img.style.height = mascot.dimensions.height ? mascot.dimensions.height : 100 + '%';
img.style.width = mascot.dimensions.width ? mascot.dimensions.width : 100 + '%';
img.style.zIndex = mascot.dimensions.zIndex ? mascot.dimensions.zIndex : 500;
img.style.position = mascot.position.type ? mascot.position.type : 'absolute';
img.style.bottom = mascot.position.bottom ? mascot.position.bottom : 0 + '%';
img.style.right = mascot.position.right ? mascot.position.right : 0 + '%';
// chateleonContainer.style.cssText = 'position:absolute;width:300px;z-index:100;bottom:300; right: 300;';
chateleonContainer.style.position = configs.position.type ? configs.position.type : 'absolute';
chateleonContainer.style.right = configs.position.right ? configs.position.right : 50 + '%';
chateleonContainer.style.bottom = configs.position.bottom ? configs.position.bottom : 50 + '%';
chateleonContainer.style.width = configs.dimensions.width ? configs.dimensions.width : 300 + 'px';
chateleonContainer.style.height = configs.dimensions.height ? configs.dimensions.height : 180 + 'px';
chateleonContainer.style.zIndex = mascot.dimensions.zIndex ? mascot.dimensions.zIndex : 500;
// doc.body.appendChild(chateleonContainer)
chameleonContainer.appendChild(chateleonContainer);
chateleonContainer.appendChild(img);
if (params.animationType === "multiple") {
if (mascot.isLoop === false) {
gif = document.getElementById(mascotId);
} else {
if (gif) {
gif.parentNode.removeChild(gif);
}
};
};
};
};
const createMascotContainer = function (filteredGif, id, data) {
var elem = document.createElement("img");
elem.setAttribute("src", filteredGif.original);
elem.setAttribute("width", "100%");
elem.onmouseover = trackEvent;
elem.onclick = trackEvent
elem.style.cssText = 'width:300px;z-index:100;';
// elemDiv.appendChild(elem);
if (data) {
if (data.targetIframe) {
var iframe = document.getElementById(data.targetIframe);
var target = iframe.contentDocument.querySelector(data.targetContainer);
if (data.prepend) {
target.prepend(elem);
} else {
target.append(elem);
}
}
else if (data.targetContainer) {
var target = document.querySelector(data.targetContainer);
if (data.prepend) {
target.prepend(elem);
} else {
target.append(elem);
}
}
} else {
var elemDiv = doc.createElement('div');
elemDiv.id = id;
// data.size ? elemDiv.style.height = data.size : null;
elemDiv.style.cssText = 'position:absolute;width:300px;z-index:100;bottom:300; right: 300;';
doc.body.appendChild(elemDiv);
elemDiv.appendChild(elem);
}
return elemDiv;
};
const trackServe = function () {
var xhr = new XMLHttpRequest();
xhr.withCredentials = true; // to send cookies
xhr.open('POST', BASE_URL + TRACK_SERVE_PATH, true);
xhr.setRequestHeader(TOKEN_HEADER_NAME, config.apiId);
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (this.readyState === XMLHttpRequest.DONE) {
// Request finished. Do processing here.
if (this.status === 200) {
} else {
console.warn("Chateleon Warning: Invalid API Key")
}
}
}
xhr.send();
};
const trackInteraction = function (eventData) {
var xhr = new XMLHttpRequest();
xhr.withCredentials = true; // to send cookies
xhr.open('POST', BASE_URL + TRACK_INTERACTION_PATH, true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.setRequestHeader(TOKEN_HEADER_NAME, config.apiId);
xhr.onreadystatechange = function () { // Call a function when the state changes.
if (this.readyState === XMLHttpRequest.DONE) {
// Request finished. Do processing here.
if (this.status === 200) {
// debugger;
} else {
console.warn("Chateleon Warning: Invalid API Key")
}
}
}
xhr.send(JSON.stringify({
eventData: {
type: eventData.type
}
}));
};
const moveGif = function (data, id) {
var gifContainer = doc.querySelector("#" + id);
// TODO: Data validation pending
data.cssText ? gifContainer.style.cssText = data.cssText : null;
data.top ? gifContainer.style.top = data.top : null;
data.left ? gifContainer.style.left = data.left : null
data.bottom ? gifContainer.style.bottom = data.bottom : null;
data.right ? gifContainer.style.right = data.right : null;
data.zIndex ? gifContainer.style.zIndex = data.zIndex : null;
data.width ? gifContainer.style.width = data.width : null;
data.visibility ? gifContainer.style.visibility = data.visibility : null;
};
const trackEvent = function (event) {
console.info("Trackevent function");
console.log(event);
// Do an API call and store the tracking information
trackInteraction(event)
};
return {
subscribe: subscribe,
unsubscribe: unsubscribe
};
};
win.Chateleon = Chateleon;
})(window, document)