1+ /**
2+ * Template Name: iPortfolio - v3.2.0
3+ * Template URL: https://bootstrapmade.com/iportfolio-bootstrap-portfolio-websites-template/
4+ * Author: BootstrapMade.com
5+ * License: https://bootstrapmade.com/license/
6+ */
7+ ( function ( ) {
8+ "use strict" ;
9+
10+ /**
11+ * Easy selector helper function
12+ */
13+ const select = ( el , all = false ) => {
14+ el = el . trim ( )
15+ if ( all ) {
16+ return [ ...document . querySelectorAll ( el ) ]
17+ } else {
18+ return document . querySelector ( el )
19+ }
20+ }
21+
22+ /**
23+ * Easy event listener function
24+ */
25+ const on = ( type , el , listener , all = false ) => {
26+ let selectEl = select ( el , all )
27+ if ( selectEl ) {
28+ if ( all ) {
29+ selectEl . forEach ( e => e . addEventListener ( type , listener ) )
30+ } else {
31+ selectEl . addEventListener ( type , listener )
32+ }
33+ }
34+ }
35+
36+ /**
37+ * Easy on scroll event listener
38+ */
39+ const onscroll = ( el , listener ) => {
40+ el . addEventListener ( 'scroll' , listener )
41+ }
42+
43+ /**
44+ * Navbar links active state on scroll
45+ */
46+ let navbarlinks = select ( '#navbar .scrollto' , true )
47+ const navbarlinksActive = ( ) => {
48+ let position = window . scrollY + 200
49+ navbarlinks . forEach ( navbarlink => {
50+ if ( ! navbarlink . hash ) return
51+ let section = select ( navbarlink . hash )
52+ if ( ! section ) return
53+ if ( position >= section . offsetTop && position <= ( section . offsetTop + section . offsetHeight ) ) {
54+ navbarlink . classList . add ( 'active' )
55+ } else {
56+ navbarlink . classList . remove ( 'active' )
57+ }
58+ } )
59+ }
60+ window . addEventListener ( 'load' , navbarlinksActive )
61+ onscroll ( document , navbarlinksActive )
62+
63+ /**
64+ * Scrolls to an element with header offset
65+ */
66+ const scrollto = ( el ) => {
67+ let elementPos = select ( el ) . offsetTop
68+ window . scrollTo ( {
69+ top : elementPos ,
70+ behavior : 'smooth'
71+ } )
72+ }
73+
74+ /**
75+ * Back to top button
76+ */
77+ let backtotop = select ( '.back-to-top' )
78+ if ( backtotop ) {
79+ const toggleBacktotop = ( ) => {
80+ if ( window . scrollY > 100 ) {
81+ backtotop . classList . add ( 'active' )
82+ } else {
83+ backtotop . classList . remove ( 'active' )
84+ }
85+ }
86+ window . addEventListener ( 'load' , toggleBacktotop )
87+ onscroll ( document , toggleBacktotop )
88+ }
89+
90+ /**
91+ * Mobile nav toggle
92+ */
93+ on ( 'click' , '.mobile-nav-toggle' , function ( e ) {
94+ select ( 'body' ) . classList . toggle ( 'mobile-nav-active' )
95+ this . classList . toggle ( 'bi-list' )
96+ this . classList . toggle ( 'bi-x' )
97+ } )
98+
99+ /**
100+ * Scrool with ofset on links with a class name .scrollto
101+ */
102+ on ( 'click' , '.scrollto' , function ( e ) {
103+ if ( select ( this . hash ) ) {
104+ e . preventDefault ( )
105+
106+ let body = select ( 'body' )
107+ if ( body . classList . contains ( 'mobile-nav-active' ) ) {
108+ body . classList . remove ( 'mobile-nav-active' )
109+ let navbarToggle = select ( '.mobile-nav-toggle' )
110+ navbarToggle . classList . toggle ( 'bi-list' )
111+ navbarToggle . classList . toggle ( 'bi-x' )
112+ }
113+ scrollto ( this . hash )
114+ }
115+ } , true )
116+
117+ /**
118+ * Scroll with ofset on page load with hash links in the url
119+ */
120+ window . addEventListener ( 'load' , ( ) => {
121+ if ( window . location . hash ) {
122+ if ( select ( window . location . hash ) ) {
123+ scrollto ( window . location . hash )
124+ }
125+ }
126+ } ) ;
127+
128+ /**
129+ * Hero type effect
130+ */
131+ const typed = select ( '.typed' )
132+ if ( typed ) {
133+ let typed_strings = typed . getAttribute ( 'data-typed-items' )
134+ typed_strings = typed_strings . split ( ',' )
135+ new Typed ( '.typed' , {
136+ strings : typed_strings ,
137+ loop : true ,
138+ typeSpeed : 100 ,
139+ backSpeed : 50 ,
140+ backDelay : 2000
141+ } ) ;
142+ }
143+
144+ /**
145+ * Skills animation
146+ */
147+ let skilsContent = select ( '.skills-content' ) ;
148+ if ( skilsContent ) {
149+ new Waypoint ( {
150+ element : skilsContent ,
151+ offset : '80%' ,
152+ handler : function ( direction ) {
153+ let progress = select ( '.progress .progress-bar' , true ) ;
154+ progress . forEach ( ( el ) => {
155+ el . style . width = el . getAttribute ( 'aria-valuenow' ) + '%'
156+ } ) ;
157+ }
158+ } )
159+ }
160+
161+ /**
162+ * Porfolio isotope and filter
163+ */
164+ window . addEventListener ( 'load' , ( ) => {
165+ let portfolioContainer = select ( '.portfolio-container' ) ;
166+ if ( portfolioContainer ) {
167+ let portfolioIsotope = new Isotope ( portfolioContainer , {
168+ itemSelector : '.portfolio-item'
169+ } ) ;
170+
171+ let portfolioFilters = select ( '#portfolio-flters li' , true ) ;
172+
173+ on ( 'click' , '#portfolio-flters li' , function ( e ) {
174+ e . preventDefault ( ) ;
175+ portfolioFilters . forEach ( function ( el ) {
176+ el . classList . remove ( 'filter-active' ) ;
177+ } ) ;
178+ this . classList . add ( 'filter-active' ) ;
179+
180+ portfolioIsotope . arrange ( {
181+ filter : this . getAttribute ( 'data-filter' )
182+ } ) ;
183+ portfolioIsotope . on ( 'arrangeComplete' , function ( ) {
184+ AOS . refresh ( )
185+ } ) ;
186+ } , true ) ;
187+ }
188+
189+ } ) ;
190+
191+ /**
192+ * Initiate portfolio lightbox
193+ */
194+ const portfolioLightbox = GLightbox ( {
195+ selector : '.portfolio-lightbox'
196+ } ) ;
197+
198+ /**
199+ * Portfolio details slider
200+ */
201+ new Swiper ( '.portfolio-details-slider' , {
202+ speed : 400 ,
203+ loop : true ,
204+ autoplay : {
205+ delay : 5000 ,
206+ disableOnInteraction : false
207+ } ,
208+ pagination : {
209+ el : '.swiper-pagination' ,
210+ type : 'bullets' ,
211+ clickable : true
212+ }
213+ } ) ;
214+
215+ /**
216+ * Testimonials slider
217+ */
218+ new Swiper ( '.testimonials-slider' , {
219+ speed : 600 ,
220+ loop : true ,
221+ autoplay : {
222+ delay : 5000 ,
223+ disableOnInteraction : false
224+ } ,
225+ slidesPerView : 'auto' ,
226+ pagination : {
227+ el : '.swiper-pagination' ,
228+ type : 'bullets' ,
229+ clickable : true
230+ } ,
231+ breakpoints : {
232+ 320 : {
233+ slidesPerView : 1 ,
234+ spaceBetween : 20
235+ } ,
236+
237+ 1200 : {
238+ slidesPerView : 3 ,
239+ spaceBetween : 20
240+ }
241+ }
242+ } ) ;
243+
244+ /**
245+ * Animation on scroll
246+ */
247+ window . addEventListener ( 'load' , ( ) => {
248+ AOS . init ( {
249+ duration : 1000 ,
250+ easing : 'ease-in-out' ,
251+ once : true ,
252+ mirror : false
253+ } )
254+ } ) ;
255+
256+ } ) ( )
0 commit comments