Related
I would like to change the color of the menu letters.
However, some problems arise.
The problem is that when I enter this jquery code the menu gets all centered
https://imgur.com/4196CgN
The goal of this jquery is to change the color of the header when it arrives in another section by assigning it a class.
If the header is between two sections, above it takes the color of the previous section, and below it takes the color of the next section.
/*!
* Midnight.js 1.1.1
* jQuery plugin to switch between multiple fixed header designs on the fly, so it looks in line with the content below it.
* http://aerolab.github.io/midnight.js/
*
* Copyright (c) 2014 Aerolab <info#aerolab.co>
*
* Released under the MIT license
* http://aerolab.github.io/midnight.js/LICENSE.txt
*/
!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){var e=0,s=Array.prototype.slice;t.cleanData=function(e){return function(s){var i,n,o;for(o=0;null!=(n=s[o]);o++)try{i=t._data(n,"events"),i&&i.remove&&t(n).triggerHandler("remove")}catch(r){}e(s)}}(t.cleanData),t.widget=function(e,s,i){var n,o,r,a,h={},d=e.split(".")[0];return e=e.split(".")[1],n=d+"-"+e,i||(i=s,s=t.Widget),t.expr[":"][n.toLowerCase()]=function(e){return!!t.data(e,n)},t[d]=t[d]||{},o=t[d][e],r=t[d][e]=function(t,e){return this._createWidget?void(arguments.length&&this._createWidget(t,e)):new r(t,e)},t.extend(r,o,{version:i.version,_proto:t.extend({},i),_childConstructors:[]}),a=new s,a.options=t.widget.extend({},a.options),t.each(i,function(e,i){return t.isFunction(i)?void(h[e]=function(){var t=function(){return s.prototype[e].apply(this,arguments)},n=function(t){return s.prototype[e].apply(this,t)};return function(){var e,s=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=i.apply(this,arguments),this._super=s,this._superApply=o,e}}()):void(h[e]=i)}),r.prototype=t.widget.extend(a,{widgetEventPrefix:o?a.widgetEventPrefix||e:e},h,{constructor:r,namespace:d,widgetName:e,widgetFullName:n}),o?(t.each(o._childConstructors,function(e,s){var i=s.prototype;t.widget(i.namespace+"."+i.widgetName,r,s._proto)}),delete o._childConstructors):s._childConstructors.push(r),t.widget.bridge(e,r),r},t.widget.extend=function(e){for(var i,n,o=s.call(arguments,1),r=0,a=o.length;a>r;r++)for(i in o[r])n=o[r][i],o[r].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var r="string"==typeof o,a=s.call(arguments,1),h=this;return o=!r&&a.length?t.widget.extend.apply(null,[o].concat(a)):o,r?this.each(function(){var s,i=t.data(this,n);return"instance"===o?(h=i,!1):i?t.isFunction(i[o])&&"_"!==o.charAt(0)?(s=i[o].apply(i,a),s!==i&&void 0!==s?(h=s&&s.jquery?h.pushStack(s.get()):s,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; attempted to call method '"+o+"'")}):this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))}),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(s,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),s),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(e,s){var i,n,o,r=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(r={},i=e.split("."),e=i.shift(),i.length){for(n=r[e]=t.widget.extend({},this.options[e]),o=0;i.length-1>o;o++)n[i[o]]=n[i[o]]||{},n=n[i[o]];if(e=i.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=s}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];r[e]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!e),e&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(e,s,i){var n,o=this;"boolean"!=typeof e&&(i=s,s=e,e=!1),i?(s=n=t(s),this.bindings=this.bindings.add(s)):(i=s,s=this.element,n=this.widget()),t.each(i,function(i,r){function a(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?o[r]:r).apply(o,arguments):void 0}"string"!=typeof r&&(a.guid=r.guid=r.guid||a.guid||t.guid++);var h=i.match(/^([\w:-]*)\s*(.*)$/),d=h[1]+o.eventNamespace,l=h[2];l?n.delegate(l,d,a):s.bind(d,a)})},_off:function(e,s){s=(s||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(s).undelegate(s),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function s(){return("string"==typeof t?i[t]:t).apply(i,arguments)}var i=this;return setTimeout(s,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,s,i){var n,o,r=this.options[e];if(i=i||{},s=t.Event(s),s.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),s.target=this.element[0],o=s.originalEvent)for(n in o)n in s||(s[n]=o[n]);return this.element.trigger(s,i),!(t.isFunction(r)&&r.apply(this.element[0],[s].concat(i))===!1||s.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,s){t.Widget.prototype["_"+e]=function(i,n,o){"string"==typeof n&&(n={effect:n});var r,a=n?n===!0||"number"==typeof n?s:n.effect||s:e;n=n||{},"number"==typeof n&&(n={duration:n}),r=!t.isEmptyObject(n),n.complete=o,n.delay&&i.delay(n.delay),r&&t.effects&&t.effects.effect[a]?i[e](n):a!==e&&i[a]?i[a](n.duration,n.easing,o):i.queue(function(s){t(this)[e](),o&&o.call(i[0]),s()})}}),t.widget}),function(t){"use strict";t.widget("aerolab.midnight",{options:{headerClass:"midnightHeader",innerClass:"midnightInner",defaultClass:"default",classPrefix:"",sectionSelector:"midnight"},_headers:{},_headerInfo:{top:0,height:0},_$sections:[],_sections:[],_scrollTop:0,_documentHeight:0,_transformMode:!1,refresh:function(){this._headerInfo={top:0,height:this.element.outerHeight()},this._$sections=t("[data-"+this.options.sectionSelector+"]:not(:hidden)"),this._sections=[],this._setupHeaders(),this.recalculate()},_create:function(){var e=this;this._scrollTop=window.pageYOffset||document.documentElement.scrollTop,this._documentHeight=t(document).height(),this._headers={},this._transformMode=this._getSupportedTransform(),this.refresh(),setInterval(function(){e._recalculateSections()},1e3),e.recalculate(),t(window).resize(function(){e.recalculate()}),this._updateHeadersLoop()},recalculate:function(){this._recalculateSections(),this._updateHeaderHeight(),this._recalculateHeaders(),this._updateHeaders()},_getSupportedTransform:function(){for(var t=["transform","WebkitTransform","MozTransform","OTransform","msTransform"],e=0;e<t.length;e++)if(void 0!==document.createElement("div").style[t[e]])return t[e];return!1},_getContainerHeight:function(){var e=this.element.find("> ."+this.options.headerClass),s=0,i=0,n=this;return e.length?e.each(function(){var e=t(this),o=e.find("> ."+n.options.innerClass);o.length?(o.css("bottom","auto").css("overflow","auto"),i=o.outerHeight(),o.css("bottom","0")):(e.css("bottom","auto"),i=e.outerHeight(),e.css("bottom","0")),s=i>s?i:s}):s=i=this.element.outerHeight(),s},_setupHeaders:function(){var e=this;this._headers[this.options.defaultClass]={};for(var s=0;s<this._$sections.length;s++){var i=t(this._$sections[s]),n=i.data(this.options.sectionSelector);"string"==typeof n&&(n=n.trim(),""!==n&&(e._headers[n]={}))}({top:this.element.css("padding-top"),right:this.element.css("padding-right"),bottom:this.element.css("padding-bottom"),left:this.element.css("padding-left")});this.element.css({position:"fixed",top:0,left:0,right:0,overflow:"hidden"}),this._updateHeaderHeight();var o=this.element.find("> ."+this.options.headerClass);o.length?o.filter("."+this.options.defaultClass).length||o.filter("."+this.options.headerClass+":first").clone(!0,!0).attr("class",this.options.headerClass+" "+this.options.defaultClass):this.element.wrapInner('<div class="'+this.options.headerClass+" "+this.options.defaultClass+'"></div>');var o=this.element.find("> ."+this.options.headerClass),r=o.filter("."+this.options.defaultClass).clone(!0,!0);for(var n in this._headers)if(this._headers.hasOwnProperty(n)&&"undefined"==typeof this._headers[n].element){var a=o.filter("."+n);a.length?this._headers[n].element=a:this._headers[n].element=r.clone(!0,!0).removeClass(this.options.defaultClass).addClass(n).appendTo(this.element);var h={position:"absolute",overflow:"hidden",top:0,left:0,right:0,bottom:0};this._headers[n].element.css(h),this._transformMode!==!1&&this._headers[n].element.css(this._transformMode,"translateZ(0)"),this._headers[n].element.find("> ."+this.options.innerClass).length||this._headers[n].element.wrapInner('<div class="'+this.options.innerClass+'"></div>'),this._headers[n].inner=this._headers[n].element.find("> ."+this.options.innerClass),this._headers[n].inner.css(h),this._transformMode!==!1&&this._headers[n].inner.css(this._transformMode,"translateZ(0)"),this._headers[n].from="",this._headers[n].progress=0}o.each(function(){var s=t(this),i=!1;for(var n in e._headers)e._headers.hasOwnProperty(n)&&s.hasClass(n)&&(i=!0);s.find("> ."+e.options.innerClass).length||s.wrapInner('<div class="'+e.options.innerClass+'"></div>'),i?s.show():s.hide()})},_recalculateHeaders:function(){this._scrollTop=window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop,this._scrollTop=Math.max(this._scrollTop,0),this._scrollTop=Math.min(this._scrollTop,this._documentHeight);var t=this._headerInfo.height,e=this._scrollTop+this._headerInfo.top,s=e+t;if("function"==typeof window.getComputedStyle){var i=window.getComputedStyle(this.element[0],null),n=0,o=0;if(this._transformMode!==!1&&"string"==typeof i.transform){var r=i.transform.match(/(-?[0-9\.]+)/g);null!==r&&r.length>=6&&!isNaN(parseFloat(r[5]))&&(o=parseFloat(r[5]))}i.top.indexOf("px")>=0&&!isNaN(parseFloat(i.top))&&(n=parseFloat(i.top)),e+=n+o,s+=n+o}for(var a in this._headers)this._headers.hasOwnProperty(a)&&(this._headers[a].from="",this._headers[a].progress=0);for(var h=0;h<this._sections.length;h++)s>=this._sections[h].start&&e<=this._sections[h].end&&(this._headers[this._sections[h].className].visible=!0,e>=this._sections[h].start&&s<=this._sections[h].end?(this._headers[this._sections[h].className].from="top",this._headers[this._sections[h].className].progress+=1):s>this._sections[h].end&&e<this._sections[h].end?(this._headers[this._sections[h].className].from="top",this._headers[this._sections[h].className].progress=1-(s-this._sections[h].end)/t):s>this._sections[h].start&&e<this._sections[h].start&&("top"===this._headers[this._sections[h].className].from?this._headers[this._sections[h].className].progress+=(s-this._sections[h].start)/t:(this._headers[this._sections[h].className].from="bottom",this._headers[this._sections[h].className].progress=(s-this._sections[h].start)/t)))},_updateHeaders:function(){if("undefined"!=typeof this._headers[this.options.defaultClass]){var t=0,e="";for(var s in this._headers)this._headers.hasOwnProperty(s)&&""!==!this._headers[s].from&&(t+=this._headers[s].progress,e=s);t<1&&(""===this._headers[this.options.defaultClass].from?(this._headers[this.options.defaultClass].from="top"===this._headers[e].from?"bottom":"top",this._headers[this.options.defaultClass].progress=1-t):this._headers[this.options.defaultClass].progress+=1-t);for(var i in this._headers)if(this._headers.hasOwnProperty(i)&&""!==!this._headers[i].from){var n=100*(1-this._headers[i].progress);n>=100&&(n=110),n<=-100&&(n=-110),"top"===this._headers[i].from?this._transformMode!==!1?(this._headers[i].element[0].style[this._transformMode]="translateY(-"+n+"%) translateZ(0)",this._headers[i].inner[0].style[this._transformMode]="translateY(+"+n+"%) translateZ(0)"):(this._headers[i].element[0].style.top="-"+n+"%",this._headers[i].inner[0].style.top="+"+n+"%"):this._transformMode!==!1?(this._headers[i].element[0].style[this._transformMode]="translateY(+"+n+"%) translateZ(0)",this._headers[i].inner[0].style[this._transformMode]="translateY(-"+n+"%) translateZ(0)"):(this._headers[i].element[0].style.top="+"+n+"%",this._headers[i].inner[0].style.top="-"+n+"%")}}},_recalculateSections:function(){this._documentHeight=t(document).height(),this._sections=[];for(var e=0;e<this._$sections.length;e++){var s=t(this._$sections[e]);this._sections.push({element:s,className:s.data(this.options.sectionSelector),start:s.offset().top,end:s.offset().top+s.outerHeight()})}},_updateHeaderHeight:function(){this._headerInfo.height=this._getContainerHeight(),this.element.css("height",this._headerInfo.height+"px")},_updateHeadersLoop:function(){var t=this;this._requestAnimationFrame(function(){t._updateHeadersLoop()}),this._recalculateHeaders(),this._updateHeaders()},_requestAnimationFrame:function(t){var e=e||function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}();e(t)}})}(jQuery);
body{font-family: 'Inter', sans-serif; font-size: 16px;}
/* base style */
a{text-decoration: none}
h1,h2,h3,h4,h5,h6,p,i{color: #000; padding-bottom: 30px;}
p{line-height: 28px; font-weight: 300px; color: #666;}
.big-text{ font-size: 70px; font-weight: 900;}
.medium-text{font-size: 40px;}
.normal-text{font-size: 20px;}
.small-text{font-size: 14px}
.intro-text{ text-transform: uppercase; font-size: 20px; font-weight: bold;}
.button{ background: #316bff; padding: 18px 28px; color: #fff; display: inline-block; border-radius: 4px;}
.subtitle{color: #000; text-decoration: underline;}
/* header */
.header{
width: 100%;
position:fixed;
top: 0;
left: 0;
padding: 30px;
display: flex;
text-align: center;
color: white;
z-index: 9999;
overflow: hidden;
}
.default{; color: #000;}
.white{ color: red;}
.menu{width: 100%; color: #fff; transition: all 1s cubic-bezier(.215, .61, .355, 1);}
.menu li{display: inline-block; }
.menu li a{;display: block; padding: 15px; color: #000; font-weight: 700;}
/* hero */
.hero{
background: linear-gradient(0deg, rgba(0,0,0,.1), rgba(0,0,0,.6)),
url('img/hero.jpg'), no-repeat center center;
background-size: cover;
height: 100vh;
display: flex; width: 100%; align-items: center;
}
.hero__content{
width: 100%;
max-width: 1350px;
margin: 0 auto;
padding: 30px;
}
.hero__content h1,
.hero__content p {
color: #fff;
}
/* poster */
.poster{
display: flex;
height: 100vh;
width: 100%;
align-items: center;
}
/* helpers */
.mt-1{margin-top: 50px;}
.mt-2{margin-top: 100px;}
.mt-3{margin-top: 150px;}
.tw{color: #fff;}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
<!-- header -->
<nav class="header">
<ul class="menu">
<li>Home</li>
<li>Statistiche</li>
<li>Giocatori</li>
<li>News</li>
</ul>
</nav>
<!-- hero -->
<div class="hero " data-midnight="default" >
<div class="hero__content reveal">
<p class="intro-text">Il sito guida di</p>
<h1 class="big-text">Goodgame Empire</h1>
Scopri di più
</div>
</div>
<!-- poster -->
<section class="poster mt-3 " data-midnight="white">
<div class="poster__content">
<h3 class="big-text">Statistiche</h3>
<p>Acquisici una conoscenza più approfondita della situazione in Goodgame Empire.<br>Questo sito ti offre gratuitamente in un unico posto tutti gli strumenti di cui hai bisogno per analizzare i rendimenti delle coalizioni, le varie classifiche, e le guerre svolte.
</p>
Scopri di più
</div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="midnight.jquery.min.js"></script>
<script>
// Start midnight
$(document).ready(function(){
// Change this to the correct selector.
$('.menu li a').midnight();
});
</script>
If I understood correctly you can use CSS to do this:
.white ul li a {
color: white;
}
/*!
* Midnight.js 1.1.1
* jQuery plugin to switch between multiple fixed header designs on the fly, so it looks in line with the content below it.
* http://aerolab.github.io/midnight.js/
*
* Copyright (c) 2014 Aerolab <info#aerolab.co>
*
* Released under the MIT license
* http://aerolab.github.io/midnight.js/LICENSE.txt
*/
! function(t) {
"function" == typeof define && define.amd ? define(["jquery"], t) : t(jQuery)
}(function(t) {
var e = 0,
s = Array.prototype.slice;
t.cleanData = function(e) {
return function(s) {
var i, n, o;
for (o = 0; null != (n = s[o]); o++) try {
i = t._data(n, "events"), i && i.remove && t(n).triggerHandler("remove")
} catch (r) {}
e(s)
}
}(t.cleanData), t.widget = function(e, s, i) {
var n, o, r, a, h = {},
d = e.split(".")[0];
return e = e.split(".")[1], n = d + "-" + e, i || (i = s, s = t.Widget), t.expr[":"][n.toLowerCase()] = function(e) {
return !!t.data(e, n)
}, t[d] = t[d] || {}, o = t[d][e], r = t[d][e] = function(t, e) {
return this._createWidget ? void(arguments.length && this._createWidget(t, e)) : new r(t, e)
}, t.extend(r, o, {
version: i.version,
_proto: t.extend({}, i),
_childConstructors: []
}), a = new s, a.options = t.widget.extend({}, a.options), t.each(i, function(e, i) {
return t.isFunction(i) ? void(h[e] = function() {
var t = function() {
return s.prototype[e].apply(this, arguments)
},
n = function(t) {
return s.prototype[e].apply(this, t)
};
return function() {
var e, s = this._super,
o = this._superApply;
return this._super = t, this._superApply = n, e = i.apply(this, arguments), this._super = s, this._superApply = o, e
}
}()) : void(h[e] = i)
}), r.prototype = t.widget.extend(a, {
widgetEventPrefix: o ? a.widgetEventPrefix || e : e
}, h, {
constructor: r,
namespace: d,
widgetName: e,
widgetFullName: n
}), o ? (t.each(o._childConstructors, function(e, s) {
var i = s.prototype;
t.widget(i.namespace + "." + i.widgetName, r, s._proto)
}), delete o._childConstructors) : s._childConstructors.push(r), t.widget.bridge(e, r), r
}, t.widget.extend = function(e) {
for (var i, n, o = s.call(arguments, 1), r = 0, a = o.length; a > r; r++)
for (i in o[r]) n = o[r][i], o[r].hasOwnProperty(i) && void 0 !== n && (e[i] = t.isPlainObject(n) ? t.isPlainObject(e[i]) ? t.widget.extend({}, e[i], n) : t.widget.extend({}, n) : n);
return e
}, t.widget.bridge = function(e, i) {
var n = i.prototype.widgetFullName || e;
t.fn[e] = function(o) {
var r = "string" == typeof o,
a = s.call(arguments, 1),
h = this;
return o = !r && a.length ? t.widget.extend.apply(null, [o].concat(a)) : o, r ? this.each(function() {
var s, i = t.data(this, n);
return "instance" === o ? (h = i, !1) : i ? t.isFunction(i[o]) && "_" !== o.charAt(0) ? (s = i[o].apply(i, a), s !== i && void 0 !== s ? (h = s && s.jquery ? h.pushStack(s.get()) : s, !1) : void 0) : t.error("no such method '" + o + "' for " + e + " widget instance") : t.error("cannot call methods on " + e + " prior to initialization; attempted to call method '" + o + "'")
}) : this.each(function() {
var e = t.data(this, n);
e ? (e.option(o || {}), e._init && e._init()) : t.data(this, n, new i(o, this))
}), h
}
}, t.Widget = function() {}, t.Widget._childConstructors = [], t.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
disabled: !1,
create: null
},
_createWidget: function(s, i) {
i = t(i || this.defaultElement || this)[0], this.element = t(i), this.uuid = e++, this.eventNamespace = "." + this.widgetName + this.uuid, this.bindings = t(), this.hoverable = t(), this.focusable = t(), i !== this && (t.data(i, this.widgetFullName, this), this._on(!0, this.element, {
remove: function(t) {
t.target === i && this.destroy()
}
}), this.document = t(i.style ? i.ownerDocument : i.document || i), this.window = t(this.document[0].defaultView || this.document[0].parentWindow)), this.options = t.widget.extend({}, this.options, this._getCreateOptions(), s), this._create(), this._trigger("create", null, this._getCreateEventData()), this._init()
},
_getCreateOptions: t.noop,
_getCreateEventData: t.noop,
_create: t.noop,
_init: t.noop,
destroy: function() {
this._destroy(), this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)), this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName + "-disabled ui-state-disabled"), this.bindings.unbind(this.eventNamespace), this.hoverable.removeClass("ui-state-hover"), this.focusable.removeClass("ui-state-focus")
},
_destroy: t.noop,
widget: function() {
return this.element
},
option: function(e, s) {
var i, n, o, r = e;
if (0 === arguments.length) return t.widget.extend({}, this.options);
if ("string" == typeof e)
if (r = {}, i = e.split("."), e = i.shift(), i.length) {
for (n = r[e] = t.widget.extend({}, this.options[e]), o = 0; i.length - 1 > o; o++) n[i[o]] = n[i[o]] || {}, n = n[i[o]];
if (e = i.pop(), 1 === arguments.length) return void 0 === n[e] ? null : n[e];
n[e] = s
} else {
if (1 === arguments.length) return void 0 === this.options[e] ? null : this.options[e];
r[e] = s
}
return this._setOptions(r), this
},
_setOptions: function(t) {
var e;
for (e in t) this._setOption(e, t[e]);
return this
},
_setOption: function(t, e) {
return this.options[t] = e, "disabled" === t && (this.widget().toggleClass(this.widgetFullName + "-disabled", !!e), e && (this.hoverable.removeClass("ui-state-hover"), this.focusable.removeClass("ui-state-focus"))), this
},
enable: function() {
return this._setOptions({
disabled: !1
})
},
disable: function() {
return this._setOptions({
disabled: !0
})
},
_on: function(e, s, i) {
var n, o = this;
"boolean" != typeof e && (i = s, s = e, e = !1), i ? (s = n = t(s), this.bindings = this.bindings.add(s)) : (i = s, s = this.element, n = this.widget()), t.each(i, function(i, r) {
function a() {
return e || o.options.disabled !== !0 && !t(this).hasClass("ui-state-disabled") ? ("string" == typeof r ? o[r] : r).apply(o, arguments) : void 0
}
"string" != typeof r && (a.guid = r.guid = r.guid || a.guid || t.guid++);
var h = i.match(/^([\w:-]*)\s*(.*)$/),
d = h[1] + o.eventNamespace,
l = h[2];
l ? n.delegate(l, d, a) : s.bind(d, a)
})
},
_off: function(e, s) {
s = (s || "").split(" ").join(this.eventNamespace + " ") + this.eventNamespace, e.unbind(s).undelegate(s), this.bindings = t(this.bindings.not(e).get()), this.focusable = t(this.focusable.not(e).get()), this.hoverable = t(this.hoverable.not(e).get())
},
_delay: function(t, e) {
function s() {
return ("string" == typeof t ? i[t] : t).apply(i, arguments)
}
var i = this;
return setTimeout(s, e || 0)
},
_hoverable: function(e) {
this.hoverable = this.hoverable.add(e), this._on(e, {
mouseenter: function(e) {
t(e.currentTarget).addClass("ui-state-hover")
},
mouseleave: function(e) {
t(e.currentTarget).removeClass("ui-state-hover")
}
})
},
_focusable: function(e) {
this.focusable = this.focusable.add(e), this._on(e, {
focusin: function(e) {
t(e.currentTarget).addClass("ui-state-focus")
},
focusout: function(e) {
t(e.currentTarget).removeClass("ui-state-focus")
}
})
},
_trigger: function(e, s, i) {
var n, o, r = this.options[e];
if (i = i || {}, s = t.Event(s), s.type = (e === this.widgetEventPrefix ? e : this.widgetEventPrefix + e).toLowerCase(), s.target = this.element[0], o = s.originalEvent)
for (n in o) n in s || (s[n] = o[n]);
return this.element.trigger(s, i), !(t.isFunction(r) && r.apply(this.element[0], [s].concat(i)) === !1 || s.isDefaultPrevented())
}
}, t.each({
show: "fadeIn",
hide: "fadeOut"
}, function(e, s) {
t.Widget.prototype["_" + e] = function(i, n, o) {
"string" == typeof n && (n = {
effect: n
});
var r, a = n ? n === !0 || "number" == typeof n ? s : n.effect || s : e;
n = n || {}, "number" == typeof n && (n = {
duration: n
}), r = !t.isEmptyObject(n), n.complete = o, n.delay && i.delay(n.delay), r && t.effects && t.effects.effect[a] ? i[e](n) : a !== e && i[a] ? i[a](n.duration, n.easing, o) : i.queue(function(s) {
t(this)[e](), o && o.call(i[0]), s()
})
}
}), t.widget
}),
function(t) {
"use strict";
t.widget("aerolab.midnight", {
options: {
headerClass: "midnightHeader",
innerClass: "midnightInner",
defaultClass: "default",
classPrefix: "",
sectionSelector: "midnight"
},
_headers: {},
_headerInfo: {
top: 0,
height: 0
},
_$sections: [],
_sections: [],
_scrollTop: 0,
_documentHeight: 0,
_transformMode: !1,
refresh: function() {
this._headerInfo = {
top: 0,
height: this.element.outerHeight()
}, this._$sections = t("[data-" + this.options.sectionSelector + "]:not(:hidden)"), this._sections = [], this._setupHeaders(), this.recalculate()
},
_create: function() {
var e = this;
this._scrollTop = window.pageYOffset || document.documentElement.scrollTop, this._documentHeight = t(document).height(), this._headers = {}, this._transformMode = this._getSupportedTransform(), this.refresh(), setInterval(function() {
e._recalculateSections()
}, 1e3), e.recalculate(), t(window).resize(function() {
e.recalculate()
}), this._updateHeadersLoop()
},
recalculate: function() {
this._recalculateSections(), this._updateHeaderHeight(), this._recalculateHeaders(), this._updateHeaders()
},
_getSupportedTransform: function() {
for (var t = ["transform", "WebkitTransform", "MozTransform", "OTransform", "msTransform"], e = 0; e < t.length; e++)
if (void 0 !== document.createElement("div").style[t[e]]) return t[e];
return !1
},
_getContainerHeight: function() {
var e = this.element.find("> ." + this.options.headerClass),
s = 0,
i = 0,
n = this;
return e.length ? e.each(function() {
var e = t(this),
o = e.find("> ." + n.options.innerClass);
o.length ? (o.css("bottom", "auto").css("overflow", "auto"), i = o.outerHeight(), o.css("bottom", "0")) : (e.css("bottom", "auto"), i = e.outerHeight(), e.css("bottom", "0")), s = i > s ? i : s
}) : s = i = this.element.outerHeight(), s
},
_setupHeaders: function() {
var e = this;
this._headers[this.options.defaultClass] = {};
for (var s = 0; s < this._$sections.length; s++) {
var i = t(this._$sections[s]),
n = i.data(this.options.sectionSelector);
"string" == typeof n && (n = n.trim(), "" !== n && (e._headers[n] = {}))
}({
top: this.element.css("padding-top"),
right: this.element.css("padding-right"),
bottom: this.element.css("padding-bottom"),
left: this.element.css("padding-left")
});
this.element.css({
position: "fixed",
top: 0,
left: 0,
right: 0,
overflow: "hidden"
}), this._updateHeaderHeight();
var o = this.element.find("> ." + this.options.headerClass);
o.length ? o.filter("." + this.options.defaultClass).length || o.filter("." + this.options.headerClass + ":first").clone(!0, !0).attr("class", this.options.headerClass + " " + this.options.defaultClass) : this.element.wrapInner('<div class="' + this.options.headerClass + " " + this.options.defaultClass + '"></div>');
var o = this.element.find("> ." + this.options.headerClass),
r = o.filter("." + this.options.defaultClass).clone(!0, !0);
for (var n in this._headers)
if (this._headers.hasOwnProperty(n) && "undefined" == typeof this._headers[n].element) {
var a = o.filter("." + n);
a.length ? this._headers[n].element = a : this._headers[n].element = r.clone(!0, !0).removeClass(this.options.defaultClass).addClass(n).appendTo(this.element);
var h = {
position: "absolute",
overflow: "hidden",
top: 0,
left: 0,
right: 0,
bottom: 0
};
this._headers[n].element.css(h), this._transformMode !== !1 && this._headers[n].element.css(this._transformMode, "translateZ(0)"), this._headers[n].element.find("> ." + this.options.innerClass).length || this._headers[n].element.wrapInner('<div class="' + this.options.innerClass + '"></div>'), this._headers[n].inner = this._headers[n].element.find("> ." + this.options.innerClass), this._headers[n].inner.css(h), this._transformMode !== !1 && this._headers[n].inner.css(this._transformMode, "translateZ(0)"), this._headers[n].from = "", this._headers[n].progress = 0
}
o.each(function() {
var s = t(this),
i = !1;
for (var n in e._headers) e._headers.hasOwnProperty(n) && s.hasClass(n) && (i = !0);
s.find("> ." + e.options.innerClass).length || s.wrapInner('<div class="' + e.options.innerClass + '"></div>'), i ? s.show() : s.hide()
})
},
_recalculateHeaders: function() {
this._scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop, this._scrollTop = Math.max(this._scrollTop, 0), this._scrollTop = Math.min(this._scrollTop, this._documentHeight);
var t = this._headerInfo.height,
e = this._scrollTop + this._headerInfo.top,
s = e + t;
if ("function" == typeof window.getComputedStyle) {
var i = window.getComputedStyle(this.element[0], null),
n = 0,
o = 0;
if (this._transformMode !== !1 && "string" == typeof i.transform) {
var r = i.transform.match(/(-?[0-9\.]+)/g);
null !== r && r.length >= 6 && !isNaN(parseFloat(r[5])) && (o = parseFloat(r[5]))
}
i.top.indexOf("px") >= 0 && !isNaN(parseFloat(i.top)) && (n = parseFloat(i.top)), e += n + o, s += n + o
}
for (var a in this._headers) this._headers.hasOwnProperty(a) && (this._headers[a].from = "", this._headers[a].progress = 0);
for (var h = 0; h < this._sections.length; h++) s >= this._sections[h].start && e <= this._sections[h].end && (this._headers[this._sections[h].className].visible = !0, e >= this._sections[h].start && s <= this._sections[h].end ? (this._headers[this._sections[h].className].from = "top", this._headers[this._sections[h].className].progress += 1) : s > this._sections[h].end && e < this._sections[h].end ? (this._headers[this._sections[h].className].from = "top", this._headers[this._sections[h].className].progress = 1 - (s - this._sections[h].end) / t) : s > this._sections[h].start && e < this._sections[h].start && ("top" === this._headers[this._sections[h].className].from ? this._headers[this._sections[h].className].progress += (s - this._sections[h].start) / t : (this._headers[this._sections[h].className].from = "bottom", this._headers[this._sections[h].className].progress = (s - this._sections[h].start) / t)))
},
_updateHeaders: function() {
if ("undefined" != typeof this._headers[this.options.defaultClass]) {
var t = 0,
e = "";
for (var s in this._headers) this._headers.hasOwnProperty(s) && "" !== !this._headers[s].from && (t += this._headers[s].progress, e = s);
t < 1 && ("" === this._headers[this.options.defaultClass].from ? (this._headers[this.options.defaultClass].from = "top" === this._headers[e].from ? "bottom" : "top", this._headers[this.options.defaultClass].progress = 1 - t) : this._headers[this.options.defaultClass].progress += 1 - t);
for (var i in this._headers)
if (this._headers.hasOwnProperty(i) && "" !== !this._headers[i].from) {
var n = 100 * (1 - this._headers[i].progress);
n >= 100 && (n = 110), n <= -100 && (n = -110), "top" === this._headers[i].from ? this._transformMode !== !1 ? (this._headers[i].element[0].style[this._transformMode] = "translateY(-" + n + "%) translateZ(0)", this._headers[i].inner[0].style[this._transformMode] = "translateY(+" + n + "%) translateZ(0)") : (this._headers[i].element[0].style.top = "-" + n + "%", this._headers[i].inner[0].style.top = "+" + n + "%") : this._transformMode !== !1 ? (this._headers[i].element[0].style[this._transformMode] = "translateY(+" + n + "%) translateZ(0)", this._headers[i].inner[0].style[this._transformMode] = "translateY(-" + n + "%) translateZ(0)") : (this._headers[i].element[0].style.top = "+" + n + "%", this._headers[i].inner[0].style.top = "-" + n + "%")
}
}
},
_recalculateSections: function() {
this._documentHeight = t(document).height(), this._sections = [];
for (var e = 0; e < this._$sections.length; e++) {
var s = t(this._$sections[e]);
this._sections.push({
element: s,
className: s.data(this.options.sectionSelector),
start: s.offset().top,
end: s.offset().top + s.outerHeight()
})
}
},
_updateHeaderHeight: function() {
this._headerInfo.height = this._getContainerHeight(), this.element.css("height", this._headerInfo.height + "px")
},
_updateHeadersLoop: function() {
var t = this;
this._requestAnimationFrame(function() {
t._updateHeadersLoop()
}), this._recalculateHeaders(), this._updateHeaders()
},
_requestAnimationFrame: function(t) {
var e = e || function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(t) {
window.setTimeout(t, 1e3 / 60)
}
}();
e(t)
}
})
}(jQuery);
body {
font-family: 'Inter', sans-serif;
font-size: 16px;
}
/* base style */
a {
text-decoration: none
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
i {
color: #000;
padding-bottom: 30px;
}
p {
line-height: 28px;
font-weight: 300px;
color: #666;
}
.big-text {
font-size: 70px;
font-weight: 900;
}
.medium-text {
font-size: 40px;
}
.normal-text {
font-size: 20px;
}
.small-text {
font-size: 14px
}
.intro-text {
text-transform: uppercase;
font-size: 20px;
font-weight: bold;
}
.button {
background: #316bff;
padding: 18px 28px;
color: #fff;
display: inline-block;
border-radius: 4px;
}
.subtitle {
color: #000;
text-decoration: underline;
}
/* header */
.header {
width: 100%;
position: fixed;
top: 0;
left: 0;
padding: 30px;
display: flex;
text-align: center;
color: white;
z-index: 9999;
overflow: hidden;
}
.default {
background: #316bff;
color: #000;
}
.white {
background: red;
color: red;
}
.white ul li a{
color: white;
}
.menu {
width: 100%;
color: #fff;
transition: all 1s cubic-bezier(.215, .61, .355, 1);
}
.menu li {
display: inline-block;
}
.menu li a {
;
display: block;
padding: 15px;
color: #000;
font-weight: 700;
}
/* hero */
.hero {
background: linear-gradient(0deg, rgba(0, 0, 0, .1), rgba(0, 0, 0, .6)), url('img/hero.jpg'), no-repeat center center;
background-size: cover;
height: 100vh;
display: flex;
width: 100%;
align-items: center;
}
.hero__content {
width: 100%;
max-width: 1350px;
margin: 0 auto;
padding: 30px;
}
.hero__content h1,
.hero__content p {
color: #fff;
}
/* poster */
.poster {
display: flex;
height: 100vh;
width: 100%;
align-items: center;
}
/* helpers */
.mt-1 {
margin-top: 50px;
}
.mt-2 {
margin-top: 100px;
}
.mt-3 {
margin-top: 150px;
}
.tw {
color: #fff;
}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
<!-- header -->
<nav class="header">
<ul class="menu">
<li>Home</li>
<li>Statistiche</li>
<li>Giocatori</li>
<li>News</li>
</ul>
</nav>
<!-- hero -->
<div class="hero " data-midnight="default">
<div class="hero__content reveal">
<p class="intro-text">Il sito guida di</p>
<h1 class="big-text">Goodgame Empire</h1>
Scopri di più
</div>
</div>
<!-- poster -->
<section class="poster mt-3 " data-midnight="white">
<div class="poster__content">
<h3 class="big-text">Statistiche</h3>
<p>Acquisici una conoscenza più approfondita della situazione in Goodgame Empire.<br>Questo sito ti offre gratuitamente in un unico posto tutti gli strumenti di cui hai bisogno per analizzare i rendimenti delle coalizioni, le varie classifiche, e le
guerre svolte.
</p>
Scopri di più
</div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="midnight.jquery.min.js"></script>
<script>
// Start midnight
$(document).ready(function() {
// Change this to the correct selector.
$('nav.header').midnight();
});
</script>
I have posted a similar question before, but it was too static. Now I want to make changes such that the code is dynamic.
OBJECTIVE
I want words that begin with "t" to be highlighted as a user types. If the word does not begin with "t" then do nothing. Basically, the user would have a normal typing experience but "t" words will be highlighted.
VERSION DETAILS
I have a version that "works" onmousemove, but this is annoying to a
user. I don't want them to have to move a mouse to get text to
highlight.
I have a version that "works" onkeypress, but the issue is that the
cursor always returns to initial position (which causes the text to be entered in reverse) and once the highlighting starts, it does not stop.
VERSION 1: event = onmousemove
//highlight ANY word that starts with t
function highlighter(ev) {
var content = ev.innerHTML;
var tokens = content.split(" ");
for (var i = 0; i < tokens.length; i++) {
if (tokens[i][0] == 't') {
tokens[i] = "<mark style='background-color:red; color:white;'>" + tokens[i] + "</mark>";
}
}
ev.innerHTML = tokens.join(" ");
}
/* NOT REQUIRED AT ALL, JUST TO MAKE INTERACTION MORE PLEASANT */
.container {
outline: none;
border: 3px solid black;
height: 100px;
width: 400px;
}
<div class="container" onmousemove=highlighter(this) contenteditable>
</div>
VERSION 2: event = onkeypress
//highlight ANY word that starts with t
function highlighter(ev) {
var content = ev.innerHTML;
var tokens = content.split(" ");
for (var i = 0; i < tokens.length; i++) {
if (tokens[i][0] == 't') {
tokens[i] = "<mark style='background-color:red; color:white;'>" + tokens[i] + "</mark>";
}
}
ev.innerHTML = tokens.join(" ");
}
/* NOT REQUIRED AT ALL, JUST TO MAKE INTERACTION MORE PLEASANT */
.container {
outline: none;
border: 3px solid black;
height: 100px;
width: 400px;
}
<div class="container" onkeypress=highlighter(this) contenteditable>
</div>
Here are draft example. I've used caret get/set snippet from this gist. Basically idea is simple - get caret position, do modification, set it back. Also swapped your innerHTML method to innerText, because you don't need to parse HTML code in your t-finder logic.
function highlighter(ev) {
// Get current cursor position
const currpos = getSelectionDirection(ev) !== 'forward' ? getSelectionStart(ev) : getSelectionEnd(ev);
// Change innerHTML to innerText, you
// dont need to parse HTML code here
var content = ev.innerText;
var tokens = content.split(" ");
for (var i = 0; i < tokens.length; i++) {
if (tokens[i][0] == 't') {
tokens[i] = "<mark style='background-color:red; color:white;'>" + tokens[i] + "</mark>";
}
}
ev.innerHTML = tokens.join(" ");
// Set cursor on it's proper position
setSelectionRange(ev, currpos, currpos);
}
/* NOT REQUIRED AT ALL, JUST TO MAKE INTERACTION MORE PLEASANT */
.container {
outline: none;
border: 3px solid black;
height: 100px;
width: 400px;
}
<div class="container" onkeypress=highlighter(this) contenteditable>
</div>
<script>
// Usage:
// var x = document.querySelector('[contenteditable]');
// var caretPosition = getSelectionDirection(x) !== 'forward' ? getSelectionStart(x) : getSelectionEnd(x);
// setSelectionRange(x, caretPosition + 1, caretPosition + 1);
// var value = getValue(x);
// it will not work with "<img /><img />" and, perhaps, in many other cases.
function isAfter(container, offset, node) {
var c = node;
while (c.parentNode != container) {
c = c.parentNode;
}
var i = offset;
while (c != null && i > 0) {
c = c.previousSibling;
i -= 1;
}
return i > 0;
}
function compareCaretPositons(node1, offset1, node2, offset2) {
if (node1 === node2) {
return offset1 - offset2;
}
var c = node1.compareDocumentPosition(node2);
if ((c & Node.DOCUMENT_POSITION_CONTAINED_BY) !== 0) {
return isAfter(node1, offset1, node2) ? +1 : -1;
} else if ((c & Node.DOCUMENT_POSITION_CONTAINS) !== 0) {
return isAfter(node2, offset2, node1) ? -1 : +1;
} else if ((c & Node.DOCUMENT_POSITION_FOLLOWING) !== 0) {
return -1;
} else if ((c & Node.DOCUMENT_POSITION_PRECEDING) !== 0) {
return +1;
}
}
function stringifyElementStart(node, isLineStart) {
if (node.tagName.toLowerCase() === 'br') {
if (true) {
return '\n';
}
}
if (node.tagName.toLowerCase() === 'div') { // Is a block-level element?
if (!isLineStart) { //TODO: Is not at start of a line?
return '\n';
}
}
return '';
}
function* positions(node, isLineStart = true) {
console.assert(node.nodeType === Node.ELEMENT_NODE);
var child = node.firstChild;
var offset = 0;
yield {node: node, offset: offset, text: stringifyElementStart(node, isLineStart)};
while (child != null) {
if (child.nodeType === Node.TEXT_NODE) {
yield {node: child, offset: 0/0, text: child.data};
isLineStart = false;
} else {
isLineStart = yield* positions(child, isLineStart);
}
child = child.nextSibling;
offset += 1;
yield {node: node, offset: offset, text: ''};
}
return isLineStart;
}
function getCaretPosition(contenteditable, textPosition) {
var textOffset = 0;
var lastNode = null;
var lastOffset = 0;
for (var p of positions(contenteditable)) {
if (p.text.length > textPosition - textOffset) {
return {node: p.node, offset: p.node.nodeType === Node.TEXT_NODE ? textPosition - textOffset : p.offset};
}
textOffset += p.text.length;
lastNode = p.node;
lastOffset = p.node.nodeType === Node.TEXT_NODE ? p.text.length : p.offset;
}
return {node: lastNode, offset: lastOffset};
}
function getTextOffset(contenteditable, selectionNode, selectionOffset) {
var textOffset = 0;
for (var p of positions(contenteditable)) {
if (selectionNode.nodeType !== Node.TEXT_NODE && selectionNode === p.node && selectionOffset === p.offset) {
return textOffset;
}
if (selectionNode.nodeType === Node.TEXT_NODE && selectionNode === p.node) {
return textOffset + selectionOffset;
}
textOffset += p.text.length;
}
return compareCaretPositons(selectionNode, selectionOffset, contenteditable, 0) < 0 ? 0 : textOffset;
}
function getValue(contenteditable) {
var value = '';
for (var p of positions(contenteditable)) {
value += p.text;
}
return value;
}
function setSelectionRange(contenteditable, start, end) {
var selection = window.getSelection();
var s = getCaretPosition(contenteditable, start);
var e = getCaretPosition(contenteditable, end);
selection.setBaseAndExtent(s.node, s.offset, e.node, e.offset);
}
//TODO: Ctrl+A - rangeCount is 2
function getSelectionDirection(contenteditable) {
var selection = window.getSelection();
var c = compareCaretPositons(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);
return c < 0 ? 'forward' : 'none';
}
function getSelectionStart(contenteditable) {
var selection = window.getSelection();
var c = compareCaretPositons(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);
return c < 0 ? getTextOffset(contenteditable, selection.anchorNode, selection.anchorOffset) : getTextOffset(contenteditable, selection.focusNode, selection.focusOffset);
}
function getSelectionEnd(contenteditable) {
var selection = window.getSelection();
var c = compareCaretPositons(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset);
return c < 0 ? getTextOffset(contenteditable, selection.focusNode, selection.focusOffset) : getTextOffset(contenteditable, selection.anchorNode, selection.anchorOffset);
}
</script>
On my HTML page, I need to have a line with text that rolls "infinitely" on the page, e.g.
"Hello World ... Hello World ... Hello World ... Hello World ..."
Sort of like a ticker tape, but with the same text's beginning rolling into its end w/o a gap.
I've tried using animation: marquee CSS style, I can get the text roll, then jump back, then roll again, but that's not what I need.
Is this possible with CSS? JS would be OK, if there is a working solution.
Try here "text rolling" working with text & images and mouse effects(js+css)
http://www.dynamicdrive.com/dynamicindex2/crawler/index.htm
Are you open to using a lib that does this?
This one here: http://www.cssscript.com/marquee-like-horizontal-scroller-with-pure-javascript-marquee-js/ does a good job.
$(document).ready(function() {
new Marquee('example', {
// once or continuous
continuous: true,
// 'rtl' or 'ltr'
direction: 'rtl',
// pause between loops
delayAfter: 1000,
// when to start
delayBefore: 0,
// scroll speed
speed: 0.5,
// loops
loops: -1
});
});
////////////////////////////// LIBRARY BELOW ///////
// See: http://www.cssscript.com/marquee-like-horizontal-scroller-with-pure-javascript-marquee-js/
/*
Vanilla Javascript Marquee
Version: 0.1.0
Author: Robert Bossaert <https://github.com/robertbossaert>
Example call:
new Marquee('element');
new Marquee('element', {
direction: 'rtl',
});
*/
var Marquee = function(element, defaults) {
"use strict";
var elem = document.getElementById(element),
options = (defaults === undefined) ? {} : defaults,
continuous = options.continuous || true, // once or continuous
delayAfter = options.delayAfter || 1000, // pause between loops
delayBefore = options.delayBefore || 0, // when to start
direction = options.direction || 'ltr', // ltr or rtl
loops = options.loops || -1,
speed = options.speed || 0.5,
timer = null,
milestone = 0,
marqueeElem = null,
elemWidth = null,
self = this,
ltrCond = 0,
loopCnt = 0,
start = 0,
process = null,
constructor = function(elem) {
// Build html
var elemHTML = elem.innerHTML,
elemNode = elem.childNodes[1] || elem;
elemWidth = elemNode.offsetWidth;
marqueeElem = '<div>' + elemHTML + '</div>';
elem.innerHTML = marqueeElem;
marqueeElem = elem.getElementsByTagName('div')[0];
elem.style.overflow = 'hidden';
marqueeElem.style.whiteSpace = 'nowrap';
marqueeElem.style.position = 'relative';
if (continuous === true) {
marqueeElem.innerHTML += elemHTML;
marqueeElem.style.width = '200%';
if (direction === 'ltr') {
start = -elemWidth;
}
} else {
ltrCond = elem.offsetWidth;
if (direction === 'rtl') {
milestone = ltrCond;
}
}
if (direction === 'ltr') {
milestone = -elemWidth;
} else if (direction === 'rtl') {
speed = -speed;
}
self.start();
return marqueeElem;
}
this.start = function() {
process = window.setInterval(function() {
self.play();
});
};
this.play = function() {
// beginning
marqueeElem.style.left = start + 'px';
start = start + speed;
if (start > ltrCond || start < -elemWidth) {
start = milestone;
loopCnt++;
if (loops !== -1 && loopCnt >= loops) {
marqueeElem.style.left = 0;
}
}
}
this.end = function() {
window.clearInterval(process);
}
// Init plugin
marqueeElem = constructor(elem);
}
body {
background: #edf3f9;
color: #3f4f5f;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
margin: 0 auto;
width: 800px;
}
header {
border-bottom: 2px solid #3f4f5f;
padding: 6.25em 0 3.95em;
text-align: center;
width: 100%;
}
header h1 {
margin: 0 0 10px;
}
.example {
padding: 3em 0;
}
h2 {
text-align: center;
}
pre {
background: #f5f2f0;
color: #000;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
line-height: 26px;
padding: 1em;
text-shadow: 0 1px white;
white-space: pre-wrap;
}
pre span.string {
color: #690;
}
pre span.number {
color: #905;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="example">
The quick brown fox ran over to the bar to drink some water. He walked up to the bar tender and said: blah blah blah.
</div>
Here is a demo based upon the lib that Dreamer posted.
I didn't like how it set inline styles on the element or how it used cookies to store past settings so I removed that in the crawler.js code.
This is a pretty old library (ie5 is mentioned (!)) but it seems to do the trick.
$(function() {
marqueeInit({
uniqueid: 'mycrawler',
style: {
},
inc: 5, //speed - pixel increment for each iteration of this marquee's movement
mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false)
moveatleast: 2,
neutral: 150,
persist: true,
savedirection: true
});
});
//////////////// CRAWLER.JS FOLLOWS ///////////
/* Text and/or Image Crawler Script v1.53 (c)2009-2012 John Davenport Scheuer
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
updated: 4/2011 for random order option, more (see below)
*/
/* Update 4/2011 to v1.5 - Adds optional random property. Set it to true to use.
Fixes browser crash from empty crawlers, ad and image blocking software/routines.
Fixes behavior in some IE of breaking script if an image is missing.
Adds alt attributes to images without them to aid in diagnosis of missing/corrupt
images. This may be disabled with the new optional noAddedAlt property set to true.
Internal workings enhanced for greater speed of execution, less memory usage.
*/
/* Update 11/2011 - Detect and randomize td elements within a single table with a single tr */
// updated 7/2012 to 1.51 for optional integration with 3rd party initializing scripts -
// ref: http://www.dynamicdrive.com/forums/showthread.php?p=278161#post278161
// updated 8/2012 to 1.52 for greater compatibility with IE in Quirks Mode
/* Update 10/2012 to v1.53 - Adds optional persist property to have the crawler remember its
position and direction page to page and on page reload. To enable it in the marqueeInit set
persist: true,
*/
///////////////// No Need to Edit - Configuration is Done in the On Page marqueeInit call(s) /////////////////
function marqueeInit(config) {
if (!document.createElement) return;
marqueeInit.ar.push(config);
marqueeInit.run(config.uniqueid);
}
(function() {
if (!document.createElement) return;
if (typeof opera === 'undefined') {
window.opera = false;
}
marqueeInit.ar = [];
document.write('<style type="text/css">.marquee{white-space:nowrap;overflow:hidden;visibility:hidden;}' +
'#marq_kill_marg_bord{border:none!important;margin:0!important;}<\/style>');
var c = 0,
tTRE = [/^\s*$/, /^\s*/, /\s*$/, /[^\/]+$/],
req1 = {
'position': 'relative',
'overflow': 'hidden'
},
defaultconfig = {
style: { //default style object for marquee containers without configured style
'margin': '0 auto'
},
direction: 'left',
inc: 2, //default speed - pixel increment for each iteration of a marquee's movement
mouse: 'pause' //default mouseover behavior ('pause' 'cursor driven' or false)
},
dash, ie = false,
oldie = 0,
ie5 = false,
iever = 0;
/*#cc_on #*/
/*#if(#_jscript_version >= 5)
ie = true;
try{document.documentMode = 2000}catch(e){};
iever = Math.min(document.documentMode, navigator.appVersion.replace(/^.*MSIE (\d+\.\d+).*$/, '$1'));
if(iever < 6)
oldie = 1;
if(iever < 5.5){
Array.prototype.push = function(el){this[this.length] = el;};
ie5 = true;
dash = /(-(.))/;
String.prototype.encamel = function(s, m){
s = this;
while((m = dash.exec(s)))
s = s.replace(m[1], m[2].toUpperCase());
return s;
};
}
#end #*/
if (!ie5) {
dash = /-(.)/g;
function toHump(a, b) {
return b.toUpperCase();
};
String.prototype.encamel = function() {
return this.replace(dash, toHump);
};
}
if (ie && iever < 8) {
marqueeInit.table = [];
window.attachEvent('onload', function() {
marqueeInit.OK = true;
var i = -1,
limit = marqueeInit.table.length;
while (++i < limit)
marqueeInit.run(marqueeInit.table[i]);
});
}
function intable(el) {
while ((el = el.parentNode))
if (el.tagName && el.tagName.toLowerCase() === 'table')
return true;
return false;
};
marqueeInit.run = function(id) {
if (ie && !marqueeInit.OK && iever < 8 && intable(document.getElementById(id))) {
marqueeInit.table.push(id);
return;
}
if (!document.getElementById(id))
setTimeout(function() {
marqueeInit.run(id);
}, 300);
else
new Marq(c++, document.getElementById(id));
}
function trimTags(tag) {
var r = [],
i = 0,
e;
while ((e = tag.firstChild) && e.nodeType === 3 && tTRE[0].test(e.nodeValue))
tag.removeChild(e);
while ((e = tag.lastChild) && e.nodeType === 3 && tTRE[0].test(e.nodeValue))
tag.removeChild(e);
if ((e = tag.firstChild) && e.nodeType === 3)
e.nodeValue = e.nodeValue.replace(tTRE[1], '');
if ((e = tag.lastChild) && e.nodeType === 3)
e.nodeValue = e.nodeValue.replace(tTRE[2], '');
while ((e = tag.firstChild))
r[i++] = tag.removeChild(e);
return r;
}
function randthem(tag) {
var els = oldie ? tag.all : tag.getElementsByTagName('*'),
i = els.length,
childels = [];
while (--i > -1) {
if (els[i].parentNode === tag) {
childels.push(els[i]);
}
}
childels.sort(function() {
return 0.5 - Math.random();
});
i = childels.length;
while (--i > -1) {
tag.appendChild(childels[i]);
}
}
function Marq(c, tag) {
var p, u, s, a, ims, ic, i, marqContent, cObj = this;
this.mq = marqueeInit.ar[c];
if (this.mq.random) {
if (tag.getElementsByTagName && tag.getElementsByTagName('tr').length === 1 && tag.childNodes.length === 1) {
randthem(tag.getElementsByTagName('tr')[0]);
} else {
randthem(tag);
}
}
for (p in defaultconfig)
if ((this.mq.hasOwnProperty && !this.mq.hasOwnProperty(p)) || (!this.mq.hasOwnProperty && !this.mq[p]))
this.mq[p] = defaultconfig[p];
this.mq.style.width = !this.mq.style.width || isNaN(parseInt(this.mq.style.width)) ? '100%' : this.mq.style.width;
if (!tag.getElementsByTagName('img')[0])
this.mq.style.height = !this.mq.style.height || isNaN(parseInt(this.mq.style.height)) ? tag.offsetHeight + 3 + 'px' : this.mq.style.height;
else
this.mq.style.height = !this.mq.style.height || isNaN(parseInt(this.mq.style.height)) ? 'auto' : this.mq.style.height;
u = this.mq.style.width.split(/\d/);
this.cw = this.mq.style.width ? [parseInt(this.mq.style.width), u[u.length - 1]] : ['a'];
marqContent = trimTags(tag);
tag.className = tag.id = '';
tag.removeAttribute('class', 0);
tag.removeAttribute('id', 0);
if (ie)
tag.removeAttribute('className', 0);
tag.appendChild(tag.cloneNode(false));
tag.className = ['marquee', c].join('');
tag.style.overflow = 'hidden';
this.c = tag.firstChild;
this.c.appendChild(this.c.cloneNode(false));
this.c.style.visibility = 'hidden';
a = [
[req1, this.c.style],
[this.mq.style, this.c.style]
];
for (i = a.length - 1; i > -1; --i)
for (p in a[i][0])
if ((a[i][0].hasOwnProperty && a[i][0].hasOwnProperty(p)) || (!a[i][0].hasOwnProperty))
a[i][1][p.encamel()] = a[i][0][p];
this.m = this.c.firstChild;
if (this.mq.mouse === 'pause') {
this.c.onmouseover = function() {
cObj.mq.stopped = true;
};
this.c.onmouseout = function() {
cObj.mq.stopped = false;
};
}
this.m.style.position = 'absolute';
this.m.style.left = '-10000000px';
this.m.style.whiteSpace = 'nowrap';
if (ie5) this.c.firstChild.appendChild((this.m = document.createElement('nobr')));
if (!this.mq.noAddedSpace)
this.m.appendChild(document.createTextNode('\xa0'));
for (i = 0; marqContent[i]; ++i)
this.m.appendChild(marqContent[i]);
if (ie5) this.m = this.c.firstChild;
ims = this.m.getElementsByTagName('img');
if (ims.length) {
for (ic = 0, i = 0; i < ims.length; ++i) {
ims[i].style.display = 'inline';
if (!ims[i].alt && !this.mq.noAddedAlt) {
ims[i].alt = (tTRE[3].exec(ims[i].src)) || ('Image #' + [i + 1]);
if (!ims[i].title) {
ims[i].title = '';
}
}
ims[i].style.display = 'inline';
ims[i].style.verticalAlign = ims[i].style.verticalAlign || 'top';
if (typeof ims[i].complete === 'boolean' && ims[i].complete)
ic++;
else {
ims[i].onload = ims[i].onerror = function() {
if (++ic === ims.length)
cObj.setup(c);
};
}
if (ic === ims.length)
this.setup(c);
}
} else this.setup(c)
}
Marq.prototype.setup = function(c) {
if (this.mq.setup) return;
this.mq.setup = this;
var s, w, cObj = this,
exit = 10000;
if (this.c.style.height === 'auto')
this.c.style.height = this.m.offsetHeight + 4 + 'px';
this.c.appendChild(this.m.cloneNode(true));
this.m = [this.m, this.m.nextSibling];
if (typeof this.mq.initcontent === 'function') {
this.mq.initcontent.apply(this.mq, [this.m]);
}
if (this.mq.mouse === 'cursor driven') {
this.r = this.mq.neutral || 16;
this.sinc = this.mq.inc;
this.c.onmousemove = function(e) {
cObj.mq.stopped = false;
cObj.directspeed(e)
};
if (this.mq.moveatleast) {
this.mq.inc = this.mq.moveatleast;
if (this.mq.savedirection) {
if (this.mq.savedirection === 'reverse') {
this.c.onmouseout = function(e) {
if (cObj.contains(e)) return;
cObj.mq.inc = cObj.mq.moveatleast;
cObj.mq.direction = cObj.mq.direction === 'right' ? 'left' : 'right';
};
} else {
this.mq.savedirection = this.mq.direction;
this.c.onmouseout = function(e) {
if (cObj.contains(e)) return;
cObj.mq.inc = cObj.mq.moveatleast;
cObj.mq.direction = cObj.mq.savedirection;
};
}
} else
this.c.onmouseout = function(e) {
if (!cObj.contains(e)) cObj.mq.inc = cObj.mq.moveatleast;
};
} else
this.c.onmouseout = function(e) {
if (!cObj.contains(e)) cObj.slowdeath();
};
}
this.w = this.m[0].offsetWidth;
this.m[0].style.left = 0;
this.c.id = 'marq_kill_marg_bord';
this.m[0].style.top = this.m[1].style.top = Math.floor((this.c.offsetHeight - this.m[0].offsetHeight) / 2 - oldie) + 'px';
this.c.id = '';
this.c.removeAttribute('id', 0);
this.m[1].style.left = this.w + 'px';
s = this.mq.moveatleast ? Math.max(this.mq.moveatleast, this.sinc) : (this.sinc || this.mq.inc);
while (this.c.offsetWidth > this.w - s && --exit) {
w = isNaN(this.cw[0]) ? this.w - s : --this.cw[0];
if (w < 1 || this.w < Math.max(1, s)) {
break;
}
this.c.style.width = isNaN(this.cw[0]) ? this.w - s + 'px' : --this.cw[0] + this.cw[1];
}
this.c.style.visibility = 'visible';
this.runit();
}
Marq.prototype.slowdeath = function() {
var cObj = this;
if (this.mq.inc) {
this.mq.inc -= 1;
this.timer = setTimeout(function() {
cObj.slowdeath();
}, 100);
}
}
Marq.prototype.runit = function() {
var cObj = this,
d = this.mq.direction === 'right' ? 1 : -1;
if (this.mq.stopped || this.mq.stopMarquee) {
setTimeout(function() {
cObj.runit();
}, 300);
return;
}
if (this.mq.mouse != 'cursor driven')
this.mq.inc = Math.max(1, this.mq.inc);
if (d * parseInt(this.m[0].style.left) >= this.w)
this.m[0].style.left = parseInt(this.m[1].style.left) - d * this.w + 'px';
if (d * parseInt(this.m[1].style.left) >= this.w)
this.m[1].style.left = parseInt(this.m[0].style.left) - d * this.w + 'px';
this.m[0].style.left = parseInt(this.m[0].style.left) + d * this.mq.inc + 'px';
this.m[1].style.left = parseInt(this.m[1].style.left) + d * this.mq.inc + 'px';
setTimeout(function() {
cObj.runit();
}, 30 + (this.mq.addDelay || 0));
}
Marq.prototype.directspeed = function(e) {
e = e || window.event;
if (this.timer) clearTimeout(this.timer);
var c = this.c,
w = c.offsetWidth,
l = c.offsetLeft,
mp = (typeof e.pageX === 'number' ?
e.pageX : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft) - l,
lb = (w - this.r) / 2,
rb = (w + this.r) / 2;
while ((c = c.offsetParent)) mp -= c.offsetLeft;
this.mq.direction = mp > rb ? 'left' : 'right';
this.mq.inc = Math.round((mp > rb ? (mp - rb) : mp < lb ? (lb - mp) : 0) / lb * this.sinc);
}
Marq.prototype.contains = function(e) {
if (e && e.relatedTarget) {
var c = e.relatedTarget;
if (c === this.c) return true;
while ((c = c.parentNode))
if (c === this.c) return true;
}
return false;
}
function resize() {
for (var s, w, m, i = 0; i < marqueeInit.ar.length; ++i) {
if (marqueeInit.ar[i] && marqueeInit.ar[i].setup) {
m = marqueeInit.ar[i].setup;
s = m.mq.moveatleast ? Math.max(m.mq.moveatleast, m.sinc) : (m.sinc || m.mq.inc);
m.c.style.width = m.mq.style.width;
m.cw[0] = m.cw.length > 1 ? parseInt(m.mq.style.width) : 'a';
while (m.c.offsetWidth > m.w - s) {
w = isNaN(m.cw[0]) ? m.w - s : --m.cw[0];
if (w < 1) {
break;
}
m.c.style.width = isNaN(m.cw[0]) ? m.w - s + 'px' : --m.cw[0] + m.cw[1];
}
}
}
}
function unload() {
for (var m, i = 0; i < marqueeInit.ar.length; ++i) {
if (marqueeInit.ar[i] && marqueeInit.ar[i].persist && marqueeInit.ar[i].setup) {
m = marqueeInit.ar[i].setup;
m.cookie.set(m.mq.uniqueid, m.m[0].style.left + ':' + m.m[1].style.left + ':' + m.mq.direction);
}
}
}
if (window.addEventListener) {
window.addEventListener('resize', resize, false);
window.addEventListener('unload', unload, false);
} else if (window.attachEvent) {
window.attachEvent('onresize', resize);
window.attachEvent('onunload', unload);
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="marquee" id="mycrawler">
Those confounded friars dully buzz that faltering jay. An appraising tongue acutely causes our courageous hogs. Their fitting submarines deftly break your approving improvisations. Her downcast taxonomies actually box up those disgusted turtles.
</div>
I'd like to delay the zoomed image disappearing by a X seconds so I can fade out the image rather than it simply disappearing.
Can I simply add .delay(1000) somewhere to the mouseleave / hide lines of code?
I've tried that but unfortunately doesn't seem to work. I've also tried to wrap a setTimeout( ... , 1000); around various parts of the code, but couldn't make that work either.
Any help much appreciated!
Here is the Jsfiddle https://jsfiddle.net/mr_antlers/nh5jw5tb/2/
This is the original 'EasyZoom' .js code.
/*!
* #name EasyZoom
* #author Matt Hinchliffe <>
* #modified Tuesday, September 6th, 2016
* #version 2.4.0
*/
! function (a) {
"use strict";
function b(b, c) {
this.$target = a(b), this.opts = a.extend({}, i, c, this.$target.data()), void 0 === this.isOpen && this._init()
}
var c, d, e, f, g, h, i = {
loadingNotice: "Loading image",
errorNotice: "The image could not be loaded",
errorDuration: 2500,
linkAttribute: "href",
preventClicks: !0,
beforeShow: a.noop,
beforeHide: a.noop,
onShow: a.noop,
onHide: a.noop,
onMove: a.noop
};
b.prototype._init = function () {
this.$link = this.$target.find("a"), this.$image = this.$target.find("img"), this.$flyout = a('<div class="easyzoom-flyout" />'), this.$notice = a('<div class="easyzoom-notice" />'), this.$target.on({
"mousemove.easyzoom touchmove.easyzoom": a.proxy(this._onMove, this),
"mouseleave.easyzoom touchend.easyzoom": a.proxy(this._onLeave, this),
"mouseenter.easyzoom touchstart.easyzoom": a.proxy(this._onEnter, this)
}), this.opts.preventClicks && this.$target.on("click.easyzoom", function (a) {
a.preventDefault()
})
}, b.prototype.show = function (a, b) {
var g, h, i, j, k = this;
if (this.opts.beforeShow.call(this) !== !1) {
if (!this.isReady) return this._loadImage(this.$link.attr(this.opts.linkAttribute), function () {
(k.isMouseOver || !b) && k.show(a)
});
this.$target.append(this.$flyout), g = this.$target.width(), h = this.$target.height(), i = this.$flyout.width(), j = this.$flyout.height(), c = this.$zoom.width() - i, d = this.$zoom.height() - j, 0 > c && (c = 0), 0 > d && (d = 0), e = c / g, f = d / h, this.isOpen = !0, this.opts.onShow.call(this), a && this._move(a)
}
}, b.prototype._onEnter = function (a) {
var b = a.originalEvent.touches;
this.isMouseOver = !0, b && 1 != b.length || (a.preventDefault(), this.show(a, !0))
}, b.prototype._onMove = function (a) {
this.isOpen && (a.preventDefault(), this._move(a))
}, b.prototype._onLeave = function () {
this.isMouseOver = !1, this.isOpen && this.hide()
}, b.prototype._onLoad = function (a) {
a.currentTarget.width && (this.isReady = !0, this.$notice.detach(), this.$flyout.html(this.$zoom), this.$target.removeClass("is-loading").addClass("is-ready"), a.data.call && a.data())
}, b.prototype._onError = function () {
var a = this;
this.$notice.text(this.opts.errorNotice), this.$target.removeClass("is-loading").addClass("is-error"), this.detachNotice = setTimeout(function () {
a.$notice.detach(), a.detachNotice = null
}, this.opts.errorDuration)
}, b.prototype._loadImage = function (b, c) {
var d = new Image;
this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)), this.$zoom = a(d).on("error", a.proxy(this._onError, this)).on("load", c, a.proxy(this._onLoad, this)), d.style.position = "absolute", d.src = b
}, b.prototype._move = function (a) {
if (0 === a.type.indexOf("touch")) {
var b = a.touches || a.originalEvent.touches;
g = b[0].pageX, h = b[0].pageY
} else g = a.pageX || g, h = a.pageY || h;
var i = this.$target.offset(),
j = h - i.top,
k = g - i.left,
l = Math.ceil(j * f),
m = Math.ceil(k * e);
if (0 > m || 0 > l || m > c || l > d) this.hide();
else {
var n = -1 * l,
o = -1 * m;
this.$zoom.css({
top: n,
left: o
}), this.opts.onMove.call(this, n, o)
}
}, b.prototype.hide = function () {
this.isOpen && this.opts.beforeHide.call(this) !== !1 && (this.$flyout.detach(), this.isOpen = !1, this.opts.onHide.call(this))
}, b.prototype.swap = function (b, c, d) {
this.hide(), this.isReady = !1, this.detachNotice && clearTimeout(this.detachNotice), this.$notice.parent().length && this.$notice.detach(), this.$target.removeClass("is-loading is-ready is-error"), this.$image.attr({
src: b,
srcset: a.isArray(d) ? d.join() : d
}), this.$link.attr(this.opts.linkAttribute, c)
}, b.prototype.teardown = function () {
this.hide(), this.$target.off(".easyzoom").removeClass("is-loading is-ready is-error"), this.detachNotice && clearTimeout(this.detachNotice), delete this.$link, delete this.$zoom, delete this.$image, delete this.$notice, delete this.$flyout, delete this.isOpen, delete this.isReady
}, a.fn.easyZoom = function (c) {
return this.each(function () {
var d = a.data(this, "easyZoom");
d ? void 0 === d.isOpen && d._init() : a.data(this, "easyZoom", new b(this, c))
})
}, "function" == typeof define && define.amd ? define(function () {
return b
}) : "undefined" != typeof module && module.exports && (module.exports = b)
}(jQuery);
// Instantiate EasyZoom instances
var $easyzoom = $('.easyzoom').easyZoom();
// Setup thumbnails example
var api1 = $easyzoom.filter('.easyzoom--with-thumbnails').data('easyZoom');
$('.thumbnails').on('click', 'a', function(e) {
var $this = $(this);
e.preventDefault();
// Use EasyZoom's `swap` method
api1.swap($this.data('standard'), $this.attr('href'));
});
// Setup toggles example
var api2 = $easyzoom.filter('.easyzoom--with-toggle').data('easyZoom');
$('.toggle').on('click', function() {
var $this = $(this);
if ($this.data("active") === true) {
$this.text("Switch on").data("active", false);
api2.teardown();
} else {
$this.text("Switch off").data("active", true);
api2._init();
}
});
You can pass in beforeShow and beforeHide argument into easyZoom when you instantiate them.
var $easyzoom = $('.easyzoom').easyZoom({
beforeHide: function() {
this.$flyout.fadeOut();
return false;
},
beforeShow: function() {
this.$flyout.show();
}
});
/*!
* #name EasyZoom
* #author Matt Hinchliffe <>
* #modified Tuesday, September 6th, 2016
* #version 2.4.0
*/
! function(a) {
"use strict";
function b(b, c) {
this.$target = a(b), this.opts = a.extend({}, i, c, this.$target.data()), void 0 === this.isOpen && this._init()
}
var c, d, e, f, g, h, i = {
loadingNotice: "Loading image",
errorNotice: "The image could not be loaded",
errorDuration: 2500,
linkAttribute: "href",
preventClicks: !0,
beforeShow: a.noop,
beforeHide: a.noop,
onShow: a.noop,
onHide: a.noop,
onMove: a.noop
};
b.prototype._init = function() {
this.$link = this.$target.find("a"), this.$image = this.$target.find("img"), this.$flyout = a('<div class="easyzoom-flyout" />'), this.$notice = a('<div class="easyzoom-notice" />'), this.$target.on({
"mousemove.easyzoom touchmove.easyzoom": a.proxy(this._onMove, this),
"mouseleave.easyzoom touchend.easyzoom": a.proxy(this._onLeave, this),
"mouseenter.easyzoom touchstart.easyzoom": a.proxy(this._onEnter, this)
}), this.opts.preventClicks && this.$target.on("click.easyzoom", function(a) {
a.preventDefault()
})
}, b.prototype.show = function(a, b) {
var g, h, i, j, k = this;
if (this.opts.beforeShow.call(this) !== !1) {
if (!this.isReady) return this._loadImage(this.$link.attr(this.opts.linkAttribute), function() {
(k.isMouseOver || !b) && k.show(a)
});
this.$target.append(this.$flyout), g = this.$target.width(), h = this.$target.height(), i = this.$flyout.width(), j = this.$flyout.height(), c = this.$zoom.width() - i, d = this.$zoom.height() - j, 0 > c && (c = 0), 0 > d && (d = 0), e = c / g, f = d / h, this.isOpen = !0, this.opts.onShow.call(this), a && this._move(a)
}
}, b.prototype._onEnter = function(a) {
var b = a.originalEvent.touches;
this.isMouseOver = !0, b && 1 != b.length || (a.preventDefault(), this.show(a, !0))
}, b.prototype._onMove = function(a) {
this.isOpen && (a.preventDefault(), this._move(a))
}, b.prototype._onLeave = function() {
this.isMouseOver = !1, this.isOpen && this.hide()
}, b.prototype._onLoad = function(a) {
a.currentTarget.width && (this.isReady = !0, this.$notice.detach(), this.$flyout.html(this.$zoom), this.$target.removeClass("is-loading").addClass("is-ready"), a.data.call && a.data())
}, b.prototype._onError = function() {
var a = this;
this.$notice.text(this.opts.errorNotice), this.$target.removeClass("is-loading").addClass("is-error"), this.detachNotice = setTimeout(function() {
a.$notice.detach(), a.detachNotice = null
}, this.opts.errorDuration)
}, b.prototype._loadImage = function(b, c) {
var d = new Image;
this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)), this.$zoom = a(d).on("error", a.proxy(this._onError, this)).on("load", c, a.proxy(this._onLoad, this)), d.style.position = "absolute", d.src = b
}, b.prototype._move = function(a) {
if (0 === a.type.indexOf("touch")) {
var b = a.touches || a.originalEvent.touches;
g = b[0].pageX, h = b[0].pageY
} else g = a.pageX || g, h = a.pageY || h;
var i = this.$target.offset(),
j = h - i.top,
k = g - i.left,
l = Math.ceil(j * f),
m = Math.ceil(k * e);
if (0 > m || 0 > l || m > c || l > d) this.hide();
else {
var n = -1 * l,
o = -1 * m;
this.$zoom.css({
top: n,
left: o
}), this.opts.onMove.call(this, n, o)
}
}, b.prototype.hide = function() {
this.isOpen && this.opts.beforeHide.call(this) !== !1 && (this.$flyout.detach(), this.isOpen = !1, this.opts.onHide.call(this))
}, b.prototype.swap = function(b, c, d) {
this.hide(), this.isReady = !1, this.detachNotice && clearTimeout(this.detachNotice), this.$notice.parent().length && this.$notice.detach(), this.$target.removeClass("is-loading is-ready is-error"), this.$image.attr({
src: b,
srcset: a.isArray(d) ? d.join() : d
}), this.$link.attr(this.opts.linkAttribute, c)
}, b.prototype.teardown = function() {
this.hide(), this.$target.off(".easyzoom").removeClass("is-loading is-ready is-error"), this.detachNotice && clearTimeout(this.detachNotice), delete this.$link, delete this.$zoom, delete this.$image, delete this.$notice, delete this.$flyout, delete this.isOpen, delete this.isReady
}, a.fn.easyZoom = function(c) {
return this.each(function() {
var d = a.data(this, "easyZoom");
d ? void 0 === d.isOpen && d._init() : a.data(this, "easyZoom", new b(this, c))
})
}, "function" == typeof define && define.amd ? define(function() {
return b
}) : "undefined" != typeof module && module.exports && (module.exports = b)
}(jQuery);
// Instantiate EasyZoom instances
var $easyzoom = $('.easyzoom').easyZoom({
beforeHide: function() {
this.$flyout.fadeOut();
return false;
},
beforeShow: function() {
this.$flyout.show();
}
});
// Setup thumbnails example
var api1 = $easyzoom.filter('.easyzoom--with-thumbnails').data('easyZoom');
$('.thumbnails').on('click', 'a', function(e) {
var $this = $(this);
e.preventDefault();
// Use EasyZoom's `swap` method
api1.swap($this.data('standard'), $this.attr('href'));
});
// Setup toggles example
var api2 = $easyzoom.filter('.easyzoom--with-toggle').data('easyZoom');
$('.toggle').on('click', function() {
var $this = $(this);
if ($this.data("active") === true) {
$this.text("Switch on").data("active", false);
api2.teardown();
} else {
$this.text("Switch off").data("active", true);
api2._init();
}
});
.easyzoom {
position: relative;
/* 'Shrink-wrap' the element */
display: inline-block;
*display: inline;
*zoom: 1;
}
.easyzoom img {
vertical-align: bottom;
}
.easyzoom.is-loading img {
cursor: progress;
}
.easyzoom.is-ready img {
cursor: default;
}
.easyzoom.is-error img {
cursor: not-allowed;
}
.easyzoom-notice {
position: absolute;
top: 50%;
left: 50%;
z-index: 150;
width: 10em;
margin: -1em 0 0 -5em;
line-height: 2em;
text-align: center;
background: #FFF;
box-shadow: 0 0 10px #888;
}
.easyzoom-flyout {
position: absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity: 0;
transition: 0.2s;
}
.easyzoom-flyout:hover {
position: absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity: 1;
transition: 0.8s;
}
.easyzoom--overlay .easyzoom-flyout {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.easyzoom--adjacent .easyzoom-flyout {
top: 0;
left: 100%;
width: 100%;
height: 100%;
margin-left: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="easyzoom easyzoom--overlay">
<a href="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg">
<img src="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg" alt="" width="608.917" height="405.833" />
</a>
</div>
You can refer the flyout zoomed image using this.$flyout in the functions.
Return false if you want to stop the default hide or show function. Just remember to add the default behavior into your function if you are doing that.
In the example I did above, I do a fadeOut on the zoomed image and stop the flyout from detaching (default behavior is detach() the zoomed image element). Then, as the flyout element was faded out, I have to use $.show() or the element will be stuck at display: none and nothing will be shown on mouseover.
Hope this helps.
'mouseleave' trigger _onLeave() which fire hide() which cause the zoomed div with image is removed from the DOM so any CSS transition or $().fadeOut() does not work. I removed hide() firing when mouseleave and change opacity in CSS and it seems to work now and anything else seems to be broken. Change opacity time as you wish.
fiddle
/*!
* #name EasyZoom
* #author Matt Hinchliffe <>
* #modified Tuesday, September 6th, 2016
* #version 2.4.0
*/
! function (a) {
"use strict";
function b(b, c) {
this.$target = a(b), this.opts = a.extend({}, i, c, this.$target.data()), void 0 === this.isOpen && this._init()
}
var c, d, e, f, g, h, i = {
loadingNotice: "Loading image",
errorNotice: "The image could not be loaded",
errorDuration: 2500,
linkAttribute: "href",
preventClicks: !0,
beforeShow: a.noop,
beforeHide: a.noop,
onShow: a.noop,
onHide: a.noop,
onMove: a.noop
};
b.prototype._init = function () {
this.$link = this.$target.find("a"), this.$image = this.$target.find("img"), this.$flyout = a('<div class="easyzoom-flyout" />'), this.$notice = a('<div class="easyzoom-notice" />'), this.$target.on({
"mousemove.easyzoom touchmove.easyzoom": a.proxy(this._onMove, this),
"mouseleave.easyzoom touchend.easyzoom": a.proxy(this._onLeave, this),
"mouseenter.easyzoom touchstart.easyzoom": a.proxy(this._onEnter, this)
}), this.opts.preventClicks && this.$target.on("click.easyzoom", function (a) {
a.preventDefault()
})
}, b.prototype.show = function (a, b) {
var g, h, i, j, k = this;
if (this.opts.beforeShow.call(this) !== !1) {
if (!this.isReady) return this._loadImage(this.$link.attr(this.opts.linkAttribute), function () {
(k.isMouseOver || !b) && k.show(a)
});
this.$target.append(this.$flyout), g = this.$target.width(), h = this.$target.height(), i = this.$flyout.width(), j = this.$flyout.height(), c = this.$zoom.width() - i, d = this.$zoom.height() - j, 0 > c && (c = 0), 0 > d && (d = 0), e = c / g, f = d / h, this.isOpen = !0, this.opts.onShow.call(this), a && this._move(a)
}
}, b.prototype._onEnter = function (a) {
var b = a.originalEvent.touches;
this.isMouseOver = !0, b && 1 != b.length || (a.preventDefault(), this.show(a, !0))
}, b.prototype._onMove = function (a) {
this.isOpen && (a.preventDefault(), this._move(a))
}, b.prototype._onLeave = function () {
this.isMouseOver = !1, this.isOpen
}, b.prototype._onLoad = function (a) {
a.currentTarget.width && (this.isReady = !0, this.$notice.detach(), this.$flyout.html(this.$zoom), this.$target.removeClass("is-loading").addClass("is-ready"), a.data.call && a.data())
}, b.prototype._onError = function () {
var a = this;
this.$notice.text(this.opts.errorNotice), this.$target.removeClass("is-loading").addClass("is-error"), this.detachNotice = setTimeout(function () {
a.$notice.detach(), a.detachNotice = null
}, this.opts.errorDuration)
}, b.prototype._loadImage = function (b, c) {
var d = new Image;
this.$target.addClass("is-loading").append(this.$notice.text(this.opts.loadingNotice)), this.$zoom = a(d).on("error", a.proxy(this._onError, this)).on("load", c, a.proxy(this._onLoad, this)), d.style.position = "absolute", d.src = b
}, b.prototype._move = function (a) {
if (0 === a.type.indexOf("touch")) {
var b = a.touches || a.originalEvent.touches;
g = b[0].pageX, h = b[0].pageY
} else g = a.pageX || g, h = a.pageY || h;
var i = this.$target.offset(),
j = h - i.top,
k = g - i.left,
l = Math.ceil(j * f),
m = Math.ceil(k * e);
if (0 > m || 0 > l || m > c || l > d) this.hide();
else {
var n = -1 * l,
o = -1 * m;
this.$zoom.css({
top: n,
left: o
}), this.opts.onMove.call(this, n, o)
}
}, b.prototype.hide = function () {
this.isOpen && this.opts.beforeHide.call(this) !== !1 && (this.$flyout.detach(), this.isOpen = !1, this.opts.onHide.call(this))
}, b.prototype.swap = function (b, c, d) {
this.hide(), this.isReady = !1, this.detachNotice && clearTimeout(this.detachNotice), this.$notice.parent().length && this.$notice.detach(), this.$target.removeClass("is-loading is-ready is-error"), this.$image.attr({
src: b,
srcset: a.isArray(d) ? d.join() : d
}), this.$link.attr(this.opts.linkAttribute, c)
}, b.prototype.teardown = function () {
this.hide(), this.$target.off(".easyzoom").removeClass("is-loading is-ready is-error"), this.detachNotice && clearTimeout(this.detachNotice), delete this.$link, delete this.$zoom, delete this.$image, delete this.$notice, delete this.$flyout, delete this.isOpen, delete this.isReady
}, a.fn.easyZoom = function (c) {
return this.each(function () {
var d = a.data(this, "easyZoom");
d ? void 0 === d.isOpen && d._init() : a.data(this, "easyZoom", new b(this, c))
})
}, "function" == typeof define && define.amd ? define(function () {
return b
}) : "undefined" != typeof module && module.exports && (module.exports = b)
}(jQuery);
// Instantiate EasyZoom instances
var $easyzoom = $('.easyzoom').easyZoom();
// Setup thumbnails example
var api1 = $easyzoom.filter('.easyzoom--with-thumbnails').data('easyZoom');
$('.thumbnails').on('click', 'a', function(e) {
var $this = $(this);
e.preventDefault();
// Use EasyZoom's `swap` method
api1.swap($this.data('standard'), $this.attr('href'));
});
// Setup toggles example
var api2 = $easyzoom.filter('.easyzoom--with-toggle').data('easyZoom');
$('.toggle').on('click', function() {
var $this = $(this);
if ($this.data("active") === true) {
$this.text("Switch on").data("active", false);
api2.teardown();
} else {
$this.text("Switch off").data("active", true);
api2._init();
}
});
.easyzoom {
position: relative;
/* 'Shrink-wrap' the element */
display: inline-block;
*display: inline;
*zoom: 1;
}
.easyzoom img {vertical-align: bottom;}
.easyzoom.is-loading img {cursor: progress;}
.easyzoom.is-ready img {cursor: default;}
.easyzoom.is-error img {cursor: not-allowed;}
.easyzoom-notice {
position: absolute;
top: 50%;
left: 50%;
z-index: 150;
width: 10em;
margin: -1em 0 0 -5em;
line-height: 2em;
text-align: center;
background: #FFF;
box-shadow: 0 0 10px #888;
}
.easyzoom-flyout {
position:absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity:0;
transition: opacity 1s ease-in-out;
}
.easyzoom-flyout:hover {
position:absolute;
z-index: 100;
overflow: hidden;
background: #FFF;
opacity:1;
}
.easyzoom--overlay .easyzoom-flyout {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.easyzoom--adjacent .easyzoom-flyout {
top: 0;
left: 100%;
width: 100%;
height: 100%;
margin-left: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="easyzoom easyzoom--overlay">
<a href="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg">
<img src="http://radarmidcentury.com.au/wp-content/uploads/2016/12/z-danish-sideboard-hans-wegner-president-in-oak-1a.jpg" alt="" width="608.917" height="405.833" />
</a>
</div>
I am trying to create a Lab color space slider with a dynamic gradient on the slider. I successfully created the slider (with the help of this library).
I'm having trouble creating the gradients for it. Here's the code relevant to the gradient creation:
setGradient(slider[0], "right", [Laba2cssString(0, Lab.a, Lab.b), Laba2cssString(100, Lab.a, Lab.b)]);
setGradient(slider[1], "right", [Laba2cssString(Lab.L, -128, Lab.b), Laba2cssString(Lab.L, 128, Lab.b)]);
setGradient(slider[2], "right", [Laba2cssString(Lab.L, Lab.a, -128), Laba2cssString(Lab.L, Lab.a, 128)]);
They work as they should, but the colors for A and B (Lab) are wrong. What's the correct way to generate the correct gradient colors?
Here's a website of how the colors should look: colorizer.org
codePen
var myColor = new Colors(),
overallSlidersWrapper = document.getElementById('overallSlidersWrapper'),
slider = document.getElementsByClassName('slider'),
type,
mode,
isLabAB = false,
currentModeType,
startPoint,
currentTarget,
currentTargetWidth,
maxReal = {
Lab: {
L: 100,
a: 256,
b: 256
}
};
var toCSSstring = {
Lab: Laba2cssString
};
var sliderDown = function(e) {
e.preventDefault();
if (e.target.classList.contains('sliderRange') || e.target.classList.contains('sliderCursor')) currentTarget = e.target.parentNode;
else if (e.target.classList.contains('slider')) currentTarget = e.target;
else if (e.target.classList.contains('leftRoundness')) currentTarget = e.target.nextElementSibling;
else if (e.target.classList.contains('rightRoundness')) currentTarget = e.target.previousElementSibling;
else return;
currentModeType = getModeType(currentTarget);
type = currentModeType.type;
mode = currentModeType.mode;
isLabAB = currentModeType.isLabAB;
startPoint = getOrigin(currentTarget);
sliderMove(e);
addEvent(window, 'mousemove', sliderMove);
startRender();
},
sliderMove = function(e) {
var newColor = {};
newColor[mode] = (e.clientX - startPoint.left) /
currentTarget.offsetWidth * maxReal[type][mode] - (isLabAB ? 128 : 0);
myColor.setColor(newColor, type);
};
renderColorSliders = function(color) {
for (var n = slider.length; n--;) {
var currentModeType = getModeType(slider[n]),
localType = currentModeType.type,
localMode = currentModeType.mode,
isLabAB = currentModeType.isLabAB;
var colorNumber = myColor.colors.RND[localType][localMode],
percentPosition = (((colorNumber / maxReal[localType][localMode]) + (isLabAB ? 0.5 : 0)) *
slider[n].offsetWidth) - 7;
var colorNumber = (localMode === 'alpha') ? myColor.colors.alpha : myColor.colors.RND[localType][localMode],
percentPosition = (((colorNumber / maxReal[localType][localMode]) + (isLabAB ? 0.5 : 0)) *
slider[n].offsetWidth) - 7;
slider[n].firstElementChild.style.transform = 'translateX(' + percentPosition + 'px)';
slider[n].firstElementChild.style.borderColor = color.RGBLuminance > 0.22 ? 'black' : 'white';
}
};
var result = document.getElementById('result');
function renderResult(color) {
result.style.backgroundColor = rgba2cssString(color.RND.rgb.r, color.RND.rgb.g, color.RND.rgb.b);
}
function renderGradients(color) {
Lab = color.RND.Lab;
setGradient(slider[0], "right", [Laba2cssString(0, Lab.a, Lab.b), Laba2cssString(100, Lab.a, Lab.b)]);
setGradient(slider[1], "right", [Laba2cssString(Lab.L, -128, Lab.b), Laba2cssString(Lab.L, 128, Lab.b)]);
setGradient(slider[2], "right", [Laba2cssString(Lab.L, Lab.a, -128), Laba2cssString(Lab.L, Lab.a, 128)]);
slider[0].previousElementSibling.style.backgroundColor = Laba2cssString(0, Lab.a, Lab.b);
slider[0].nextElementSibling.style.backgroundColor = Laba2cssString(100, Lab.a, Lab.b);
slider[1].previousElementSibling.style.backgroundColor = Laba2cssString(Lab.L, -128, Lab.b);
slider[1].nextElementSibling.style.backgroundColor = Laba2cssString(Lab.L, 128, Lab.b);
slider[2].previousElementSibling.style.backgroundColor = Laba2cssString(Lab.L, Lab.a, -128);
slider[2].nextElementSibling.style.backgroundColor = Laba2cssString(Lab.L, Lab.a, 128);
}
addEvent(overallSlidersWrapper, 'mousedown', sliderDown);
function removeMouseUpEvents() {
removeEvent(window, 'mousemove', sliderMove);
stopRender();
}
addEvent(window, 'mouseup', removeMouseUpEvents);
var doRender = function(color) {
renderColorSliders(color);
renderResult(color);
renderGradients(color);
},
renderTimer,
startRender = function() {
renderTimer = setInterval(function() {
doRender(myColor.colors);
// http://stackoverflow.com/questions/2940054/
}, 13); // 1000 / 60); // ~16.666 -> 60Hz or 60fps
},
stopRender = function() {
clearInterval(renderTimer);
};
doRender(myColor.colors);
/*-----------------------------*/
/*------ Function Helpers -----*/
/*-----------------------------*/
function getOrigin(elm) {
var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {
top: 0,
left: 0
},
doc = elm && elm.ownerDocument,
body = doc.body,
win = doc.defaultView || doc.parentWindow || window,
docElem = doc.documentElement || body.parentNode,
clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
clientLeft = docElem.clientLeft || body.clientLeft || 0;
return {
left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
};
}
function addEvent(obj, type, func) {
addEvent.cache = addEvent.cache || {
_get: function(obj, type, func, checkOnly) {
var cache = addEvent.cache[type] || [];
for (var n = cache.length; n--;) {
if (obj === cache[n].obj && '' + func === '' + cache[n].func) {
func = cache[n].func;
if (!checkOnly) {
cache[n] = cache[n].obj = cache[n].func = null;
cache.splice(n, 1);
}
return func;
}
}
},
_set: function(obj, type, func) {
var cache = addEvent.cache[type] = addEvent.cache[type] || [];
if (addEvent.cache._get(obj, type, func, true)) {
return true;
} else {
cache.push({
func: func,
obj: obj
});
}
}
};
if (!func.name && addEvent.cache._set(obj, type, func) || typeof func !== 'function') {
return;
}
if (obj.addEventListener) obj.addEventListener(type, func, false);
else obj.attachEvent('on' + type, func);
}
function removeEvent(obj, type, func) {
if (typeof func !== 'function') return;
if (!func.name) {
func = addEvent.cache._get(obj, type, func) || func;
}
if (obj.removeEventListener) obj.removeEventListener(type, func, false);
else obj.detachEvent('on' + type, func);
}
function hasClass(ele, cls) {
return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function getModeType(elem) {
var id = elem.id, // rgbR
len = id.length - 1, // 3
type = id.substr(0, len), // rgb
mode = id.charAt(len), // r
isLabAB = type === 'Lab' && (/(?:a|b)/.test(mode)); //is 'Lab && ()'a' || 'b')
if (elem.id === 'rgbA') mode = 'alpha';
return {
type: type,
mode: mode,
isLabAB: isLabAB
};
}
/**
* Formats the given RGB values into a string that can be used in CSS
*/
function rgba2cssString(r, g, b, a) {
if (r == null) return;
if (isObject(r)) r = Object.keys(r).map(function(key) {
return r[key]
});
if (Array.isArray(r)) {
// Check if array doesn't have alpha
if (r.length === 3) return rgba2cssString(r[0], r[1], r[2]);
// Check if array has alpha
else if (r.length === 4) return rgba2cssString(r[0], r[1], r[2], r[3]);
}
if (a || a === 0) return "rgba(" + r + "," + g + "," + b + "," + a + ")";
return "rgb(" + r + "," + g + "," + b + ")";
}
/**
* Formats the given HSL values into a string that can be used in CSS
*/
function hsla2cssString(h, s, l, a) {
if (h == null) return;
if (isObject(h)) h = Object.keys(h).map(function(key) {
return h[key]
});
if (Array.isArray(h)) {
// Check if array doesn't have alpha
if (h.length === 3) return rgba2cssString(h[0], h[1], h[2]);
// Check if array has alpha
else if (h.length === 4) return rgba2cssString(h[0], h[1], h[2], h[3]);
}
if (a || a === 0) return "hsla(" + h + "," + s + "%," + l + "%," + a + ")";
return "hsl(" + h + "," + s + "%," + l + "%)";
}
/**
* Formats the given HSV values into a string that can be used in CSS
*/
function hsva2cssString(h, s, v, a) {
if (h == null) return;
var hsvObject,
alpha;
if (isObject(h)) {
hsvObject = h;
alpha = h.a;
} else if (Array.isArray(h)) {
hsvObject = {
h: h[0],
s: h[1],
v: h[2]
};
alpha = h[3];
} else if (s != null) {
hsvObject = {
h: h,
s: s,
v: v
};
alpha = a;
}
var rgbColor = myColor.convertColor(hsvObject, 'HSV2RGB');
rgbColor.a = alpha;
return rgba2cssString(rgbColor);
}
/**
* Formats the given Lab values into a string that can be used in CSS
*/
function Laba2cssString(L, a, b, alpha) {
if (L == null) return;
var LabObject,
alphaLocal;
if (isObject(L)) {
LabObject = L;
alphaLocal = L.alpha;
} else if (Array.isArray(L)) {
LabObject = {
L: L[0],
a: L[1],
b: L[2]
};
alphaLocal = L[3];
} else if (a != null) {
LabObject = {
L: L,
a: a,
b: b
};
alphaLocal = alpha;
}
var rgbColor = myColor.convertColor(LabObject, 'Lab2RGB');
rgbColor.a = alpha;
return rgba2cssString(rgbColor);
}
function setGradient(el, direction, steps, multipleBG) {
var gradientString = "linear-gradient(to " + direction + ",";
stepSize = 100 / (steps.length - 1);
for (var i = 0; i < steps.length; i++) {
gradientString += (i > 0 ? "," : "") + steps[i] + (i * stepSize) + "%";
}
gradientString += ")";
if (multipleBG) {
gradientString += ', ' + multipleBG;
}
el.style.backgroundImage = gradientString;
}
function isObject(obj) {
return (typeof obj === "object" && !Array.isArray(obj) && obj !== null);
}
#overallSlidersWrapper {
width: 500px;
}
.sliderContent {
height: 138px;
}
.colorSliderTabsLabel {
width: calc(100% /4);
display: inline-block;
text-align: center;
cursor: pointer;
}
#colorSliderTabUnderliner {
height: 3px;
width: calc(100% /4);
background-color: green;
transition: transform 0.3s cubic-bezier(0.45, 0.05, 0.55, 0.95);
}
#tabContentWrapper {
width: 680px;
align-items: flex-start;
position: relative;
}
#overallSlidersWrapper {} .sliderOuterWrapper {
margin-bottom: 10px;
}
.sliderLabel {} .sliderInnerWrapper {
height: 18px;
width: 100%;
cursor: pointer;
position: relative;
display: flex;
}
.slider {
height: 100%;
width: calc(100% - 62px);
/* Subtract TextField (44px) and Both Rounders for Slider (19px each)*/
position: relative;
border: 1px solid black;
border-right: none;
border-left: none;
}
.leftRoundness,
.rightRoundness {
width: 9px;
height: 100%;
border: 1px solid black;
}
.leftRoundness {
border-right: none;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
.rightRoundness {
border-left: none;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
}
.sliderCursor {
width: 14px;
height: 14px;
border-radius: 50%;
position: relative;
border: 2px solid black;
}
#result {
width: 100px;
height: 100px;
}
<script src="https://rawgit.com/PitPik/colorPicker/master/colors.js"></script>
<div id="result"></div>
<div id="overallSlidersWrapper">
<div id="LabSliderContent" class="sliderContent">
<div class="sliderOuterWrapper">
<div class="sliderLabel">Lightness</div>
<div class="sliderInnerWrapper">
<div class="leftRoundness"></div>
<div id="LabL" class="slider">
<div class="sliderCursor"></div>
</div>
<div class="rightRoundness"></div>
</div>
</div>
<div class="sliderOuterWrapper">
<div class="sliderLabel">a (Green ↔ Red)</div>
<div class="sliderInnerWrapper">
<div class="leftRoundness"></div>
<div id="Laba" class="slider">
<div class="sliderCursor"></div>
</div>
<div class="rightRoundness"></div>
</div>
</div>
<div class="sliderOuterWrapper">
<div class="sliderLabel">b (Blue ↔ Yellow)</div>
<div class="sliderInnerWrapper">
<div class="leftRoundness"></div>
<div id="Labb" class="slider">
<div class="sliderCursor"></div>
</div>
<div class="rightRoundness"></div>
</div>
</div>
</div>
</div>
setgradient make a gradient going through the points you define. In your code, you just define the colors in the corners of your slider, so everything in the middle is out of control for you. You can improve the result by adding more points in the way of the gradient as:
setGradient(slider[0], "right", [Laba2cssString(0, Lab.a, Lab.b), Laba2cssString(50, Lab.a, Lab.b), Laba2cssString(100, Lab.a, Lab.b)]);
setGradient(slider[1], "right", [Laba2cssString(Lab.L, -128, Lab.b),Laba2cssString(Lab.L, -0, Lab.b), Laba2cssString(Lab.L, 128, Lab.b)]);
setGradient(slider[2], "right", [Laba2cssString(Lab.L, Lab.a, -128),Laba2cssString(Lab.L, Lab.a, -0), Laba2cssString(Lab.L, Lab.a, 128)]);
The more points you add, the better the sliderbar would look like.