4 Images in a row that animate into existance with an icon that appears upon hover, once clicked it will open the image in a modal box.
CSS
/* Might not be required */ /* .jsn-demo-page #jsn-pos-user-top { border: none; padding: 0; } .jsn-demo-page #jsn-centercol { padding: 0 !important; } */ /* Latest Projects */ .jsn-modulecontainer.demo-latest-projects { margin-top: 0 !important; } #demo-latest-projects .section-heading { background-color: #111; color: #fff; font-size: 1.8em; text-transform: uppercase; letter-spacing: 5px; text-align: center; margin: 0; padding: 45px 0; } .jsn-color-blue #demo-latest-projects .section-heading { background-color: #1c8bbe; } .jsn-color-red #demo-latest-projects .section-heading { background-color: #d85544; } .jsn-color-green #demo-latest-projects .section-heading { background-color: #139d6b; } .jsn-color-orange #demo-latest-projects .section-heading { background-color: #c78f23; } .jsn-color-violet #demo-latest-projects .section-heading { background-color: #8762ae; } .jsn-color-grey #demo-latest-projects .section-heading { background-color: #333; } #demo-latest-projects .latest-projects .grid-col { width: 25%; } #demo-latest-projects .latest-projects .grid-col_inner { margin: 0; } #demo-latest-projects .latest-projects .project-item a { display: block; position: relative; z-index: 90; top: 0; left: 0; } #demo-latest-projects .latest-projects .project-item a img { max-width: 100%; display: block; } #demo-latest-projects .latest-projects .project-item { position: relative; overflow: hidden; } #demo-latest-projects .latest-projects .project-item a:before, #demo-latest-projects .latest-projects .project-item a:after { opacity: 0; filter: alpha(opacity=0); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -webkit-transition: all 0.3s ease-in-out; } #demo-latest-projects .latest-projects .project-item a:before { content: ""; display: block; position: absolute; width: 100%; height: 100%; background-color: #000\9; background-color: rgba(0,0,0,0.75); z-index: 100; } #demo-latest-projects .latest-projects .project-item a:after { content: "\f00e"; font-family: 'FontAwesome'; font-size: 1.6em; position: absolute; display: block; width: 80px; height: 80px; line-height: 70px; text-align: center; color: #fff; top: 40%; left: 50%; margin-top: -40px; margin-left: -40px; border: 3px solid #fff; border-radius: 100%; -moz-border-radius: 100%; -webkit-border-radius: 100%; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; z-index: 110; } #demo-latest-projects .latest-projects .project-item a:hover:before, #demo-latest-projects .latest-projects .project-item a:hover:after { opacity: 1; filter: alpha(opacity=100); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } #demo-latest-projects .latest-projects .project-item a:hover:after { top: 50%; } /* ===== RESPONSIVE OPTIMIZING ===== */ @media only screen and (max-width: 480px), (max-device-width: 480px) { .jsn-mobile #demo-latest-projects .latest-projects .grid-col { width: 100%; } .jsn-mobile #demo-latest-projects .section-heading { font-size: 1.2em; padding: 30px 0; } }
CSS (Optional / Animation / Waypoints)
/* ===== WAYPOINT ONSCROLL ACTION ===== */ /* Waypoint by http://imakewebthings.com/jquery-waypoints/ */ /* Declare scale-fade animation */ @keyframes scale-fade { 0% { transform:scale(0.5); opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; } 100% { transform:scale(1); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } } @-moz-keyframes scale-fade { 0% { -moz-transform:scale(0.5); opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; } 100% { -moz-transform:scale(1); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } } @-webkit-keyframes scale-fade { 0% { -webkit-transform:scale(0.5); opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; } 100% { -webkit-transform:scale(1); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } } /* Declare translate-fade animation */ @keyframes translate-fade { 0% { transform:translate(0,50px); opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; } 100% { transform:translate(0,0); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } } @-moz-keyframes translate-fade { 0% { -moz-transform:translate(0,50px); opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; } 100% { -moz-transform:translate(0,0); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } } @-webkit-keyframes translate-fade { 0% { -webkit-transform:translate(0,50px); opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; } 100% { -webkit-transform:translate(0,0); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; } } .appearing .project-item, .appearing .main-features .feature-item [class*="fa fa-"], .appearing .graph-item .graph-item-inner, .appearing .stat-group .counting-number { opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; -moz-transform: scale(0.5); -webkit-transform: scale(0.5); -ms-transform: scale(0.5); transform: scale(0.5); transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -webkit-transition: all 0.3s ease-in-out; } .appearing.scroll-action .project-item, .appearing.scroll-action .main-features .feature-item [class*="fa fa-"], .appearing.scroll-action .graph-item .graph-item-inner, .appearing.scroll-action .stat-group .counting-number { -webkit-animation: scale-fade 0.8s 1 cubic-bezier(0,.61,.46,1.33); -moz-animation: scale-fade 0.8s 1 cubic-bezier(0,.61,.46,1.33); animation: scale-fade 0.8s 1 cubic-bezier(0,.61,.46,1.33); opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; -moz-transform: scale(1); -webkit-transform: scale(1); -ms-transform: scale(1); transform: scale(1); } .appearing .apple-devices { opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; -moz-transform: translate(0,50px); -webkit-transform: translate(0,50px); -ms-transform: translate(0,50px); transform: translate(0,50px); transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -webkit-transition: all 0.3s ease-in-out; } .appearing.scroll-action .apple-devices { -webkit-animation: translate-fade 1s 1 ease-in-out; -moz-animation: translate-fade 1s 1 ease-in-out; animation: translate-fade 1s 1 ease-in-out; opacity:1; filter: alpha(opacity=100); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; -moz-transform: translate(0,0); -webkit-transform: translate(0,0); -ms-transform: translate(0,0); transform: translate(0,0); } .scroll-down { } .scroll-down.scroll-action { opacity:0; filter: alpha(opacity=0); -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; }
JS (Optional / Animation / Waypoints)
/* ==================== JSN MINI CUSTOM JS ==================== */ // i have seperated out each complete function with //---------------------------------------- // use the whole file for Mini effects and just delete stuff you do not want setTimeout(function() { (function($) { //---------------------------------------- // intiates the Waypoints codebase // This causes animations to be paused until triggered by the Waypoints code // Waypoints are configured later /* Waypoints */ (function(){var t=[].indexOf||function(t){for(var e=0,n=this.length;e<n;e++){if(e in this&&this[e]===t)return e}return-1},e=[].slice;(function(t,e){if(typeof define==="function"&&define.amd){return define("waypoints",["jquery"],function(n){return e(n,t)})}else{return e(t.jQuery,t)}})(window,function(n,r){var i,o,l,s,f,u,c,a,h,d,p,y,v,w,g,m;i=n(r);a=t.call(r,"ontouchstart")>=0;s={horizontal:{},vertical:{}};f=1;c={};u="waypoints-context-id";p="resize.waypoints";y="scroll.waypoints";v=1;w="waypoints-waypoint-ids";g="waypoint";m="waypoints";o=function(){function t(t){var e=this;this.$element=t;this.element=t[0];this.didResize=false;this.didScroll=false;this.id="context"+f++;this.oldScroll={x:t.scrollLeft(),y:t.scrollTop()};this.waypoints={horizontal:{},vertical:{}};this.element[u]=this.id;c[this.id]=this;t.bind(y,function(){var t;if(!(e.didScroll||a)){e.didScroll=true;t=function(){e.doScroll();return e.didScroll=false};return r.setTimeout(t,n[m].settings.scrollThrottle)}});t.bind(p,function(){var t;if(!e.didResize){e.didResize=true;t=function(){n[m]("refresh");return e.didResize=false};return r.setTimeout(t,n[m].settings.resizeThrottle)}})}t.prototype.doScroll=function(){var t,e=this;t={horizontal:{newScroll:this.$element.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.$element.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};if(a&&(!t.vertical.oldScroll||!t.vertical.newScroll)){n[m]("refresh")}n.each(t,function(t,r){var i,o,l;l=[];o=r.newScroll>r.oldScroll;i=o?r.forward:r.backward;n.each(e.waypoints[t],function(t,e){var n,i;if(r.oldScroll<(n=e.offset)&&n<=r.newScroll){return l.push(e)}else if(r.newScroll<(i=e.offset)&&i<=r.oldScroll){return l.push(e)}});l.sort(function(t,e){return t.offset-e.offset});if(!o){l.reverse()}return n.each(l,function(t,e){if(e.options.continuous||t===l.length-1){return e.trigger([i])}})});return this.oldScroll={x:t.horizontal.newScroll,y:t.vertical.newScroll}};t.prototype.refresh=function(){var t,e,r,i=this;r=n.isWindow(this.element);e=this.$element.offset();this.doScroll();t={horizontal:{contextOffset:r?0:e.left,contextScroll:r?0:this.oldScroll.x,contextDimension:this.$element.width(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:r?0:e.top,contextScroll:r?0:this.oldScroll.y,contextDimension:r?n[m]("viewportHeight"):this.$element.height(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};return n.each(t,function(t,e){return n.each(i.waypoints[t],function(t,r){var i,o,l,s,f;i=r.options.offset;l=r.offset;o=n.isWindow(r.element)?0:r.$element.offset()[e.offsetProp];if(n.isFunction(i)){i=i.apply(r.element)}else if(typeof i==="string"){i=parseFloat(i);if(r.options.offset.indexOf("%")>-1){i=Math.ceil(e.contextDimension*i/100)}}r.offset=o-e.contextOffset+e.contextScroll-i;if(r.options.onlyOnScroll&&l!=null||!r.enabled){return}if(l!==null&&l<(s=e.oldScroll)&&s<=r.offset){return r.trigger([e.backward])}else if(l!==null&&l>(f=e.oldScroll)&&f>=r.offset){return r.trigger([e.forward])}else if(l===null&&e.oldScroll>=r.offset){return r.trigger([e.forward])}})})};t.prototype.checkEmpty=function(){if(n.isEmptyObject(this.waypoints.horizontal)&&n.isEmptyObject(this.waypoints.vertical)){this.$element.unbind([p,y].join(" "));return delete c[this.id]}};return t}();l=function(){function t(t,e,r){var i,o;if(r.offset==="bottom-in-view"){r.offset=function(){var t;t=n[m]("viewportHeight");if(!n.isWindow(e.element)){t=e.$element.height()}return t-n(this).outerHeight()}}this.$element=t;this.element=t[0];this.axis=r.horizontal?"horizontal":"vertical";this.callback=r.handler;this.context=e;this.enabled=r.enabled;this.id="waypoints"+v++;this.offset=null;this.options=r;e.waypoints[this.axis][this.id]=this;s[this.axis][this.id]=this;i=(o=this.element[w])!=null?o:[];i.push(this.id);this.element[w]=i}t.prototype.trigger=function(t){if(!this.enabled){return}if(this.callback!=null){this.callback.apply(this.element,t)}if(this.options.triggerOnce){return this.destroy()}};t.prototype.disable=function(){return this.enabled=false};t.prototype.enable=function(){this.context.refresh();return this.enabled=true};t.prototype.destroy=function(){delete s[this.axis][this.id];delete this.context.waypoints[this.axis][this.id];return this.context.checkEmpty()};t.getWaypointsByElement=function(t){var e,r;r=t[w];if(!r){return[]}e=n.extend({},s.horizontal,s.vertical);return n.map(r,function(t){return e[t]})};return t}();d={init:function(t,e){var r;e=n.extend({},n.fn[g].defaults,e);if((r=e.handler)==null){e.handler=t}this.each(function(){var t,r,i,s;t=n(this);i=(s=e.context)!=null?s:n.fn[g].defaults.context;if(!n.isWindow(i)){i=t.closest(i)}i=n(i);r=c[i[0][u]];if(!r){r=new o(i)}return new l(t,r,e)});n[m]("refresh");return this},disable:function(){return d._invoke.call(this,"disable")},enable:function(){return d._invoke.call(this,"enable")},destroy:function(){return d._invoke.call(this,"destroy")},prev:function(t,e){return d._traverse.call(this,t,e,function(t,e,n){if(e>0){return t.push(n[e-1])}})},next:function(t,e){return d._traverse.call(this,t,e,function(t,e,n){if(e<n.length-1){return t.push(n[e+1])}})},_traverse:function(t,e,i){var o,l;if(t==null){t="vertical"}if(e==null){e=r}l=h.aggregate(e);o=[];this.each(function(){var e;e=n.inArray(this,l[t]);return i(o,e,l[t])});return this.pushStack(o)},_invoke:function(t){this.each(function(){var e;e=l.getWaypointsByElement(this);return n.each(e,function(e,n){n[t]();return true})});return this}};n.fn[g]=function(){var t,r;r=arguments[0],t=2<=arguments.length?e.call(arguments,1):[];if(d[r]){return d[r].apply(this,t)}else if(n.isFunction(r)){return d.init.apply(this,arguments)}else if(n.isPlainObject(r)){return d.init.apply(this,[null,r])}else if(!r){return n.error("jQuery Waypoints needs a callback function or handler option.")}else{return n.error("The "+r+" method does not exist in jQuery Waypoints.")}};n.fn[g].defaults={context:r,continuous:true,enabled:true,horizontal:false,offset:0,triggerOnce:false};h={refresh:function(){return n.each(c,function(t,e){return e.refresh()})},viewportHeight:function(){var t;return(t=r.innerHeight)!=null?t:i.height()},aggregate:function(t){var e,r,i;e=s;if(t){e=(i=c[n(t)[0][u]])!=null?i.waypoints:void 0}if(!e){return[]}r={horizontal:[],vertical:[]};n.each(r,function(t,i){n.each(e[t],function(t,e){return i.push(e)});i.sort(function(t,e){return t.offset-e.offset});r[t]=n.map(i,function(t){return t.element});return r[t]=n.unique(r[t])});return r},above:function(t){if(t==null){t=r}return h._filter(t,"vertical",function(t,e){return e.offset<=t.oldScroll.y})},below:function(t){if(t==null){t=r}return h._filter(t,"vertical",function(t,e){return e.offset>t.oldScroll.y})},left:function(t){if(t==null){t=r}return h._filter(t,"horizontal",function(t,e){return e.offset<=t.oldScroll.x})},right:function(t){if(t==null){t=r}return h._filter(t,"horizontal",function(t,e){return e.offset>t.oldScroll.x})},enable:function(){return h._invoke("enable")},disable:function(){return h._invoke("disable")},destroy:function(){return h._invoke("destroy")},extendFn:function(t,e){return d[t]=e},_invoke:function(t){var e;e=n.extend({},s.vertical,s.horizontal);return n.each(e,function(e,n){n[t]();return true})},_filter:function(t,e,r){var i,o;i=c[n(t)[0][u]];if(!i){return[]}o=[];n.each(i.waypoints[e],function(t,e){if(r(i,e)){return o.push(e)}});o.sort(function(t,e){return t.offset-e.offset});return n.map(o,function(t){return t.element})}};n[m]=function(){var t,n;n=arguments[0],t=2<=arguments.length?e.call(arguments,1):[];if(h[n]){return h[n].apply(null,t)}else{return h.aggregate.call(null,n)}};n[m].settings={resizeThrottle:100,scrollThrottle:30};return i.on("load.waypoints",function(){return n[m]("refresh")})})}).call(this); //---------------------------------------- // Now the javascript has been setup this code triggers all the effects $(document).ready( function() { /* Waypoint script to add action when scroll onto objects */ /* This effect brought by http://imakewebthings.com/jquery-waypoints/ */ // This sets the Waypoint triggers // Waypoints is the easiest way to trigger a function when you scroll to an element. // this adds a scrolling action to elements but not the 'counting up' // delete the ones you dont use $( '#demo-latest-projects' ).waypoint(function() { $( '#demo-latest-projects' ).addClass( 'scroll-action' ); }, { offset: '70%' }) }); //---------------------------------------- })(jQuery); }, 0);
HTML
<div id="demo-latest-projects" class="appearing"> <h2 class="section-heading">Our latest projects</h2> <div class="grid-layout latest-projects"> <div class="grid-col"> <div class="project-item"> <a href="/media/joomlashine/jsn-mini/custom-html/738/1.jpg" class="modal link-tooltip" style="z-index: 90;" rel="{handler: 'iframe', size: {x: 640, y: 440}}"> <img src="/media/joomlashine/jsn-mini/custom-html/738/1.jpg" alt="" /> </a> </div> </div> <div class="grid-col"> <div class="project-item"> <a href="/media/joomlashine/jsn-mini/custom-html/738/2.jpg" class="modal link-tooltip" style="z-index: 90;" rel="{handler: 'iframe', size: {x: 640, y: 440}}"> <img src="/media/joomlashine/jsn-mini/custom-html/738/2.jpg" alt="" /> </a> </div> </div> <div class="grid-col"> <div class="project-item"> <a href="/media/joomlashine/jsn-mini/custom-html/738/3.jpg" class="modal link-tooltip" style="z-index: 90;" rel="{handler: 'iframe', size: {x: 640, y: 440}}"> <img src="/media/joomlashine/jsn-mini/custom-html/738/3.jpg" alt="" /> </a> </div> </div> <div class="grid-col"> <div class="project-item"> <a href="/media/joomlashine/jsn-mini/custom-html/738/4.jpg" class="modal link-tooltip" style="z-index: 90;" rel="{handler: 'iframe', size: {x: 640, y: 440}}"> <img src="/media/joomlashine/jsn-mini/custom-html/738/4.jpg" alt="" /> </a> </div> </div> </div> </div>
To use JSN-Mini-Icon font instead of FontAwesome icons
The 'Latest Projects' code above does not fully work because the JSN-Mini-Icon font is not available in this template, however you can use whatever font you want so i changed the following code to get it to work. Tthis assumes you have FontAwesome as part of your template or you have added it in with an extension.
Change #demo-latest-projects .latest-projects .project-item a:after { content: "\f00e"; font-family: 'FontAwesome'; To #demo-latest-projects .latest-projects .project-item a:after { content: "\e61e"; font-family: 'JSN-Mini-Icon';
Remove the circle with Font Icon in it (New version)
if you dont want that circle with font, you can just remove the following code which leaves the fade effect and leaves it like the new version of 'Latest Projects' in the JSN Mini demo. You could probably also just add display:none
/* This adds circle with a Icon via a font call on item hover */ #demo-latest-projects .latest-projects .project-item a:after { content: "\e61e"; font-family: 'JSN-Mini-Icon'; font-size: 1.6em; position: absolute; display: block; width: 80px; height: 80px; line-height: 70px; text-align: center; color: #fff; top: 40%; left: 50%; margin-top: -40px; margin-left: -40px; border: 3px solid #fff; border-radius: 100%; -moz-border-radius: 100%; -webkit-border-radius: 100%; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; z-index: 110; }
Code used to correct issues in this template
/* Correct gap between images in mobile view for this template */ @media only screen and (max-width: 480px), (max-device-width: 480px) { div.grid-col { margin-bottom: 0px; } }
Notes
- This is taken from the JSN Mini tempalte demo
- The animations will only work if you include the optional CSS and Javascript
-
I have also changed [class*="jsn-icon-"] to [class*="fa fa-"] to allow the use of FontAwesome instead of the JSN-Mini-Icon set which is not available.
- You can probably type messages/words instead of icons by changing font-family: 'FontAwesome'; to a normal font
- This code has a waypoint attached.
- Add the class jsn-demo-page to the page suffix to get the code to work
- To get this demo working without adding the page suffix jsn-demo-page I wrapped the code in
<div class="jsn-mobile jsn-demo-page"></div>
- This simulates adding the class but this technique can also be used if you want to use it in a module.
- You can remove the .jsn-demo-page from the CSS as another option instead of wrapping the CSS code in the<div> above.
- There is a new version of 'Latest Projects' without the use of icons. I will add it here at some point or you can check out the current demo at Joomlashine.