"use strict"; (function(factory){ // AMD if(typeof define === 'function' && define.amd) { define(['jquery', './jquery.enjoyhint.js', 'jquery.scrollto'], factory); } // CommonJS else if (typeof require === 'function' && typeof exports === 'object') { module.exports = factory(require('jquery'), require('./jquery.enjoyhint.js'), require('jquery.scrollto')); } // Global else { window.EnjoyHint = factory(jQuery) } })(function($){ var EnjoyHint = function(configs) { var $event_element; var that = this; var _options = configs || {}; var BTN_NEXT_TEXT = _options.btnNextText; var BTN_SKIP_TEXT = _options.btnSkipText; var SHAPE_BACKGROUND_COLOR = _options.backgroundColor || "rgba(0,0,0,0.6)"; var body = "body"; // TODO: Is it possible case when we need to define enjoyhint somewhere else? var defaults = { onStart: function() {}, onEnd: function() {}, onSkip: function() {}, onNext: function() {} }; var options = $.extend(defaults, _options); var data = []; var current_step = 0; var $body = $(body); /********************* PRIVATE METHODS ***************************************/ var init = function() { if ($(".enjoyhint")) { $(".enjoyhint").remove(); } $body.css({ overflow: "hidden" }); $(document).on("touchmove", lockTouch); $body.enjoyhint({ onResetClick: function(){ resetStep(); }, onNextClick: function() { nextStep(); }, onPrevClick: function(){ prevStep(); }, onSkipClick: function() { options.onSkip(); skipAll(); }, fill: SHAPE_BACKGROUND_COLOR }); }; var lockTouch = function(e) { e.preventDefault(); }; var destroyEnjoy = function() { $(".enjoyhint").remove(); $body.css({ overflow: "auto" }); $(document).off("touchmove", lockTouch); }; that.clear = function() { var $nextBtn = $(".enjoyhint_next_btn"); var $skipBtn = $(".enjoyhint_skip_btn"); var $prevBtn = $(".enjoyhint_prev_btn"); var $resetBtn = $(".enjoyhint_reset_btn"); $prevBtn.removeClass(that.prevUserClass); $nextBtn.removeClass(that.nextUserClass); $nextBtn.text(BTN_NEXT_TEXT); $skipBtn.removeClass(that.skipUserClass); $skipBtn.text(BTN_SKIP_TEXT); }; function hideCurrentHint(){ $body.enjoyhint("render_circle", []); $("#enjoyhint_label").remove(); $("#enjoyhint_arrpw_line").remove(); $body.enjoyhint("hide_prev"); $body.enjoyhint("hide_next"); $body.enjoyhint("hide_skip"); }; var stepAction = function() { if (!(data && data[current_step])) { $body.enjoyhint("hide"); options.onEnd(); destroyEnjoy(); return; } options.onNext(); var $enjoyhint = $(".enjoyhint"); $enjoyhint.removeClass("enjoyhint-step-" + current_step); $enjoyhint.removeClass("enjoyhint-step-" + (current_step + 1)); $enjoyhint.removeClass("enjoyhint-step-" + (current_step + 2)); $enjoyhint.addClass("enjoyhint-step-" + (current_step + 1)); var step_data = data[current_step]; var scrollSpeed = step_data.scrollAnimationSpeed; if ( step_data.onBeforeStart && typeof step_data.onBeforeStart === "function" ) { step_data.onBeforeStart(); } var timeout = step_data.timeout || 0; setTimeout(function() { if (!step_data.selector) { for (var prop in step_data) { if (step_data.hasOwnProperty(prop) && prop.split(" ")[1]) { step_data.selector = prop.split(" ")[1]; step_data.event = prop.split(" ")[0]; if ( prop.split(" ")[0] == "next" || prop.split(" ")[0] == "auto" || prop.split(" ")[0] == "custom" ) { step_data.event_type = prop.split(" ")[0]; } step_data.description = step_data[prop]; } } } setTimeout(function() { that.clear(); }, 250); var isHintInViewport = $(step_data.selector).get(0).getBoundingClientRect(); if(isHintInViewport.top < 0 || isHintInViewport.bottom > (window.innerHeight || document.documentElement.clientHeight)){ hideCurrentHint(); $(document.body).scrollTo(step_data.selector, step_data.scrollAnimationSpeed || 250, {offset: -200}); } else { // if previous button has been clicked and element are in viewport to prevent custom step scrollAnimationSpeed set scrollSpeed to default scrollSpeed = 250; } setTimeout(function() { var $element = $(step_data.selector); var event = makeEventName(step_data.event); $body.enjoyhint("show"); $event_element = $element; if (step_data.event_selector) { $event_element = $(step_data.event_selector); } $event_element.off(event) $element.off("keydown"); if (!step_data.event_type && step_data.event == "key") { $element.keydown(function(event) { if (event.which == step_data.keyCode) { current_step++; stepAction(); } }); } if (step_data.showNext !== true) { $body.enjoyhint("hide_next"); } else { $body.enjoyhint("show_next"); } $body.enjoyhint("hide_prev"); if(current_step !== 0) { $body.enjoyhint("show_prev"); } if (step_data.showPrev == false) { $body.enjoyhint("hide_prev"); } if (step_data.showSkip == false) { $body.enjoyhint("hide_skip"); } else { $body.enjoyhint("show_skip"); } if (step_data.nextButton) { var $nextBtn = $(".enjoyhint_next_btn"); $nextBtn.addClass(step_data.nextButton.className || ""); $nextBtn.text(step_data.nextButton.text || "Next"); that.nextUserClass = step_data.nextButton.className; } if (step_data.prevButton) { var $prevBtn = $(".enjoyhint_prev_btn"); $prevBtn.addClass(step_data.prevButton.className || ""); $prevBtn.text(step_data.prevButton.text || "Previous"); that.prevUserClass = step_data.prevButton.className; } if (step_data.skipButton) { var $skipBtn = $(".enjoyhint_skip_btn"); $skipBtn.addClass(step_data.skipButton.className || ""); $skipBtn.text(step_data.skipButton.text || "Skip"); that.skipUserClass = step_data.skipButton.className; } if (step_data.event_type) { switch (step_data.event_type) { case "auto": $element[step_data.event](); switch (step_data.event) { case "click": break; } current_step++; stepAction(); return; case "custom": on(step_data.event, function() { current_step++; off(step_data.event); stepAction(); }); break; case "next": $body.enjoyhint("show_next"); break; } } else { $event_element.on(event, function(e) { if (step_data.keyCode && e.keyCode != step_data.keyCode) { return; } current_step++; stepAction(); // clicked }); } var max_habarites = Math.max( $element.outerWidth(), $element.outerHeight() ); var radius = step_data.radius || Math.round(max_habarites / 2) + 5; var offset = $element.offset(); var w = $element.outerWidth(); var h = $element.outerHeight(); var shape_margin = step_data.margin !== undefined ? step_data.margin : 10; var coords = { x: offset.left + Math.round(w / 2), y: offset.top + Math.round(h / 2) - $(document).scrollTop() }; var shape_data = { enjoyHintElementSelector: step_data.selector, center_x: coords.x, center_y: coords.y, text: step_data.description, arrowColor: step_data.arrowColor, top: step_data.top, bottom: step_data.bottom, left: step_data.left, right: step_data.right, margin: step_data.margin, scroll: step_data.scroll }; var customBtnProps = { nextButton: step_data.nextButton, prevButton: step_data.prevButton } if (shape_data.center_x === 0 && shape_data.center_y === 0) { $body.enjoyhint("hide"); destroyEnjoy(); return console.log("Error: Element position couldn't be reached"); } if (step_data.shape && step_data.shape == "circle") { shape_data.shape = "circle"; shape_data.radius = radius; } else { shape_data.radius = 0; shape_data.width = w + shape_margin; shape_data.height = h + shape_margin; } $body.enjoyhint("render_label_with_shape", shape_data, that.stop, customBtnProps); }, scrollSpeed + 20 || 270); }, timeout); }; var nextStep = function() { current_step++; stepAction(); }; var prevStep = function() { current_step--; stepAction(); }; var resetStep = function() { current_step = 0; stepAction(); }; var skipAll = function() { var step_data = data[current_step]; var $element = $(step_data.selector); off(step_data.event); $element.off(makeEventName(step_data.event)); destroyEnjoy(); }; var makeEventName = function(name, is_custom) { return name + (is_custom ? "custom" : "") + ".enjoy_hint"; }; var on = function(event_name, callback) { $body.on(makeEventName(event_name, true), callback); }; var off = function(event_name) { $body.off(makeEventName(event_name, true)); }; /********************* PUBLIC METHODS ***************************************/ window.addEventListener( "resize", function() { if ($event_element != null) { $body.enjoyhint( "redo_events_near_rect", $event_element[0].getBoundingClientRect() ); } }, false ); that.stop = function() { skipAll(); }; that.reRunScript = function(cs) { current_step = cs; stepAction(); }; that.runScript = function() { current_step = 0; options.onStart(); stepAction(); }; that.resumeScript = function() { stepAction(); }; that.setCurrentStep = function(cs) { current_step = cs; }; that.getCurrentStep = function() { return current_step; }; that.trigger = function(event_name) { switch (event_name) { case "next": nextStep(); break; case "skip": skipAll(); break; default: $body.trigger(makeEventName(event_name, true)); } }; that.setScript = function(_data) { if (!(_data instanceof Array) && _data.length < 1) { throw new Error("Configurations list isn't correct."); } data = _data; }; //support deprecated API methods /** * Configure data list */ that.set = function(_data) { that.setScript(_data); }; that.setSteps = function(_data) { that.setScript(_data); }; that.run = function() { that.runScript(); }; that.resume = function() { that.resumeScript(); }; init(); }; return EnjoyHint; }) ;CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) { if (w < 2 * r) r = w / 2; if (h < 2 * r) r = h / 2; this.beginPath(); this.moveTo(x + r, y); this.arcTo(x + w, y, x + w, y + h, r); this.arcTo(x + w, y + h, x, y + h, r); this.arcTo(x, y + h, x, y, r); this.arcTo(x, y, x + w, y, r); this.closePath(); return this; }; (function(factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // AMD define(['jquery', 'kinetic'], factory); } else if (typeof module !== 'undefined' && module.exports) { // CommonJS module.exports = factory(require('jquery'), require('kinetic')); } else { // Global factory(jQuery, Kinetic); } })(function($, Kinetic) { var that; var originalLabelLeft, originalLabelTop; var originalArrowLeft, originalArrowTop; var originalCenterX, originalCenterY; var originalSkipbuttonLeft, originalSkipbuttonTop; var prevWindowWidth, prevWindowHeight; var originalWidth = window.innerWidth, originalHeight = window.innerHeight; var methods = { init: function(options) { return this.each(function() { var defaults = { onNextClick: function() {}, onSkipClick: function() {}, onPrevClick: function() {}, animation_time: 800 }; this.enjoyhint_obj = {}; that = this.enjoyhint_obj; that.resetComponentStuff = function() { originalLabelLeft = null; originalLabelTop = null; originalArrowLeft = null; originalArrowTop = null; originalCenterX = null; originalCenterY = null; originalSkipbuttonLeft = null; originalSkipbuttonTop = null; prevWindowWidth = null; prevWindowHeight = null; originalWidth = window.innerWidth; originalHeight = window.innerHeight; }; var $that = $(this); that.options = $.extend(defaults, options); //general classes that.gcl = { chooser: "enjoyhint" }; // classes that.cl = { enjoy_hint: "enjoyhint", hide: "enjoyhint_hide", disable_events_element: "enjoyhint_disable_events", btn: "enjoyhint_btn", skip_btn: "enjoyhint_skip_btn", close_btn: "enjoyhint_close_btn", reset_btn: "enjoyhint_reset_btn", next_btn: "enjoyhint_next_btn", previous_btn: "enjoyhint_prev_btn", main_canvas: "enjoyhint_canvas", main_svg: "enjoyhint_svg", svg_wrapper: "enjoyhint_svg_wrapper", svg_transparent: "enjoyhint_svg_transparent", kinetic_container: "kinetic_container" }; function makeSVG(tag, attrs) { var el = document.createElementNS("http://www.w3.org/2000/svg", tag); for (var k in attrs) { el.setAttribute(k, attrs[k]); } return el; } // ======================================================================= // ========================---- enjoyhint ----============================== // ======================================================================= that.canvas_size = { w: $(window).width() * 1.4, h: $(window).height() * 1.4 }; var canvas_id = "enj_canvas"; that.enjoyhint = $("