├── img ├── menu.png ├── lemnis1.png ├── lemnis2.png └── lemnisabout.png ├── .github └── workflows │ └── node.js.yml ├── js ├── countUp-jquery.js ├── script.js ├── jquery.easypiechart.min.js ├── countUp.min.js ├── countUp.js ├── jquery.superslides.min.js ├── typed.min.js └── owl.carousel.min.js ├── LICENSE ├── css ├── superslides.css ├── owl.carousel.min.css └── style.css ├── README.md └── index.html /img/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Subuthai/VerySimplePortfolio/HEAD/img/menu.png -------------------------------------------------------------------------------- /img/lemnis1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Subuthai/VerySimplePortfolio/HEAD/img/lemnis1.png -------------------------------------------------------------------------------- /img/lemnis2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Subuthai/VerySimplePortfolio/HEAD/img/lemnis2.png -------------------------------------------------------------------------------- /img/lemnisabout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Subuthai/VerySimplePortfolio/HEAD/img/lemnisabout.png -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [12.x, 14.x, 16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: 'npm' 29 | - run: npm ci 30 | - run: npm run build --if-present 31 | - run: npm test 32 | -------------------------------------------------------------------------------- /js/countUp-jquery.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | $.fn.countup = function (params) { 3 | // make sure dependency is present 4 | if (typeof CountUp !== "function") { 5 | console.error( 6 | "countUp.js is a required dependency of countUp-jquery.js." 7 | ); 8 | return; 9 | } 10 | 11 | var defaults = { 12 | startVal: 0, 13 | decimals: 0, 14 | duration: 2, 15 | }; 16 | 17 | if (typeof params === "number") { 18 | defaults.endVal = params; 19 | } else if (typeof params === "object") { 20 | $.extend(defaults, params); 21 | } else { 22 | console.error( 23 | "countUp-jquery requires its argument to be either an object or number" 24 | ); 25 | return; 26 | } 27 | 28 | this.each(function (i, elem) { 29 | var countUp = new CountUp( 30 | elem, 31 | defaults.startVal, 32 | defaults.endVal, 33 | defaults.decimals, 34 | defaults.duration, 35 | defaults.options 36 | ); 37 | 38 | countUp.start(); 39 | }); 40 | 41 | return this; 42 | }; 43 | })(jQuery); 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Subuthai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /css/superslides.css: -------------------------------------------------------------------------------- 1 | #slides { 2 | position: relative; 3 | } 4 | #slides .slides-container { 5 | display: none; 6 | } 7 | #slides .scrollable { 8 | *zoom: 1; 9 | position: relative; 10 | top: 0; 11 | left: 0; 12 | overflow-y: auto; 13 | -webkit-overflow-scrolling: touch; 14 | height: 100%; 15 | } 16 | #slides .scrollable:after { 17 | content: ""; 18 | display: table; 19 | clear: both; 20 | } 21 | 22 | .slides-navigation { 23 | margin: 0 auto; 24 | position: absolute; 25 | z-index: 3; 26 | top: 46%; 27 | width: 100%; 28 | } 29 | .slides-navigation a { 30 | position: absolute; 31 | display: block; 32 | } 33 | 34 | .slides-pagination { 35 | position: absolute; 36 | z-index: 3; 37 | bottom: 0; 38 | text-align: center; 39 | width: 100%; 40 | } 41 | .slides-pagination a { 42 | border: 2px solid #222; 43 | border-radius: 15px; 44 | width: 10px; 45 | height: 10px; 46 | display: -moz-inline-stack; 47 | display: inline-block; 48 | vertical-align: middle; 49 | *vertical-align: auto; 50 | zoom: 1; 51 | *display: inline; 52 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII="); 53 | margin: 2px; 54 | overflow: hidden; 55 | text-indent: -100%; 56 | } 57 | .slides-pagination a.current { 58 | background: #222; 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Very Simple Portfolio (literally very simple) 2 | 3 | ### A very simple portfolio page made with HTML, CSS & JS. 4 | 5 | - First of all, this is my first open source project. So please show me some respect and star my project. 🤠 6 | - Used isotope, typed, owlcarousel and more stuffs. 7 | - Responsive & mobile-friendly. (I think so 🤠) 8 | - And yes, It's not very pleasing to eyes, I know. 9 | - Take a look: https://subuthai.github.io/VerySimplePortfolio/ 10 | 11 | ### Contact me: 12 | 13 | [subuthai.xyz][website] 14 | [subuthai | YouTube][youtube] 15 | [subuthai_ | Twitter][twitter] 16 | [subuthai_ | Instagram][instagram] 17 | [subuthai_ | Discord][discord] 18 | 19 | [website]: https://subuthai.xyz 20 | [twitter]: https://twitter.com/subuthai_ 21 | [youtube]: https://youtube.com/Subuthai 22 | [instagram]: https://instagram.com/subuthai_ 23 | [discord]: https://discord.gg/yBPcHQcVjB 24 | -------------------------------------------------------------------------------- /js/script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $("#slides").superslides({ 3 | animation: "fade", 4 | play: 5000, 5 | pagination: false, 6 | }); 7 | 8 | var typed = new Typed(".typed", { 9 | strings: ["Jr. Full-Stack", "Video Editor", "Discord Bot Developer"], 10 | typeSpeed: 60, 11 | startDelay: 900, 12 | showCursor: false, 13 | loop: true, 14 | backDelay: 900, 15 | backSpeed: 40, 16 | }); 17 | 18 | $(".owl-carousel").owlCarousel({ 19 | loop: true, 20 | items: 4, 21 | responsive: { 22 | 0: { 23 | items: 1, 24 | }, 25 | 480: { 26 | items: 2, 27 | }, 28 | 768: { 29 | items: 3, 30 | }, 31 | 938: { 32 | items: 4, 33 | }, 34 | }, 35 | }); 36 | 37 | var skillsTopOffset = $(".skillsSection").offset().top; 38 | var statsTopOffset = $(".statsSection").offset().top; 39 | var countUpFinished = false; 40 | 41 | $(window).scroll(function () { 42 | if (window.pageYOffset > skillsTopOffset - $(window).height() + 200) { 43 | $(".chart").easyPieChart({ 44 | easing: "easeInOut", 45 | barColor: "#fff", 46 | trackColor: false, 47 | scaleColor: false, 48 | lineWidth: 4, 49 | size: 152, 50 | onStep: function (from, to, percent) { 51 | $(this.el).find(".percent").text(Math.round(percent)); 52 | }, 53 | }); 54 | } 55 | if ( 56 | !countUpFinished && 57 | window.pageYOffset > statsTopOffset - $(window).height() + 200 58 | ) { 59 | $(".counter").each(function () { 60 | var element = $(this); 61 | var endVal = parseInt(element.text()); 62 | element.countup(endVal); 63 | }); 64 | countUpFinished = true; 65 | } 66 | }); 67 | 68 | $("[data-fancybox]").fancybox(); 69 | $("#filters a").click(function () { 70 | $("#filters .current").removeClass("current"); 71 | $(this).addClass("current"); 72 | 73 | var selector = $(this).attr("data-filter"); 74 | 75 | $(".items").isotope({ 76 | filter: selector, 77 | animationOptions: { 78 | duration: 1500, 79 | easing: "linear", 80 | queue: false, 81 | }, 82 | }); 83 | return false; 84 | }); 85 | 86 | $("#navigation li a").click(function (e) { 87 | e.preventDefault(); 88 | var targetElement = $(this).attr("href"); 89 | var targetPosition = $(targetElement).offset().top; 90 | $("html, body").animate({ scrollTop: targetPosition - 50 }, "slow"); 91 | }); 92 | 93 | const nav = $("#navigation"); 94 | const navTop = nav.offset().top; 95 | 96 | $(window).on("scroll", stickyNavigation); 97 | 98 | function stickyNavigation() { 99 | var body = $("body"); 100 | if ($(window).scrollTop() >= navTop) { 101 | body.css("padding-top", nav.outerHeight() + "px"); 102 | body.addClass("fixedNav"); 103 | } else { 104 | body.css("padding-top", 0); 105 | body.removeClass("fixedNav"); 106 | } 107 | } 108 | }); 109 | -------------------------------------------------------------------------------- /css/owl.carousel.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Owl Carousel v2.3.4 3 | * Copyright 2013-2018 David Deutsch 4 | * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE 5 | */ 6 | .owl-carousel, 7 | .owl-carousel .owl-item { 8 | -webkit-tap-highlight-color: transparent; 9 | position: relative; 10 | } 11 | .owl-carousel { 12 | display: none; 13 | width: 100%; 14 | z-index: 1; 15 | } 16 | .owl-carousel .owl-stage { 17 | position: relative; 18 | -ms-touch-action: pan-Y; 19 | touch-action: manipulation; 20 | -moz-backface-visibility: hidden; 21 | } 22 | .owl-carousel .owl-stage:after { 23 | content: "."; 24 | display: block; 25 | clear: both; 26 | visibility: hidden; 27 | line-height: 0; 28 | height: 0; 29 | } 30 | .owl-carousel .owl-stage-outer { 31 | position: relative; 32 | overflow: hidden; 33 | -webkit-transform: translate3d(0, 0, 0); 34 | } 35 | .owl-carousel .owl-item, 36 | .owl-carousel .owl-wrapper { 37 | -webkit-backface-visibility: hidden; 38 | -moz-backface-visibility: hidden; 39 | -ms-backface-visibility: hidden; 40 | -webkit-transform: translate3d(0, 0, 0); 41 | -moz-transform: translate3d(0, 0, 0); 42 | -ms-transform: translate3d(0, 0, 0); 43 | } 44 | .owl-carousel .owl-item { 45 | min-height: 1px; 46 | float: left; 47 | -webkit-backface-visibility: hidden; 48 | -webkit-touch-callout: none; 49 | } 50 | .owl-carousel .owl-item img { 51 | display: block; 52 | width: 100%; 53 | } 54 | .owl-carousel .owl-dots.disabled, 55 | .owl-carousel .owl-nav.disabled { 56 | display: none; 57 | } 58 | .no-js .owl-carousel, 59 | .owl-carousel.owl-loaded { 60 | display: block; 61 | } 62 | .owl-carousel .owl-dot, 63 | .owl-carousel .owl-nav .owl-next, 64 | .owl-carousel .owl-nav .owl-prev { 65 | cursor: pointer; 66 | -webkit-user-select: none; 67 | -khtml-user-select: none; 68 | -moz-user-select: none; 69 | -ms-user-select: none; 70 | user-select: none; 71 | } 72 | .owl-carousel .owl-nav button.owl-next, 73 | .owl-carousel .owl-nav button.owl-prev, 74 | .owl-carousel button.owl-dot { 75 | background: 0 0; 76 | color: inherit; 77 | border: none; 78 | padding: 0 !important; 79 | font: inherit; 80 | } 81 | .owl-carousel.owl-loading { 82 | opacity: 0; 83 | display: block; 84 | } 85 | .owl-carousel.owl-hidden { 86 | opacity: 0; 87 | } 88 | .owl-carousel.owl-refresh .owl-item { 89 | visibility: hidden; 90 | } 91 | .owl-carousel.owl-drag .owl-item { 92 | -ms-touch-action: pan-y; 93 | touch-action: pan-y; 94 | -webkit-user-select: none; 95 | -moz-user-select: none; 96 | -ms-user-select: none; 97 | user-select: none; 98 | } 99 | .owl-carousel.owl-grab { 100 | cursor: move; 101 | cursor: grab; 102 | } 103 | .owl-carousel.owl-rtl { 104 | direction: rtl; 105 | } 106 | .owl-carousel.owl-rtl .owl-item { 107 | float: right; 108 | } 109 | .owl-carousel .animated { 110 | animation-duration: 1s; 111 | animation-fill-mode: both; 112 | } 113 | .owl-carousel .owl-animated-in { 114 | z-index: 0; 115 | } 116 | .owl-carousel .owl-animated-out { 117 | z-index: 1; 118 | } 119 | .owl-carousel .fadeOut { 120 | animation-name: fadeOut; 121 | } 122 | @keyframes fadeOut { 123 | 0% { 124 | opacity: 1; 125 | } 126 | 100% { 127 | opacity: 0; 128 | } 129 | } 130 | .owl-height { 131 | transition: height 0.5s ease-in-out; 132 | } 133 | .owl-carousel .owl-item .owl-lazy { 134 | opacity: 0; 135 | transition: opacity 0.4s ease; 136 | } 137 | .owl-carousel .owl-item .owl-lazy:not([src]), 138 | .owl-carousel .owl-item .owl-lazy[src^=""] { 139 | max-height: 0; 140 | } 141 | .owl-carousel .owl-item img.owl-lazy { 142 | transform-style: preserve-3d; 143 | } 144 | .owl-carousel .owl-video-wrapper { 145 | position: relative; 146 | height: 100%; 147 | background: #000; 148 | } 149 | .owl-carousel .owl-video-play-icon { 150 | position: absolute; 151 | height: 80px; 152 | width: 80px; 153 | left: 50%; 154 | top: 50%; 155 | margin-left: -40px; 156 | margin-top: -40px; 157 | background: url(owl.video.play.png) no-repeat; 158 | cursor: pointer; 159 | z-index: 1; 160 | -webkit-backface-visibility: hidden; 161 | transition: transform 0.1s ease; 162 | } 163 | .owl-carousel .owl-video-play-icon:hover { 164 | -ms-transform: scale(1.3, 1.3); 165 | transform: scale(1.3, 1.3); 166 | } 167 | .owl-carousel .owl-video-playing .owl-video-play-icon, 168 | .owl-carousel .owl-video-playing .owl-video-tn { 169 | display: none; 170 | } 171 | .owl-carousel .owl-video-tn { 172 | opacity: 0; 173 | height: 100%; 174 | background-position: center center; 175 | background-repeat: no-repeat; 176 | background-size: contain; 177 | transition: opacity 0.4s ease; 178 | } 179 | .owl-carousel .owl-video-frame { 180 | position: relative; 181 | z-index: 1; 182 | height: 100%; 183 | width: 100%; 184 | } 185 | -------------------------------------------------------------------------------- /js/jquery.easypiechart.min.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * easy-pie-chart 3 | * Lightweight plugin to render simple, animated and retina optimized pie charts 4 | * 5 | * @license 6 | * @author Robert Fleischmann (http://robert-fleischmann.de) 7 | * @version 2.1.7 8 | **/ 9 | !(function (a, b) { 10 | "function" == typeof define && define.amd 11 | ? define(["jquery"], function (a) { 12 | return b(a); 13 | }) 14 | : "object" == typeof exports 15 | ? (module.exports = b(require("jquery"))) 16 | : b(jQuery); 17 | })(this, function (a) { 18 | var b = function (a, b) { 19 | var c, 20 | d = document.createElement("canvas"); 21 | a.appendChild(d), 22 | "object" == typeof G_vmlCanvasManager && 23 | G_vmlCanvasManager.initElement(d); 24 | var e = d.getContext("2d"); 25 | d.width = d.height = b.size; 26 | var f = 1; 27 | window.devicePixelRatio > 1 && 28 | ((f = window.devicePixelRatio), 29 | (d.style.width = d.style.height = [b.size, "px"].join("")), 30 | (d.width = d.height = b.size * f), 31 | e.scale(f, f)), 32 | e.translate(b.size / 2, b.size / 2), 33 | e.rotate((-0.5 + b.rotate / 180) * Math.PI); 34 | var g = (b.size - b.lineWidth) / 2; 35 | b.scaleColor && b.scaleLength && (g -= b.scaleLength + 2), 36 | (Date.now = 37 | Date.now || 38 | function () { 39 | return +new Date(); 40 | }); 41 | var h = function (a, b, c) { 42 | c = Math.min(Math.max(-1, c || 0), 1); 43 | var d = 0 >= c ? !0 : !1; 44 | e.beginPath(), 45 | e.arc(0, 0, g, 0, 2 * Math.PI * c, d), 46 | (e.strokeStyle = a), 47 | (e.lineWidth = b), 48 | e.stroke(); 49 | }, 50 | i = function () { 51 | var a, c; 52 | (e.lineWidth = 1), (e.fillStyle = b.scaleColor), e.save(); 53 | for (var d = 24; d > 0; --d) 54 | d % 6 === 0 55 | ? ((c = b.scaleLength), (a = 0)) 56 | : ((c = 0.6 * b.scaleLength), (a = b.scaleLength - c)), 57 | e.fillRect(-b.size / 2 + a, 0, c, 1), 58 | e.rotate(Math.PI / 12); 59 | e.restore(); 60 | }, 61 | j = (function () { 62 | return ( 63 | window.requestAnimationFrame || 64 | window.webkitRequestAnimationFrame || 65 | window.mozRequestAnimationFrame || 66 | function (a) { 67 | window.setTimeout(a, 1e3 / 60); 68 | } 69 | ); 70 | })(), 71 | k = function () { 72 | b.scaleColor && i(), 73 | b.trackColor && h(b.trackColor, b.trackWidth || b.lineWidth, 1); 74 | }; 75 | (this.getCanvas = function () { 76 | return d; 77 | }), 78 | (this.getCtx = function () { 79 | return e; 80 | }), 81 | (this.clear = function () { 82 | e.clearRect(b.size / -2, b.size / -2, b.size, b.size); 83 | }), 84 | (this.draw = function (a) { 85 | b.scaleColor || b.trackColor 86 | ? e.getImageData && e.putImageData 87 | ? c 88 | ? e.putImageData(c, 0, 0) 89 | : (k(), (c = e.getImageData(0, 0, b.size * f, b.size * f))) 90 | : (this.clear(), k()) 91 | : this.clear(), 92 | (e.lineCap = b.lineCap); 93 | var d; 94 | (d = "function" == typeof b.barColor ? b.barColor(a) : b.barColor), 95 | h(d, b.lineWidth, a / 100); 96 | }.bind(this)), 97 | (this.animate = function (a, c) { 98 | var d = Date.now(); 99 | b.onStart(a, c); 100 | var e = function () { 101 | var f = Math.min(Date.now() - d, b.animate.duration), 102 | g = b.easing(this, f, a, c - a, b.animate.duration); 103 | this.draw(g), 104 | b.onStep(a, c, g), 105 | f >= b.animate.duration ? b.onStop(a, c) : j(e); 106 | }.bind(this); 107 | j(e); 108 | }.bind(this)); 109 | }, 110 | c = function (a, c) { 111 | var d = { 112 | barColor: "#ef1e25", 113 | trackColor: "#f9f9f9", 114 | scaleColor: "#dfe0e0", 115 | scaleLength: 5, 116 | lineCap: "round", 117 | lineWidth: 3, 118 | trackWidth: void 0, 119 | size: 110, 120 | rotate: 0, 121 | animate: { duration: 1e3, enabled: !0 }, 122 | easing: function (a, b, c, d, e) { 123 | return ( 124 | (b /= e / 2), 125 | 1 > b ? (d / 2) * b * b + c : (-d / 2) * (--b * (b - 2) - 1) + c 126 | ); 127 | }, 128 | onStart: function (a, b) {}, 129 | onStep: function (a, b, c) {}, 130 | onStop: function (a, b) {}, 131 | }; 132 | if ("undefined" != typeof b) d.renderer = b; 133 | else { 134 | if ("undefined" == typeof SVGRenderer) 135 | throw new Error("Please load either the SVG- or the CanvasRenderer"); 136 | d.renderer = SVGRenderer; 137 | } 138 | var e = {}, 139 | f = 0, 140 | g = function () { 141 | (this.el = a), (this.options = e); 142 | for (var b in d) 143 | d.hasOwnProperty(b) && 144 | ((e[b] = c && "undefined" != typeof c[b] ? c[b] : d[b]), 145 | "function" == typeof e[b] && (e[b] = e[b].bind(this))); 146 | "string" == typeof e.easing && 147 | "undefined" != typeof jQuery && 148 | jQuery.isFunction(jQuery.easing[e.easing]) 149 | ? (e.easing = jQuery.easing[e.easing]) 150 | : (e.easing = d.easing), 151 | "number" == typeof e.animate && 152 | (e.animate = { duration: e.animate, enabled: !0 }), 153 | "boolean" != typeof e.animate || 154 | e.animate || 155 | (e.animate = { duration: 1e3, enabled: e.animate }), 156 | (this.renderer = new e.renderer(a, e)), 157 | this.renderer.draw(f), 158 | a.dataset && a.dataset.percent 159 | ? this.update(parseFloat(a.dataset.percent)) 160 | : a.getAttribute && 161 | a.getAttribute("data-percent") && 162 | this.update(parseFloat(a.getAttribute("data-percent"))); 163 | }.bind(this); 164 | (this.update = function (a) { 165 | return ( 166 | (a = parseFloat(a)), 167 | e.animate.enabled 168 | ? this.renderer.animate(f, a) 169 | : this.renderer.draw(a), 170 | (f = a), 171 | this 172 | ); 173 | }.bind(this)), 174 | (this.disableAnimation = function () { 175 | return (e.animate.enabled = !1), this; 176 | }), 177 | (this.enableAnimation = function () { 178 | return (e.animate.enabled = !0), this; 179 | }), 180 | g(); 181 | }; 182 | a.fn.easyPieChart = function (b) { 183 | return this.each(function () { 184 | var d; 185 | a.data(this, "easyPieChart") || 186 | ((d = a.extend({}, b, a(this).data())), 187 | a.data(this, "easyPieChart", new c(this, d))); 188 | }); 189 | }; 190 | }); 191 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 14px; 3 | color: #333; 4 | background-color: #fff; 5 | letter-spacing: 1px; 6 | } 7 | 8 | .overlay { 9 | width: 100%; 10 | height: 100%; 11 | position: absolute; 12 | z-index: 3; 13 | background-color: rgba(0, 0, 0, 0.4); 14 | } 15 | 16 | .slides-navigation { 17 | z-index: 6; 18 | } 19 | 20 | .titleMessage { 21 | position: absolute; 22 | width: 100%; 23 | height: 250px; 24 | top: 50%; 25 | z-index: 5; 26 | text-align: center; 27 | margin-top: -125px; 28 | } 29 | 30 | .titleMessage .heading p { 31 | color: #fff; 32 | text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.4); 33 | font-weight: 100; 34 | letter-spacing: 7px; 35 | } 36 | 37 | .titleMessage .heading .main { 38 | font-size: 50px; 39 | } 40 | 41 | .titleMessage .heading .sub { 42 | font-size: 23px; 43 | } 44 | 45 | .section { 46 | background-color: rgb(27, 27, 27); 47 | color: rgb(151, 150, 150); 48 | padding: 100px 0; 49 | } 50 | 51 | .aboutImage { 52 | max-width: 100%; 53 | } 54 | 55 | .skillsSection { 56 | background: linear-gradient( 57 | 270deg, 58 | rgba(2, 0, 36, 1) 0%, 59 | rgba(9, 9, 121, 1) 0%, 60 | rgba(15, 124, 5, 1) 0%, 61 | rgba(0, 90, 143, 1) 100% 62 | ); 63 | color: #fff; 64 | } 65 | 66 | .contactSection { 67 | background: linear-gradient( 68 | 90deg, 69 | rgba(2, 0, 36, 1) 0%, 70 | rgba(9, 9, 121, 1) 0%, 71 | rgba(15, 124, 5, 1) 0%, 72 | rgba(0, 90, 143, 1) 100% 73 | ); 74 | color: #fff; 75 | } 76 | 77 | .skill { 78 | text-align: center; 79 | margin-left: 10px; 80 | } 81 | 82 | .chart { 83 | position: relative; 84 | width: 152px; 85 | height: 152px; 86 | display: inline-block; 87 | text-align: center; 88 | } 89 | 90 | .chart canvas { 91 | position: absolute; 92 | left: 0; 93 | top: 0; 94 | } 95 | 96 | .chart .percent { 97 | color: #000; 98 | line-height: 152px; 99 | display: inline-block; 100 | font-size: 35px; 101 | } 102 | 103 | .chart .percent:after { 104 | content: "%"; 105 | } 106 | 107 | .squareItem { 108 | margin-top: 30px; 109 | position: relative; 110 | } 111 | 112 | .squareInnerContainer { 113 | position: relative; 114 | padding: 50px 15px 35px; 115 | text-align: center; 116 | border: 2px solid #444; 117 | border-top: none; 118 | } 119 | 120 | .squareInnerContainer:before, 121 | .squareInnerContainer:after { 122 | content: ""; 123 | position: absolute; 124 | top: 0px; 125 | width: 30%; 126 | border-bottom: 2px solid #444; 127 | } 128 | 129 | .squareInnerContainer:before { 130 | right: 0px; 131 | } 132 | 133 | .squareInnerContainer:after { 134 | left: 0px; 135 | } 136 | 137 | .squareContent h2 { 138 | font-size: 56px; 139 | margin-bottom: 10px; 140 | font-weight: 400; 141 | color: linear-gradient( 142 | 270deg, 143 | rgba(2, 0, 36, 1) 0%, 144 | rgba(9, 9, 121, 1) 0%, 145 | rgba(19, 146, 7, 1) 0%, 146 | rgba(0, 212, 255, 1) 100% 147 | ); 148 | } 149 | 150 | .squareContent h3 { 151 | font-size: 13px; 152 | font-weight: 600px; 153 | margin: 0; 154 | } 155 | 156 | .squareIcon { 157 | position: absolute; 158 | left: 50%; 159 | top: -30px; 160 | width: 40%; 161 | height: 50px; 162 | font-size: 45px; 163 | margin-left: -20%; 164 | color: #444; 165 | } 166 | 167 | .contactButton { 168 | color: #fff; 169 | padding: 15px 20px; 170 | display: inline-block; 171 | margin-top: 20px; 172 | border: 1px solid #fff; 173 | border-radius: 2px; 174 | } 175 | 176 | .contactButton:hover { 177 | text-decoration: none; 178 | color: #ffff; 179 | background: linear-gradient( 180 | 270deg, 181 | rgba(2, 0, 36, 1) 0%, 182 | rgba(9, 9, 121, 1) 0%, 183 | rgba(19, 146, 7, 1) 0%, 184 | rgba(0, 212, 255, 1) 100% 185 | ); 186 | opacity: 0.7; 187 | transition: 0.3s; 188 | } 189 | 190 | .filter a { 191 | color: #bdc3c7; 192 | border: 1px solid #bdc3c7; 193 | padding: 10px 18px; 194 | display: block; 195 | } 196 | 197 | .filter li { 198 | display: inline-block; 199 | padding: 5px; 200 | } 201 | 202 | .filter .current { 203 | background: linear-gradient( 204 | 270deg, 205 | rgba(2, 0, 36, 1) 0%, 206 | rgba(9, 9, 121, 1) 0%, 207 | rgba(19, 146, 7, 1) 0%, 208 | rgba(0, 212, 255, 1) 100% 209 | ); 210 | border-color: linear-gradient( 211 | 270deg, 212 | rgba(2, 0, 36, 1) 0%, 213 | rgba(9, 9, 121, 1) 0%, 214 | rgba(19, 146, 7, 1) 0%, 215 | rgba(0, 212, 255, 1) 100% 216 | ); 217 | color: #fff; 218 | } 219 | 220 | .filter { 221 | text-align: center; 222 | width: 100%; 223 | } 224 | 225 | .section .heading { 226 | text-align: center; 227 | padding-bottom: 40px; 228 | width: 100%; 229 | } 230 | 231 | .items li { 232 | display: inline-block; 233 | padding: 5px; 234 | } 235 | 236 | .itemsContainer { 237 | width: 100%; 238 | } 239 | 240 | .items li img { 241 | width: 100%; 242 | 243 | -webkit-transition: all 0.2s linear, 1s; 244 | -moz-transition: all 0.2s linear, 1s; 245 | -o-transition: all 0.2s linear, 1s; 246 | -ms-transition: all 0.2s linear, 1s; 247 | -transition: all 0.2s linear, 1s; 248 | } 249 | 250 | .items .item { 251 | position: relative; 252 | display: block; 253 | overflow: hidden; 254 | } 255 | 256 | .items .icons { 257 | position: absolute; 258 | width: 90px; 259 | height: 40px; 260 | left: 50%; 261 | top: 50%; 262 | margin: -20px auto 0 -47px; 263 | text-align: center; 264 | z-index: 3; 265 | } 266 | 267 | .items .icons i { 268 | text-shadow: 2px 2px 8px #fff; 269 | color: #fff; 270 | font-size: 20px; 271 | margin-top: 9px; 272 | } 273 | 274 | .items a { 275 | width: 40px; 276 | height: 40px; 277 | background-color: rgba(12, 36, 97, 0.3); 278 | position: relative; 279 | display: inline-block; 280 | 281 | -webkit-transition: all 0.2s linear, 0.5s; 282 | -moz-transition: all 0.2s linear, 0.5s; 283 | -o-transition: all 0.2s linear, 0.5s; 284 | -ms-transition: all 0.2s linear, 0.5s; 285 | -transition: all 0.2s linear, 0.5s; 286 | } 287 | 288 | .items .imageOverlay { 289 | width: 100%; 290 | height: 100%; 291 | background-color: rgba(0, 0, 0, 0.89); 292 | position: absolute; 293 | top: 0px; 294 | left: 0px; 295 | opacity: 0; 296 | 297 | -webkit-transition: all 0.2s linear, 1s; 298 | -moz-transition: all 0.2s linear, 1s; 299 | -o-transition: all 0.2s linear, 1s; 300 | -ms-transition: all 0.2s linear, 1s; 301 | -transition: all 0.2s linear, 1s; 302 | } 303 | 304 | .items .item:hover .imageOverlay { 305 | opacity: 1; 306 | } 307 | 308 | .items .openButton { 309 | float: left; 310 | left: -200px; 311 | } 312 | 313 | .items .projectLink { 314 | float: right; 315 | right: -200px; 316 | } 317 | 318 | .items .item:hover .openButton { 319 | left: 0px; 320 | } 321 | 322 | .items .item:hover .projectLink { 323 | right: 0px; 324 | } 325 | 326 | .items .item:hover img { 327 | -webkit-transform: scale(1.05, 1.05); 328 | -moz-transform: scale(1.05, 1.05); 329 | -o-transform: scale(1.05, 1.05); 330 | -ms-transform: scale(1.05, 1.05); 331 | -transform: scale(1.05, 1.05); 332 | } 333 | 334 | .items { 335 | padding: 0; 336 | } 337 | 338 | .copyrightSection { 339 | background-color: #000; 340 | color: #fff; 341 | padding: 30px 5px; 342 | } 343 | 344 | .copyrightSection p { 345 | margin: 0; 346 | } 347 | 348 | #navigation { 349 | background: linear-gradient( 350 | 90deg, 351 | rgba(2, 0, 36, 1) 0%, 352 | rgba(9, 9, 121, 1) 0%, 353 | rgba(15, 124, 5, 1) 0%, 354 | rgba(0, 90, 143, 1) 100% 355 | ); 356 | padding: 20px 10px; 357 | z-index: 100; 358 | width: 100%; 359 | } 360 | 361 | #navigation li { 362 | padding: 0 10px; 363 | } 364 | 365 | #navigation li a { 366 | color: #fff; 367 | } 368 | 369 | #navigation li a:hover { 370 | color: rgb(0, 57, 90); 371 | opacity: 0.6; 372 | transition: 0.3s; 373 | } 374 | 375 | .navbar-brand, 376 | .navbar-brand:hover { 377 | color: #000; 378 | } 379 | 380 | .navbar-toggler-icon { 381 | background: url(../img/menu.png); 382 | background-size: 100%; 383 | } 384 | 385 | .fixedNav #navigation { 386 | position: fixed; 387 | top: 0; 388 | } 389 | -------------------------------------------------------------------------------- /js/countUp.min.js: -------------------------------------------------------------------------------- 1 | var __assign = 2 | (this && this.__assign) || 3 | function () { 4 | return (__assign = 5 | Object.assign || 6 | function (t) { 7 | for (var i, a = 1, s = arguments.length; a < s; a++) 8 | for (var n in (i = arguments[a])) 9 | Object.prototype.hasOwnProperty.call(i, n) && (t[n] = i[n]); 10 | return t; 11 | }).apply(this, arguments); 12 | }, 13 | CountUp = (function () { 14 | function t(t, i, a) { 15 | var s = this; 16 | (this.target = t), 17 | (this.endVal = i), 18 | (this.options = a), 19 | (this.version = "2.0.4"), 20 | (this.defaults = { 21 | startVal: 0, 22 | decimalPlaces: 0, 23 | duration: 2, 24 | useEasing: !0, 25 | useGrouping: !0, 26 | smartEasingThreshold: 999, 27 | smartEasingAmount: 333, 28 | separator: ",", 29 | decimal: ".", 30 | prefix: "", 31 | suffix: "", 32 | }), 33 | (this.finalEndVal = null), 34 | (this.useEasing = !0), 35 | (this.countDown = !1), 36 | (this.error = ""), 37 | (this.startVal = 0), 38 | (this.paused = !0), 39 | (this.count = function (t) { 40 | s.startTime || (s.startTime = t); 41 | var i = t - s.startTime; 42 | (s.remaining = s.duration - i), 43 | s.useEasing 44 | ? s.countDown 45 | ? (s.frameVal = 46 | s.startVal - 47 | s.easingFn(i, 0, s.startVal - s.endVal, s.duration)) 48 | : (s.frameVal = s.easingFn( 49 | i, 50 | s.startVal, 51 | s.endVal - s.startVal, 52 | s.duration 53 | )) 54 | : s.countDown 55 | ? (s.frameVal = 56 | s.startVal - (s.startVal - s.endVal) * (i / s.duration)) 57 | : (s.frameVal = 58 | s.startVal + (s.endVal - s.startVal) * (i / s.duration)), 59 | s.countDown 60 | ? (s.frameVal = s.frameVal < s.endVal ? s.endVal : s.frameVal) 61 | : (s.frameVal = s.frameVal > s.endVal ? s.endVal : s.frameVal), 62 | (s.frameVal = 63 | Math.round(s.frameVal * s.decimalMult) / s.decimalMult), 64 | s.printValue(s.frameVal), 65 | i < s.duration 66 | ? (s.rAF = requestAnimationFrame(s.count)) 67 | : null !== s.finalEndVal 68 | ? s.update(s.finalEndVal) 69 | : s.callback && s.callback(); 70 | }), 71 | (this.formatNumber = function (t) { 72 | var i, 73 | a, 74 | n, 75 | e, 76 | r, 77 | o = t < 0 ? "-" : ""; 78 | if ( 79 | ((i = Math.abs(t).toFixed(s.options.decimalPlaces)), 80 | (n = (a = (i += "").split("."))[0]), 81 | (e = a.length > 1 ? s.options.decimal + a[1] : ""), 82 | s.options.useGrouping) 83 | ) { 84 | r = ""; 85 | for (var l = 0, h = n.length; l < h; ++l) 86 | 0 !== l && l % 3 == 0 && (r = s.options.separator + r), 87 | (r = n[h - l - 1] + r); 88 | n = r; 89 | } 90 | return ( 91 | s.options.numerals && 92 | s.options.numerals.length && 93 | ((n = n.replace(/[0-9]/g, function (t) { 94 | return s.options.numerals[+t]; 95 | })), 96 | (e = e.replace(/[0-9]/g, function (t) { 97 | return s.options.numerals[+t]; 98 | }))), 99 | o + s.options.prefix + n + e + s.options.suffix 100 | ); 101 | }), 102 | (this.easeOutExpo = function (t, i, a, s) { 103 | return (a * (1 - Math.pow(2, (-10 * t) / s)) * 1024) / 1023 + i; 104 | }), 105 | (this.options = __assign({}, this.defaults, a)), 106 | (this.formattingFn = this.options.formattingFn 107 | ? this.options.formattingFn 108 | : this.formatNumber), 109 | (this.easingFn = this.options.easingFn 110 | ? this.options.easingFn 111 | : this.easeOutExpo), 112 | (this.startVal = this.validateValue(this.options.startVal)), 113 | (this.frameVal = this.startVal), 114 | (this.endVal = this.validateValue(i)), 115 | (this.options.decimalPlaces = Math.max(this.options.decimalPlaces)), 116 | (this.decimalMult = Math.pow(10, this.options.decimalPlaces)), 117 | this.resetDuration(), 118 | (this.options.separator = String(this.options.separator)), 119 | (this.useEasing = this.options.useEasing), 120 | "" === this.options.separator && (this.options.useGrouping = !1), 121 | (this.el = "string" == typeof t ? document.getElementById(t) : t), 122 | this.el 123 | ? this.printValue(this.startVal) 124 | : (this.error = "[CountUp] target is null or undefined"); 125 | } 126 | return ( 127 | (t.prototype.determineDirectionAndSmartEasing = function () { 128 | var t = this.finalEndVal ? this.finalEndVal : this.endVal; 129 | this.countDown = this.startVal > t; 130 | var i = t - this.startVal; 131 | if (Math.abs(i) > this.options.smartEasingThreshold) { 132 | this.finalEndVal = t; 133 | var a = this.countDown ? 1 : -1; 134 | (this.endVal = t + a * this.options.smartEasingAmount), 135 | (this.duration = this.duration / 2); 136 | } else (this.endVal = t), (this.finalEndVal = null); 137 | this.finalEndVal 138 | ? (this.useEasing = !1) 139 | : (this.useEasing = this.options.useEasing); 140 | }), 141 | (t.prototype.start = function (t) { 142 | this.error || 143 | ((this.callback = t), 144 | this.duration > 0 145 | ? (this.determineDirectionAndSmartEasing(), 146 | (this.paused = !1), 147 | (this.rAF = requestAnimationFrame(this.count))) 148 | : this.printValue(this.endVal)); 149 | }), 150 | (t.prototype.pauseResume = function () { 151 | this.paused 152 | ? ((this.startTime = null), 153 | (this.duration = this.remaining), 154 | (this.startVal = this.frameVal), 155 | this.determineDirectionAndSmartEasing(), 156 | (this.rAF = requestAnimationFrame(this.count))) 157 | : cancelAnimationFrame(this.rAF), 158 | (this.paused = !this.paused); 159 | }), 160 | (t.prototype.reset = function () { 161 | cancelAnimationFrame(this.rAF), 162 | (this.paused = !0), 163 | this.resetDuration(), 164 | (this.startVal = this.validateValue(this.options.startVal)), 165 | (this.frameVal = this.startVal), 166 | this.printValue(this.startVal); 167 | }), 168 | (t.prototype.update = function (t) { 169 | cancelAnimationFrame(this.rAF), 170 | (this.startTime = null), 171 | (this.endVal = this.validateValue(t)), 172 | this.endVal !== this.frameVal && 173 | ((this.startVal = this.frameVal), 174 | this.finalEndVal || this.resetDuration(), 175 | this.determineDirectionAndSmartEasing(), 176 | (this.rAF = requestAnimationFrame(this.count))); 177 | }), 178 | (t.prototype.printValue = function (t) { 179 | var i = this.formattingFn(t); 180 | "INPUT" === this.el.tagName 181 | ? (this.el.value = i) 182 | : "text" === this.el.tagName || "tspan" === this.el.tagName 183 | ? (this.el.textContent = i) 184 | : (this.el.innerHTML = i); 185 | }), 186 | (t.prototype.ensureNumber = function (t) { 187 | return "number" == typeof t && !isNaN(t); 188 | }), 189 | (t.prototype.validateValue = function (t) { 190 | var i = Number(t); 191 | return this.ensureNumber(i) 192 | ? i 193 | : ((this.error = "[CountUp] invalid start or end value: " + t), null); 194 | }), 195 | (t.prototype.resetDuration = function () { 196 | (this.startTime = null), 197 | (this.duration = 1e3 * Number(this.options.duration)), 198 | (this.remaining = this.duration); 199 | }), 200 | t 201 | ); 202 | })(); 203 | export { CountUp }; 204 | -------------------------------------------------------------------------------- /js/countUp.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | countUp.js 4 | by @inorganik 5 | 6 | */ 7 | 8 | // target = id of html element or var of previously selected html element where counting occurs 9 | // startVal = the value you want to begin at 10 | // endVal = the value you want to arrive at 11 | // decimals = number of decimal places, default 0 12 | // duration = duration of animation in seconds, default 2 13 | // options = optional object of options (see below) 14 | 15 | var CountUp = function (target, startVal, endVal, decimals, duration, options) { 16 | var self = this; 17 | self.version = function () { 18 | return "1.9.3"; 19 | }; 20 | 21 | // default options 22 | self.options = { 23 | useEasing: true, // toggle easing 24 | useGrouping: true, // 1,000,000 vs 1000000 25 | separator: ",", // character to use as a separator 26 | decimal: ".", // character to use as a decimal 27 | easingFn: easeOutExpo, // optional custom easing function, default is Robert Penner's easeOutExpo 28 | formattingFn: formatNumber, // optional custom formatting function, default is formatNumber above 29 | prefix: "", // optional text before the result 30 | suffix: "", // optional text after the result 31 | numerals: [], // optionally pass an array of custom numerals for 0-9 32 | }; 33 | 34 | // extend default options with passed options object 35 | if (options && typeof options === "object") { 36 | for (var key in self.options) { 37 | if (options.hasOwnProperty(key) && options[key] !== null) { 38 | self.options[key] = options[key]; 39 | } 40 | } 41 | } 42 | 43 | if (self.options.separator === "") { 44 | self.options.useGrouping = false; 45 | } else { 46 | // ensure the separator is a string (formatNumber assumes this) 47 | self.options.separator = "" + self.options.separator; 48 | } 49 | 50 | // make sure requestAnimationFrame and cancelAnimationFrame are defined 51 | // polyfill for browsers without native support 52 | // by Opera engineer Erik Möller 53 | var lastTime = 0; 54 | var vendors = ["webkit", "moz", "ms", "o"]; 55 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 56 | window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"]; 57 | window.cancelAnimationFrame = 58 | window[vendors[x] + "CancelAnimationFrame"] || 59 | window[vendors[x] + "CancelRequestAnimationFrame"]; 60 | } 61 | if (!window.requestAnimationFrame) { 62 | window.requestAnimationFrame = function (callback, element) { 63 | var currTime = new Date().getTime(); 64 | var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 65 | var id = window.setTimeout(function () { 66 | callback(currTime + timeToCall); 67 | }, timeToCall); 68 | lastTime = currTime + timeToCall; 69 | return id; 70 | }; 71 | } 72 | if (!window.cancelAnimationFrame) { 73 | window.cancelAnimationFrame = function (id) { 74 | clearTimeout(id); 75 | }; 76 | } 77 | 78 | function formatNumber(num) { 79 | var neg = num < 0, 80 | x, 81 | x1, 82 | x2, 83 | x3, 84 | i, 85 | len; 86 | num = Math.abs(num).toFixed(self.decimals); 87 | num += ""; 88 | x = num.split("."); 89 | x1 = x[0]; 90 | x2 = x.length > 1 ? self.options.decimal + x[1] : ""; 91 | if (self.options.useGrouping) { 92 | x3 = ""; 93 | for (i = 0, len = x1.length; i < len; ++i) { 94 | if (i !== 0 && i % 3 === 0) { 95 | x3 = self.options.separator + x3; 96 | } 97 | x3 = x1[len - i - 1] + x3; 98 | } 99 | x1 = x3; 100 | } 101 | // optional numeral substitution 102 | if (self.options.numerals.length) { 103 | x1 = x1.replace(/[0-9]/g, function (w) { 104 | return self.options.numerals[+w]; 105 | }); 106 | x2 = x2.replace(/[0-9]/g, function (w) { 107 | return self.options.numerals[+w]; 108 | }); 109 | } 110 | return ( 111 | (neg ? "-" : "") + self.options.prefix + x1 + x2 + self.options.suffix 112 | ); 113 | } 114 | // Robert Penner's easeOutExpo 115 | function easeOutExpo(t, b, c, d) { 116 | return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b; 117 | } 118 | function ensureNumber(n) { 119 | return typeof n === "number" && !isNaN(n); 120 | } 121 | 122 | self.initialize = function () { 123 | if (self.initialized) return true; 124 | 125 | self.error = ""; 126 | self.d = 127 | typeof target === "string" ? document.getElementById(target) : target; 128 | if (!self.d) { 129 | self.error = "[CountUp] target is null or undefined"; 130 | return false; 131 | } 132 | self.startVal = Number(startVal); 133 | self.endVal = Number(endVal); 134 | // error checks 135 | if (ensureNumber(self.startVal) && ensureNumber(self.endVal)) { 136 | self.decimals = Math.max(0, decimals || 0); 137 | self.dec = Math.pow(10, self.decimals); 138 | self.duration = Number(duration) * 1000 || 2000; 139 | self.countDown = self.startVal > self.endVal; 140 | self.frameVal = self.startVal; 141 | self.initialized = true; 142 | return true; 143 | } else { 144 | self.error = 145 | "[CountUp] startVal (" + 146 | startVal + 147 | ") or endVal (" + 148 | endVal + 149 | ") is not a number"; 150 | return false; 151 | } 152 | }; 153 | 154 | // Print value to target 155 | self.printValue = function (value) { 156 | var result = self.options.formattingFn(value); 157 | 158 | if (self.d.tagName === "INPUT") { 159 | this.d.value = result; 160 | } else if (self.d.tagName === "text" || self.d.tagName === "tspan") { 161 | this.d.textContent = result; 162 | } else { 163 | this.d.innerHTML = result; 164 | } 165 | }; 166 | 167 | self.count = function (timestamp) { 168 | if (!self.startTime) { 169 | self.startTime = timestamp; 170 | } 171 | 172 | self.timestamp = timestamp; 173 | var progress = timestamp - self.startTime; 174 | self.remaining = self.duration - progress; 175 | 176 | // to ease or not to ease 177 | if (self.options.useEasing) { 178 | if (self.countDown) { 179 | self.frameVal = 180 | self.startVal - 181 | self.options.easingFn( 182 | progress, 183 | 0, 184 | self.startVal - self.endVal, 185 | self.duration 186 | ); 187 | } else { 188 | self.frameVal = self.options.easingFn( 189 | progress, 190 | self.startVal, 191 | self.endVal - self.startVal, 192 | self.duration 193 | ); 194 | } 195 | } else { 196 | if (self.countDown) { 197 | self.frameVal = 198 | self.startVal - 199 | (self.startVal - self.endVal) * (progress / self.duration); 200 | } else { 201 | self.frameVal = 202 | self.startVal + 203 | (self.endVal - self.startVal) * (progress / self.duration); 204 | } 205 | } 206 | 207 | // don't go past endVal since progress can exceed duration in the last frame 208 | if (self.countDown) { 209 | self.frameVal = self.frameVal < self.endVal ? self.endVal : self.frameVal; 210 | } else { 211 | self.frameVal = self.frameVal > self.endVal ? self.endVal : self.frameVal; 212 | } 213 | 214 | // decimal 215 | self.frameVal = Math.round(self.frameVal * self.dec) / self.dec; 216 | 217 | // format and print value 218 | self.printValue(self.frameVal); 219 | 220 | // whether to continue 221 | if (progress < self.duration) { 222 | self.rAF = requestAnimationFrame(self.count); 223 | } else { 224 | if (self.callback) self.callback(); 225 | } 226 | }; 227 | // start your animation 228 | self.start = function (callback) { 229 | if (!self.initialize()) return; 230 | self.callback = callback; 231 | self.rAF = requestAnimationFrame(self.count); 232 | }; 233 | // toggles pause/resume animation 234 | self.pauseResume = function () { 235 | if (!self.paused) { 236 | self.paused = true; 237 | cancelAnimationFrame(self.rAF); 238 | } else { 239 | self.paused = false; 240 | delete self.startTime; 241 | self.duration = self.remaining; 242 | self.startVal = self.frameVal; 243 | requestAnimationFrame(self.count); 244 | } 245 | }; 246 | // reset to startVal so animation can be run again 247 | self.reset = function () { 248 | self.paused = false; 249 | delete self.startTime; 250 | self.initialized = false; 251 | if (self.initialize()) { 252 | cancelAnimationFrame(self.rAF); 253 | self.printValue(self.startVal); 254 | } 255 | }; 256 | // pass a new endVal and start animation 257 | self.update = function (newEndVal) { 258 | if (!self.initialize()) return; 259 | newEndVal = Number(newEndVal); 260 | if (!ensureNumber(newEndVal)) { 261 | self.error = 262 | "[CountUp] update() - new endVal is not a number: " + newEndVal; 263 | return; 264 | } 265 | self.error = ""; 266 | if (newEndVal === self.frameVal) return; 267 | cancelAnimationFrame(self.rAF); 268 | self.paused = false; 269 | delete self.startTime; 270 | self.startVal = self.frameVal; 271 | self.endVal = newEndVal; 272 | self.countDown = self.startVal > self.endVal; 273 | self.rAF = requestAnimationFrame(self.count); 274 | }; 275 | 276 | // format startVal on initialization 277 | if (self.initialize()) self.printValue(self.startVal); 278 | }; 279 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Subuthai's Very Simple Portfolio 5 | 6 | 7 | 8 | 9 | 13 | 17 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | 30 | 31 |
32 |
33 |
34 |

Subuthai's Very Simple Portfolio

35 |

36 |
37 |
38 |
39 | 40 | 41 | 75 | 76 | 77 |
78 |
79 |
80 |
81 | 82 |
83 | 84 |
85 |

About Me

86 |

87 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus 88 | laoreet ex quis leo molestie feugiat. Donec gravida congue enim id 89 | cursus. Cras fermentum semper metus at rhoncus. Quisque elementum 90 | tristique varius. Sed non quam sit amet dui eleifend congue. 91 | Quisque pulvinar, lectus eu sagittis consequat, velit lacus 92 | lobortis orci, sed feugiat metus risus vitae ipsum. Donec aliquet 93 | mauris urna, et convallis justo sagittis a. Ut urna lacus, 94 | tristique ut libero eget, commodo hendrerit massa. Curabitur sit 95 | amet diam lobortis, finibus lorem vel, tempus diam. Quisque elit 96 | urna, scelerisque eu porta in, sollicitudin a dui. Nunc quis 97 | ultrices velit. Proin rhoncus ante a nisi vestibulum, at luctus 98 | mauris condimentum. Aenean pulvinar turpis malesuada nunc 99 | pharetra, at tincidunt enim fermentum. Donec scelerisque sapien 100 | feugiat ligula consequat ultrices. Phasellus elit tellus, lobortis 101 | et vestibulum quis, semper vitae augue. 102 |

103 | 104 |

105 | Aenean tincidunt nisl orci, sed faucibus augue lobortis ac. Ut ac 106 | fermentum leo, quis rhoncus sapien. Nulla facilisi. Fusce eget 107 | accumsan sapien. Ut lacinia ex eu feugiat commodo. Curabitur 108 | varius lectus at risus porttitor porttitor. Vivamus suscipit 109 | sodales metus vel pulvinar. Duis fringilla semper augue vitae 110 | venenatis. Praesent posuere, nunc non condimentum egestas, magna 111 | risus ornare metus, nec iaculis enim orci at ante. Nam eros 112 | turpis, pharetra non imperdiet vitae, dictum quis mauris. Vivamus 113 | egestas aliquet risus, quis ultricies arcu tincidunt vel. 114 | Curabitur luctus ac orci ut consectetur. Nulla rutrum orci quis 115 | elit elementum aliquet. Proin at augue libero. Pellentesque 116 | habitant morbi tristique senectus et netus et malesuada fames ac 117 | turpis egestas. Integer imperdiet dui a vulputate cursus. 118 |

119 |
120 |
121 |
122 |
123 | 124 | 125 |
126 |
127 |
128 |
129 |

MY SKILLS

130 |

My skills in web & programming languages.

131 |
132 | 133 | 166 |
167 |
168 |
169 | 170 | 171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 | 179 |
180 |
181 |

59

182 |

Projects Done

183 |
184 |
185 |
186 |
187 | 188 |
189 |
190 |
191 |
192 | 193 |
194 |
195 |

14

196 |

Clients

197 |
198 |
199 |
200 |
201 | 202 |
203 |
204 |
205 |
206 | 207 |
208 |
209 |

999999

210 |

Cups Of Coffee

211 |
212 |
213 |
214 |
215 | 216 |
217 |
218 |
219 |
220 | 221 |
222 |
223 |

3

224 |

Discord Bots I Made

225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 | 233 | 234 |
235 |
236 |

Do you want to contact me?

237 |

Send an email now.

238 | Contact me! 241 |
242 |
243 | 244 | 245 | 246 |
247 |
248 |

249 | copyright © 2021 some rights reserved | 85% of website was made 250 | by subuthai 251 |

252 |
253 |
254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 266 | 271 | 275 | 276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /js/jquery.superslides.min.js: -------------------------------------------------------------------------------- 1 | /*! Superslides - v0.6.3-wip - 2013-12-17 2 | * https://github.com/nicinabox/superslides 3 | * Copyright (c) 2013 Nic Aitch; Licensed MIT */ 4 | (function (i, t) { 5 | var n, 6 | e = "superslides"; 7 | (n = function (n, e) { 8 | this.options = t.extend( 9 | { 10 | play: !1, 11 | animation_speed: 600, 12 | animation_easing: "swing", 13 | animation: "slide", 14 | inherit_width_from: i, 15 | inherit_height_from: i, 16 | pagination: !0, 17 | hashchange: !1, 18 | scrollable: !0, 19 | elements: { 20 | preserve: ".preserve", 21 | nav: ".slides-navigation", 22 | container: ".slides-container", 23 | pagination: ".slides-pagination", 24 | }, 25 | }, 26 | e 27 | ); 28 | var s = this, 29 | o = t("
", { class: "slides-control" }), 30 | a = 1; 31 | (this.$el = t(n)), 32 | (this.$container = this.$el.find(this.options.elements.container)); 33 | var r = function () { 34 | return ( 35 | (a = s._findMultiplier()), 36 | s.$el.on("click", s.options.elements.nav + " a", function (i) { 37 | i.preventDefault(), 38 | s.stop(), 39 | t(this).hasClass("next") 40 | ? s.animate("next", function () { 41 | s.start(); 42 | }) 43 | : s.animate("prev", function () { 44 | s.start(); 45 | }); 46 | }), 47 | t(document).on("keyup", function (i) { 48 | 37 === i.keyCode && s.animate("prev"), 49 | 39 === i.keyCode && s.animate("next"); 50 | }), 51 | t(i).on("resize", function () { 52 | setTimeout(function () { 53 | var i = s.$container.children(); 54 | (s.width = s._findWidth()), 55 | (s.height = s._findHeight()), 56 | i.css({ width: s.width, left: s.width }), 57 | s.css.containers(), 58 | s.css.images(); 59 | }, 10); 60 | }), 61 | s.options.hashchange && 62 | t(i).on("hashchange", function () { 63 | var i, 64 | t = s._parseHash(); 65 | (i = s._upcomingSlide(t)), 66 | i >= 0 && i !== s.current && s.animate(i); 67 | }), 68 | s.pagination._events(), 69 | s.start(), 70 | s 71 | ); 72 | }, 73 | h = { 74 | containers: function () { 75 | s.init 76 | ? (s.$el.css({ height: s.height }), 77 | s.$control.css({ width: s.width * a, left: -s.width }), 78 | s.$container.css({})) 79 | : (t("body").css({ margin: 0 }), 80 | s.$el.css({ 81 | position: "relative", 82 | overflow: "hidden", 83 | width: "100%", 84 | height: s.height, 85 | }), 86 | s.$control.css({ 87 | position: "relative", 88 | transform: "translate3d(0)", 89 | height: "100%", 90 | width: s.width * a, 91 | left: -s.width, 92 | }), 93 | s.$container.css({ 94 | display: "none", 95 | margin: "0", 96 | padding: "0", 97 | listStyle: "none", 98 | position: "relative", 99 | height: "100%", 100 | })), 101 | 1 === s.size() && s.$el.find(s.options.elements.nav).hide(); 102 | }, 103 | images: function () { 104 | var i = s.$container.find("img").not(s.options.elements.preserve); 105 | i 106 | .removeAttr("width") 107 | .removeAttr("height") 108 | .css({ 109 | "-webkit-backface-visibility": "hidden", 110 | "-ms-interpolation-mode": "bicubic", 111 | position: "absolute", 112 | left: "0", 113 | top: "0", 114 | "z-index": "-1", 115 | "max-width": "none", 116 | }), 117 | i.each(function () { 118 | var i = s.image._aspectRatio(this), 119 | n = this; 120 | if (t.data(this, "processed")) 121 | s.image._scale(n, i), s.image._center(n, i); 122 | else { 123 | var e = new Image(); 124 | (e.onload = function () { 125 | s.image._scale(n, i), 126 | s.image._center(n, i), 127 | t.data(n, "processed", !0); 128 | }), 129 | (e.src = this.src); 130 | } 131 | }); 132 | }, 133 | children: function () { 134 | var i = s.$container.children(); 135 | i.is("img") && 136 | (i.each(function () { 137 | if (t(this).is("img")) { 138 | t(this).wrap("
"); 139 | var i = t(this).attr("id"); 140 | t(this).removeAttr("id"), t(this).parent().attr("id", i); 141 | } 142 | }), 143 | (i = s.$container.children())), 144 | s.init || i.css({ display: "none", left: 2 * s.width }), 145 | i.css({ 146 | position: "absolute", 147 | overflow: "hidden", 148 | height: "100%", 149 | width: s.width, 150 | top: 0, 151 | zIndex: 0, 152 | }); 153 | }, 154 | }, 155 | c = { 156 | slide: function (i, t) { 157 | var n = s.$container.children(), 158 | e = n.eq(i.upcoming_slide); 159 | e.css({ left: i.upcoming_position, display: "block" }), 160 | s.$control.animate( 161 | { left: i.offset }, 162 | s.options.animation_speed, 163 | s.options.animation_easing, 164 | function () { 165 | s.size() > 1 && 166 | (s.$control.css({ left: -s.width }), 167 | n.eq(i.upcoming_slide).css({ left: s.width, zIndex: 2 }), 168 | i.outgoing_slide >= 0 && 169 | n 170 | .eq(i.outgoing_slide) 171 | .css({ left: s.width, display: "none", zIndex: 0 })), 172 | t(); 173 | } 174 | ); 175 | }, 176 | fade: function (i, t) { 177 | var n = this, 178 | e = n.$container.children(), 179 | s = e.eq(i.outgoing_slide), 180 | o = e.eq(i.upcoming_slide); 181 | o 182 | .css({ left: this.width, opacity: 0, display: "block" }) 183 | .animate( 184 | { opacity: 1 }, 185 | n.options.animation_speed, 186 | n.options.animation_easing 187 | ), 188 | i.outgoing_slide >= 0 189 | ? s.animate( 190 | { opacity: 0 }, 191 | n.options.animation_speed, 192 | n.options.animation_easing, 193 | function () { 194 | n.size() > 1 && 195 | (e.eq(i.upcoming_slide).css({ zIndex: 2 }), 196 | i.outgoing_slide >= 0 && 197 | e 198 | .eq(i.outgoing_slide) 199 | .css({ opacity: 1, display: "none", zIndex: 0 })), 200 | t(); 201 | } 202 | ) 203 | : (o.css({ zIndex: 2 }), t()); 204 | }, 205 | }; 206 | c = t.extend(c, t.fn.superslides.fx); 207 | var d = { 208 | _centerY: function (i) { 209 | var n = t(i); 210 | n.css({ top: (s.height - n.height()) / 2 }); 211 | }, 212 | _centerX: function (i) { 213 | var n = t(i); 214 | n.css({ left: (s.width - n.width()) / 2 }); 215 | }, 216 | _center: function (i) { 217 | s.image._centerX(i), s.image._centerY(i); 218 | }, 219 | _aspectRatio: function (i) { 220 | if (!i.naturalHeight && !i.naturalWidth) { 221 | var t = new Image(); 222 | (t.src = i.src), 223 | (i.naturalHeight = t.height), 224 | (i.naturalWidth = t.width); 225 | } 226 | return i.naturalHeight / i.naturalWidth; 227 | }, 228 | _scale: function (i, n) { 229 | n = n || s.image._aspectRatio(i); 230 | var e = s.height / s.width, 231 | o = t(i); 232 | e > n 233 | ? o.css({ height: s.height, width: s.height / n }) 234 | : o.css({ height: s.width * n, width: s.width }); 235 | }, 236 | }, 237 | l = { 238 | _setCurrent: function (i) { 239 | if (s.$pagination) { 240 | var t = s.$pagination.children(); 241 | t.removeClass("current"), t.eq(i).addClass("current"); 242 | } 243 | }, 244 | _addItem: function (i) { 245 | var n = i + 1, 246 | e = n, 247 | o = s.$container.children().eq(i), 248 | a = o.attr("id"); 249 | a && (e = a); 250 | var r = t("", { href: "#" + e, text: e }); 251 | r.appendTo(s.$pagination); 252 | }, 253 | _setup: function () { 254 | if (s.options.pagination && 1 !== s.size()) { 255 | var i = t("