Skip to content

Instantly share code, notes, and snippets.

@talha08
Created October 16, 2019 12:58
Show Gist options
  • Save talha08/90855bb0496db22f4d897966e4841c69 to your computer and use it in GitHub Desktop.
Save talha08/90855bb0496db22f4d897966e4841c69 to your computer and use it in GitHub Desktop.
/**
* Created by Usman on 17/11/14.
* video ad with ability to split into two portions horizontally
*/
Function.prototype.bind = Function.prototype.bind || function(b) {
// Polyfill from https://gist.github.com/dsingleton/1312328
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var a = Array.prototype.slice, f = a.call(arguments, 1), e = this, c = function() {
}, d = function() {
return e.apply(this instanceof c ? this : b || window, f.concat(a.call(arguments)));
};
c.prototype = this.prototype;
d.prototype = new c();
return d;
};
(function(wisp, undefined) {
'use strict';
/**
* @param {Object} input
* @constructor
*/
function videoAd(input) {
this.debug = !!(typeof input.debug !== "undefined" && (input.debug).toString() === "true");
this.log("Debug enabled: "+ this.debug );
this.helper = typeof input.helper != "undefined" ? input.helper : null;
this.log("WSHelper: "+ this.helper);
if(this.helper == null) {
console.log("Helper not defined........... return;");
return;
}
this.random = input.random;
this.log("Random Number: "+ this.random);
this.video = typeof input.video != "undefined" ? {} : false;
if(this.video) {
this.video.splitVideo = !!(typeof input.video.splitVideo != "undefined" && (input.video.splitVideo).toString() === "true");
this.log("Split video is: "+ this.video.splitVideo);
this.video.src = typeof input.video.src != "undefined" ? input.video.src : null;
this.log("Video src: "+ this.video.src );
this.video.closeButton = !!(typeof input.video.closeButton != "undefined" && (input.video.closeButton).toString() === "true");
this.log("Video Close Button: "+ this.video.closeButton);
this.video.controls = !!(typeof input.video.controls != "undefined" && (input.video.controls).toString() === "true");
this.log("Video Controls: "+ this.video.controls );
this.video.position = typeof input.video.position != "undefined" && (input.video.position == "top" || input.video.position == "bottom") ? input.video.position : "top";
this.log("Video Position: "+ this.video.position );
}
this.log("Video Parameter defined: "+ JSON.stringify(this.video));
this.playIconUrl = typeof input.playIconUrl != "undefined" ? input.playIconUrl : "#";
this.log("Play Icon url: "+ this.playIconUrl);
this.dynamicBanners = typeof input.dynamicBanners != "undefined" ? input.dynamicBanners : false;
this.log("Dynamic Banner defined: "+ JSON.stringify(this.dynamicBanners));
this.dynamicBannerBG = typeof input.dynamicBannerBG != "undefined" ? input.dynamicBannerBG : "rgba(0,0,0,1)";
this.log("dynamicBannerBG: "+ this.dynamicBannerBG );
this.overridePlayIconHeight = !!(typeof input.overridePlayIconHeight != "undefined" && (input.overridePlayIconHeight).toString() === "true");
this.log("OverridePlayIconHeight: "+ this.overridePlayIconHeight );
this.events = {
"click": [], // click anywhere in ad with container name as return
"show": [] // when ad displayed, triggered once
};
// transition css parameters
this.startBannerTransition = {};
this.startBannerTransition.lengthOfAnim = typeof input.startBannerTransition !="undefined" && typeof input.startBannerTransition.lengthOfAnim !="undefined" ? input.startBannerTransition.lengthOfAnim : 5;
this.startBannerTransition.lengthOfTransition = typeof input.startBannerTransition !="undefined" && typeof input.startBannerTransition.lengthOfTransition !="undefined" ? input.startBannerTransition.lengthOfTransition : 0.4;
this.startBannerTransition.scaleValue = typeof input.startBannerTransition !="undefined" && typeof input.startBannerTransition.scaleValue !="undefined" ? input.startBannerTransition.scaleValue : 1.1;
this.startBannerTransition.cssClassPrefix = typeof input.startBannerTransition !="undefined" && typeof input.startBannerTransition.cssClassPrefix !="undefined" ? input.startBannerTransition.cssClassPrefix : "";
// Elements ref.
this.adContainer = this.helper.getAdContainer();
this.closeButtonContainer = input.closeButtonContainer || document.getElementById("wsCloseButton"+this.random);
this.startBannerContainer = input.startBannerContainer || document.getElementById("wsStartBanner"+this.random);
this.playIconContainer = input.playIconContainer || document.getElementById("wsPlayIcon"+this.random);
this.dynamicBannerContainer = input.dynamicBannerContainer || document.getElementById("wsDynamicBanners"+this.random);
this.endBannerContainer = input.endBannerContainer || document.getElementById("wsEndBanner"+this.random);
this.init();
}
videoAd.prototype.init = function() {
this.setStyling();
this.setDynamicBanners(this.dynamicBannerContainer);
this.clickHandler(this.startBannerContainer, "START_BANNER");
this.clickHandler(this.playIconContainer, "PLAY_BANNER");
this.clickHandler(this.endBannerContainer, "END_BANNER");
this.closeButtonHandler(this.closeButtonContainer);
this.show();
};
/**
* set necessary styling of each container
*/
videoAd.prototype.setStyling = function() {
this.log("Starting setStyling");
this.adContainer.style.width = this.helper.getSize().width+"px";
this.adContainer.style.height = this.helper.getSize().height+"px";
this.adContainer.style.cssText += "display:none; position:relative; margin:0 auto; padding:0; overflow:hidden; z-index:998;";
this.playIconContainer.style.background = "url('"+this.playIconUrl+"') no-repeat center";
this.playIconContainer.style.cssText += "position:absolute;width:100%; margin: 0 auto; padding: 0; overflow: hidden; z-index: 997;";
this.playIconContainer.style[this.video.position] = 0;
this.playIconContainer.style.height = this.video.splitVideo && !this.overridePlayIconHeight ? "50%" : "100%";
if(this.startBannerContainer) {
this.startBannerContainer.style.height = this.video.splitVideo ? "50%" : "100%";
this.startBannerContainer.style[this.video.position === "top" ? "bottom" : "top"] = 0;
this.startBannerContainer.style.cssText += "position:absolute; width:100%; z-index: 996;";
}
this.dynamicBannerContainer.style.height = this.video.splitVideo ? "50%" : "100%";
this.dynamicBannerContainer.style[this.video.position] = 0;
this.dynamicBannerContainer.style.cssText += "position:absolute; width:100%; z-index: 996; overflow: hidden";
this.dynamicBannerContainer.style.setProperty("background", this.dynamicBannerBG, "important");
this.endBannerContainer.style.cssText += "position:absolute; left:0; top:0; width:100%; height:100%; overflow: hidden; z-index: 994;padding: 0;";
this.log("Finish setStyling");
};
/**
* Append dynamic banners in container and set its css transition styling
*
* @param {HTMLElement} elem
*/
videoAd.prototype.setDynamicBanners = function(elem) {
var container = elem || this.dynamicBannerContainer;
if(!container) return;
this.setBannersTransitionCSS(container);
this.log("Setting dynamic banner(s)...");
for (var i = 0; i < this.dynamicBanners.length; i++) {
var elemClass = "ws_zoom_fade_"+this.random+"_"+(i+1);
var currentElem = null;
this.log(JSON.stringify(this.dynamicBanners[i]) +"Started");
if (this.dynamicBanners[i].elementId) {
currentElem = document.getElementById(this.dynamicBanners[i].elementId);
currentElem.className = elemClass;
currentElem.onload = function() {
this.style.width = this.width+"px";
this.style.height = this.height+"px";
}
this.log("Html Element as dynamic banner");
}
else if (this.dynamicBanners[i].imageSrc) {
currentElem = new Image();
currentElem.onload = function() {
this.style.width = "100%";
this.style.height = "auto";
}
currentElem.src = this.dynamicBanners[i].imageSrc;
currentElem.className = elemClass;
this.log("Image as dynamic banner");
}
else {
this.log("Start element "+(i+1)+" is null");
}
if(currentElem)
currentElem.style.cssText += "position: absolute; left:0; top:0";
container.appendChild(currentElem);
this.log("Dynamic banner "+(i+1)+" appended to container");
}
};
videoAd.prototype.setBannersTransitionCSS = function(elem) {
var container = elem || this.dynamicBannerContainer;
if(!container) return;
this.startBannerTransition.totalElements = this.dynamicBanners && this.dynamicBanners.length ? this.dynamicBanners.length : 0;
this.startBannerTransition.appendTo = container;
if(this.startBannerTransition.totalElements < 2) return;
this.helper.setBannersTransitionCSS(this.startBannerTransition);
};
/**
* Listen to click events of 3 containers and dispatch videoAd click event
*
* @param {HTMLElement} element
* @param {string} value to return
*/
videoAd.prototype.clickHandler = function(element, value) {
if(!element) return;
var that = this;
this.log("Starting clickHandler on "+ element.id);
element.addEventListener("click", function() {
that.dispatch("click", value);
that.log("CLICK dispatched with value: "+value);
if(element === that.playIconContainer) that.playVideo();
}, false);
this.log("Finish clickHandler on "+ element.id);
};
/**
* Plays video using helper.playVideo
*/
videoAd.prototype.playVideo = function() {
var videoOptions = {
controls: this.video.controls,
closeButton: this.video.closeButton,
attr: ['playsinline']
};
this.helper.playVideo(this.video.src, videoOptions);
this.log("Helper play video triggered");
var that = this;
setTimeout(function(){
that.hideElement(that.playIconContainer);
that.hideElement(that.dynamicBannerContainer);
that.hideElement(that.startBannerContainer);
}, 500);
};
/**
* will hide element
* @param {HTMLElement} elem
*/
videoAd.prototype.hideElement = function(elem) {
if (!elem) return;
elem.style.display = "none";
elem.style.visibility = "hidden";
this.log(elem.id +" hided");
};
/**
* will use console.log only if this.debug is true
* @param {string} message
*/
videoAd.prototype.log = function(message) {
if (this.debug && window.console) {
console.log(message);
}
};
/**
* Close ad when click on close
*
* @param {HTMLElement} elem
*/
videoAd.prototype.closeButtonHandler = function(elem) {
var closeButton = elem || this.closeButtonContainer;
if(!closeButton) return;
var that = this;
closeButton.addEventListener("click", function(e) {
that.helper.close(e);
that.log("Ad hided");
});
};
/**
* Dispatch show and display adContainer
*
* @param {string} event - The event.
* @param {Function} callback - callback function that will be triggered on the event.
*/
videoAd.prototype.show = function(elem) {
var adContainer = elem || this.adContainer;
this.adLoaded = this.adLoaded || false;
if(this.adLoaded || !adContainer) return;
this.adLoaded = true;
this.dispatch("show", adContainer);
adContainer.style.display = "block";
this.helper.bindLinkClicks(adContainer);
this.log("SHOW dispatched");
};
/**
* Add a event listeners.
*
* @param {string} event - the event type, that must be in events objects.
* @param {Function} callback - The callback function that will be triggered by the Dispatcher method on an event.
* @return {boolean} - returns false and exit the metod when the event dosent exists in event object.
*/
videoAd.prototype.addEventListener = function(event, callback) {
if (!this.events.hasOwnProperty(event)) {
return;
}
this.events[event].push(callback);
};
/**
* Removes a event listener.
*
* @param {string} event - the event type that will be remeved.
* @param {Function} callback - The callback function that will be removed.
* @return {boolean} - returns false and exit the metod when the event dosent exists in event object.
*/
videoAd.prototype.removeEventListener = function(event, callback) {
if (this.events.hasOwnProperty(event)) {
return;
}
// Find the function in the event and remove is callback function from the events array.
for (var i = 0; i < this.events[event].length; i++) {
if (this.events[event][i] === callback) {
this.events[event].splice(i, 1);
}
}
};
/**
* Event listener dispatch / trigger method.
*
* @param {string} event - The event.
* @param {Function} callback - callback function that will be triggered on the event.
*/
videoAd.prototype.dispatch = function(event, callback) {
for (var i = 0; i < this.events[event].length; i++) {
this.events[event][i](callback);
}
};
/**
* @namespace
*/
wisp.ad = wisp.ad || {};
/**
* Constructor for the video ad.
*
* @constructor
* @param {Object} input
*/
wisp.ad.videoAd = function wispVideoAdConstructor(input) {
var wispVideoAd = new videoAd(input);
this.addEventListener = wispVideoAd.addEventListener.bind(wispVideoAd);
this.removeEventListener = wispVideoAd.removeEventListener.bind(wispVideoAd);
};
}(window.wisp = window.wisp || {}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment