30 |
31 |
32 |
36 |
37 |
38 |
42 |
43 |
LOADING ...
44 |
PLAY
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/gulp/tasks/browsersync.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserSync = require('browser-sync');
3 |
4 | gulp.task('browserSync', function(){
5 | browserSync({
6 | open: 'external',
7 | reloadDebounce: 2000,
8 | ui: false,
9 | notify: false,
10 | startPath: "/",
11 | ghostMode: false,
12 | server: {
13 | baseDir: "dst/"
14 | },
15 | files: [
16 | "dst/**/*.obj",
17 |
18 | "dst/**/*.json",
19 | "dst/**/*.xml",
20 |
21 | "dst/**/*.mp4",
22 | "dst/**/*.webm",
23 | "dst/**/*.mp3",
24 |
25 | "dst/**/*.png",
26 | "dst/**/*.jpg",
27 | "dst/**/*.gif",
28 | "dst/**/*.svg",
29 |
30 | "dst/**/*.frag",
31 | "dst/**/*.vert",
32 | "dst/**/*.glsl",
33 |
34 | "dst/**/*.html",
35 | "dst/**/*.css",
36 | "dst/**/*.js"
37 | ]
38 | });
39 | });
--------------------------------------------------------------------------------
/gulp/tasks/glsl.js:
--------------------------------------------------------------------------------
1 | var gulp = require("gulp");
2 | var glslify = require("gulp-glslify");
3 |
4 | // var path = "assets/test";
5 |
6 |
7 | gulp.task("glsl", null, function() {
8 | gulp.src("src/**/*.{vert,frag}")
9 | .pipe(glslify())
10 | .pipe(gulp.dest("dst"));
11 | });
--------------------------------------------------------------------------------
/gulp/tasks/html.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var plumber = require('gulp-plumber');
3 |
4 |
5 | gulp.task('html', function()
6 | {
7 |
8 | gulp.src("src/**/*.html")
9 | .pipe(gulp.dest("dst"));
10 | });
--------------------------------------------------------------------------------
/gulp/tasks/javascript.js:
--------------------------------------------------------------------------------
1 | var gulp = require("gulp");
2 | var changed = require("gulp-changed");
3 | var concat = require("gulp-concat");
4 | var runSequence = require('run-sequence');
5 | var stripDebug = require('gulp-strip-debug');
6 | var babel = require('gulp-babel');
7 | var plumber = require('gulp-plumber');
8 |
9 |
10 |
11 | gulp.task("js", function(){
12 | return runSequence(
13 | "js.concat"
14 | );
15 | });
16 |
17 |
18 |
19 | gulp.task("js.concat", function(){
20 | return gulp.src([
21 | "src/assets/js/lib-head/*.js",
22 | "src/assets/js/lib/*.js",
23 | "src/assets/js/module/*.js",
24 | "src/assets/js/main.js"
25 | ],
26 | { base: "src" }
27 | )
28 | .pipe(plumber())
29 | .pipe(babel())
30 | .pipe(concat("main.min.js"))
31 | .pipe(gulp.dest("dst/assets/js/"));
32 | })
--------------------------------------------------------------------------------
/gulp/tasks/sass.js:
--------------------------------------------------------------------------------
1 | var gulp = require("gulp");
2 | var sass = require("gulp-sass");
3 | var plumber = require('gulp-plumber');
4 | var csswring = require('csswring');
5 |
6 |
7 | gulp.task("css", function () {
8 |
9 | var postcss = require("gulp-postcss");
10 | var postcssOptions = [
11 | require('postcss-mixins'),
12 | require("autoprefixer")({ browsers: [
13 | 'ie >= 9',
14 | 'ie_mob >= 10',
15 | 'ff >= 31',
16 | 'chrome >= 36',
17 | 'safari >= 8',
18 | 'opera >= 23',
19 | 'ios >= 8',
20 | 'android >= 4'
21 | ]}),
22 | require("css-mqpacker")({ sort: function (a, b) { return b.localeCompare(a); } }),
23 | require("postcss-flexbugs-fixes"),
24 | require("postcss-partial-import")()
25 | ];
26 |
27 | postcssOptions.push(csswring);
28 |
29 | gulp.src("src/assets/css/styles.scss")
30 | .pipe(plumber())
31 | .pipe(sass({outputStyle: "expanded"}))
32 | .pipe(postcss(postcssOptions))
33 | .pipe(gulp.dest("dst/assets/css/"));
34 | });
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var requireDir = require('require-dir');
3 | var runSequence = require('run-sequence');
4 |
5 |
6 | requireDir('./gulp/tasks');
7 |
8 | gulp.task('media', function()
9 | {
10 |
11 | gulp.src("src/**/*.txt")
12 | .pipe(gulp.dest("dst"));
13 | });
14 |
15 | gulp.task('watch', function(){
16 | gulp.watch(['src/assets/css/**/*.{scss,css}'], ['css']);
17 | gulp.watch('src/assets/js/**/*.js', ['js']);
18 | gulp.watch('src/assets/glsl/**/*.{vert,frag}', ['glsl']);
19 | gulp.watch('src/**/*.html', ['html']);
20 | gulp.watch('src/**/*.txt', ['media']);
21 | });
22 |
23 |
24 | gulp.task('predefault', function(){
25 | runSequence(
26 | 'css',
27 | 'html',
28 | 'glsl',
29 | 'js',
30 | 'media',
31 | 'browserSync',
32 | 'watch'
33 | );
34 | });
35 |
36 |
37 | gulp.task('default', ['predefault'], function(){
38 | console.log('running default tasks...');
39 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "audio-visualizer-torus",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "author": "Misaki Nakano",
7 | "license": "GPL",
8 | "dependencies": {},
9 | "scripts": {
10 | "start": "cross-env gulp"
11 | },
12 | "devDependencies": {
13 | "autoprefixer": "^6.4.0",
14 | "babel-core": "^5.5.8",
15 | "babel-loader": "^5.1.4",
16 | "browser-sync": "^2.13.0",
17 | "cross-env": "^2.0.0",
18 | "css-loader": "^0.25.0",
19 | "css-mqpacker": "^5.0.1",
20 | "csswring": "^5.1.0",
21 | "del": "^2.2.2",
22 | "fs": "0.0.1-security",
23 | "glslify": "^6.0.2",
24 | "glslify-hex": "^2.1.1",
25 | "glslify-import": "^3.0.0",
26 | "gulp": "^3.9.1",
27 | "gulp-babel": "^5.1.0",
28 | "gulp-changed": "^1.3.2",
29 | "gulp-concat": "^2.6.0",
30 | "gulp-glslify": "git+https://github.com/yuichiroharai/gulp-glslify.git",
31 | "gulp-if": "^2.0.1",
32 | "gulp-load-plugins": "^1.2.4",
33 | "gulp-notify": "^2.2.0",
34 | "gulp-plumber": "^1.1.0",
35 | "gulp-postcss": "^6.1.1",
36 | "gulp-sass": "^2.3.2",
37 | "gulp-strip-debug": "^1.1.0",
38 | "gulp-uglify": "^2.0.0",
39 | "gulp-util": "^3.0.7",
40 | "gulp-watch": "^4.3.9",
41 | "gulp-webpack": "^1.5.0",
42 | "gulp.spritesmith": "^6.2.1",
43 | "html-loader": "^0.4.4",
44 | "postcss-flexbugs-fixes": "^2.0.0",
45 | "postcss-mixins": "^5.2.0",
46 | "postcss-partial-import": "^2.0.0",
47 | "require-dir": "^0.3.0",
48 | "run-sequence": "^1.2.2",
49 | "sass-variables-loader": "^0.1.3",
50 | "strip-loader": "^0.1.2",
51 | "style-loader": "^0.13.1",
52 | "through2": "^2.0.3",
53 | "vue-loader": "^9.7.0",
54 | "vue-style-loader": "^1.0.0",
55 | "webpack": "^2.2.1"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mnmxmx/audio-visualizer-torus/e48841d2532f2bee8546a582005df3b88d9d5db4/screenshot1.png
--------------------------------------------------------------------------------
/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mnmxmx/audio-visualizer-torus/e48841d2532f2bee8546a582005df3b88d9d5db4/screenshot2.png
--------------------------------------------------------------------------------
/src/assets/css/styles.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | @import "vendor/initial";
4 |
5 | body{
6 | overflow: hidden;
7 | }
8 |
9 | .stats{
10 | position:absolute;
11 | top: 0;
12 | right: 0;
13 | z-index: 2;
14 | }
15 |
16 |
17 | .file{
18 | position: absolute;
19 | top: 15px;
20 | left: 15px;
21 | padding: 10px;
22 | box-sizing: border-box;
23 | border: 1px solid #000;
24 | // background: rgba(255, 255, 255, 0.2);
25 |
26 | letter-spacing: 0.01em;
27 | color: #000;
28 | cursor: pointer;
29 | transition: opacity .4s;
30 |
31 | font-size: 12px;
32 | padding: 15px 30px;
33 | letter-spacing: 0.15em;
34 | display: none;
35 | // opacity: 0;
36 |
37 | &.isHidden{
38 | display: none;
39 | }
40 |
41 |
42 |
43 |
44 | // &:hover{
45 | // opacity: .8;
46 | // }
47 |
48 | input{
49 | display: none;
50 | }
51 | }
52 |
53 |
54 | .credits{
55 | position: absolute;
56 | top: 20px;
57 | left: 20px;
58 | letter-spacing: 0.2em;
59 | font-size: 18px;
60 | p{
61 | margin-bottom: 20px;
62 | }
63 | a{
64 | color: #FF52AA
65 |
66 | }
67 | }
68 |
69 | .start{
70 | position: absolute;
71 | width: 100%;
72 | height: 100%;
73 | top: 0;
74 | left: 0;
75 | background: rgba(#fff, 0.8);
76 | letter-spacing: 0.4em;
77 | font-size: 18px;
78 | z-index: 1000000000;
79 |
80 | transition: opacity 0.5s, visibility 0s 0.5s;
81 |
82 | &.isHidden{
83 | opacity: 0;
84 | visibility: hidden;
85 | }
86 |
87 | .play, .loading{
88 | position: absolute;
89 | top: 50%;
90 | left: 50%;
91 | transform: translate(-50%, -50%);
92 | // transition: opacity 0.5s, visibility 0s 0.5s;
93 |
94 | &.isHidden{
95 | opacity: 0;
96 | visibility: hidden;
97 |
98 | }
99 | }
100 |
101 | .loading{
102 |
103 | }
104 |
105 | .play{
106 | // background: rgba(#000, 0.4);
107 | border: 2px solid #000;
108 | padding: 20px 40px;
109 |
110 | cursor: pointer;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/assets/css/vendor/_initial.scss:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | // -------------------- from reset.css
4 | html,
5 | body, article, section, nav, aside,
6 | h1, h2, h3, h4, h5, h6,
7 | header, footer, address,
8 | p, ol, ul, li, dl, dt, dd, div,
9 | a, strong, small, sup, sup, span,
10 | img, iframe, embed, object, video, audio,
11 | table, tr, td, th,
12 | canvas,
13 | svg {
14 | margin: 0;
15 | padding: 0;
16 | border: 0;
17 | font-size: 100%;
18 | font: inherit;
19 | vertical-align: baseline;
20 | }
21 |
22 |
23 |
24 | // -------------------- from normalize.css / sanitize.css
25 | html {
26 | cursor: default;
27 | line-height: 1;
28 |
29 | // http://ultimate-ez.com/2014/03/29/3572/
30 | // http://xxmiz0rexx.tumblr.com/post/73393990520/webkit-text-size-adjust-100%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%8F%E3%81%A6%E7%84%A6%E3%81%A3%E3%81%9F
31 | -ms-text-size-adjust: 100%;
32 | -webkit-text-size-adjust: 100%;
33 | &.windows{
34 | -webkit-font-smoothing: antialiased;
35 | }
36 |
37 |
38 | -webkit-overflow-scrolling: touch;
39 | -webkit-tap-highlight-color: transparent;
40 | font-family: arial;
41 | }
42 |
43 |
44 |
45 | // -------------------- from sanitize.css
46 | // https://developer.mozilla.org/ja/docs/Web/CSS/::selection
47 | //::-moz-selection,
48 | //::selection {
49 | // background-color: #ccc;
50 | // color: #000;
51 | // text-shadow: none;
52 | //}
53 |
54 | ::-moz-selection {
55 | background-color: #ccc;
56 | color: #000;
57 | text-shadow: none;
58 | }
59 |
60 | ::selection {
61 | background-color: #ccc;
62 | color: #000;
63 | text-shadow: none;
64 | }
65 |
66 |
67 |
68 | // -------------------- from reset.css
69 | ol, ul {
70 | list-style: none;
71 | }
72 |
73 |
74 |
75 | // -------------------- from reset.css / sanitize.css
76 | table {
77 | border-collapse: collapse;
78 | border-spacing: 0;
79 | }
80 |
81 |
82 |
83 | // -------------------- from reset.css / normalize.css / sanitize.css
84 | article, section, nav, aside,
85 | header, footer {
86 | display: block;
87 | }
88 |
89 |
90 |
91 | // -------------------- from normalize.css / sanitize.css
92 | video, audio,
93 | canvas {
94 | display: inline-block;
95 | }
96 |
97 |
98 |
99 | // -------------------- from normalize.css / sanitize.css
100 | audio:not([controls]) {
101 | display: none;
102 | height: 0;
103 | }
104 |
105 |
106 |
107 | // -------------------- from normalize.css / sanitize.css
108 | hr {
109 | box-sizing: content-box;
110 | height: 0;
111 | overflow: visible;
112 | }
113 |
114 |
115 |
116 | // -------------------- from normalize.css / sanitize.css
117 | strong {
118 | font-weight: inherit;
119 | }
120 | strong {
121 | font-weight: bolder;
122 | }
123 |
124 |
125 |
126 | // -------------------- from normalize.css / sanitize.css
127 | sub,
128 | sup {
129 | line-height: 0;
130 | position: relative;
131 | vertical-align: baseline;
132 | }
133 | sub {
134 | bottom: -.25em;
135 | }
136 | sup {
137 | top: -.5em;
138 | }
139 |
140 |
141 |
142 | // -------------------- from sanitize.css
143 |
144 | // http://www.02320.net/how-to-fill-svg-by-css/
145 | svg {
146 | fill: currentColor;
147 | }
148 |
149 |
150 |
151 | // -------------------- from normalize.css / sanitize.css
152 | svg:not(:root) {
153 | overflow: hidden;
154 | }
155 |
156 |
157 |
158 | // -------------------- from normalize.css / sanitize.css
159 | a {
160 | background-color: transparent;
161 |
162 | // https://css-tricks.com/almanac/properties/t/text-decoration-skip/
163 | -webkit-text-decoration-skip: objects;
164 | }
165 |
166 |
167 |
168 | // -------------------- from normalize.css / sanitize.css
169 | a:active,
170 | a:hover {
171 | outline-width: 0;
172 | }
173 |
174 |
175 |
176 | // -------------------- from normalize.css / sanitize.css
177 | // http://lealog.hateblo.jp/entry/2015/02/19/124748
178 | a {
179 | -ms-touch-action: manipulation;
180 | touch-action: manipulation;
181 | }
--------------------------------------------------------------------------------
/src/assets/data/s.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mnmxmx/audio-visualizer-torus/e48841d2532f2bee8546a582005df3b88d9d5db4/src/assets/data/s.txt
--------------------------------------------------------------------------------
/src/assets/glsl/torus.frag:
--------------------------------------------------------------------------------
1 | varying vec2 vUv;
2 | varying vec3 vPos;
3 | varying float vFrequency;
4 |
5 | const vec3 objColor = vec3(1.0);
6 |
7 | const vec3 hemiLight_g_1 = #e50061;
8 | const vec3 hemiLight_s_1 = #efcb03;
9 | const vec3 hemiLight_g_2 = #a20b79;
10 | const vec3 hemiLight_s_2 = #a20b24;
11 |
12 |
13 | const vec3 dirLight = vec3(0.2);
14 | const vec3 dirLight_2 = vec3(0.15);
15 |
16 |
17 | const vec3 hemiLightPos_1 = vec3(1.0, 0.0, -1.0);
18 | const vec3 hemiLightPos_2 = vec3(-0.5, 0.5, 1.0);
19 |
20 |
21 | const vec3 dirLightPos = vec3(-30, 50, 50);
22 | const vec3 dirLightPos_2 = vec3(30, -50, -50);
23 |
24 |
25 | vec3 calcIrradiance_hemi(vec3 newNormal, vec3 lightPos, vec3 grd, vec3 sky){
26 | float dotNL = dot(newNormal, normalize(lightPos));
27 | float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
28 |
29 | return mix(grd, sky, hemiDiffuseWeight);
30 | }
31 |
32 | vec3 calcIrradiance_dir(vec3 newNormal, vec3 lightPos, vec3 light){
33 | float dotNL = dot(newNormal, normalize(lightPos));
34 |
35 | return light * max(0.0, dotNL);
36 | }
37 |
38 |
39 | void main(){
40 |
41 | vec3 _normal = normalize( cross(dFdx(vPos), dFdy(vPos)) );
42 |
43 | vec3 hemiColor = vec3(0.0);
44 | hemiColor += calcIrradiance_hemi(_normal, hemiLightPos_1, hemiLight_g_1, hemiLight_s_1) * 0.7;
45 | hemiColor += calcIrradiance_hemi(_normal, hemiLightPos_2, hemiLight_g_2, hemiLight_s_2) * 0.8;
46 |
47 | vec3 dirColor = vec3(0.0);
48 | dirColor += calcIrradiance_dir(_normal, dirLightPos, dirLight);
49 | dirColor += calcIrradiance_dir(_normal, dirLightPos_2, dirLight_2);
50 |
51 |
52 | vec3 color = objColor * hemiColor;
53 |
54 | color += dirColor;
55 |
56 | vec3 offsetColor = vec3(vFrequency * 0.2, vFrequency * 1.5, -vFrequency * 0.7) * 0.008;
57 |
58 | color += offsetColor;
59 | color.g = min(0.9, color.g);
60 |
61 | color.r = (color.g == 0.9 && color.r > 0.94) ? 0.94 : color.r;
62 |
63 | color = min(vec3(1.0), color);
64 |
65 | float offsetColor2 = min(0.0, (vPos.x + vPos.y) / 2000.0);
66 | color -= vec3(offsetColor2) * vec3(-0.3, -1.0, 1.2);
67 |
68 | color = min(vec3(1.0), color + 0.1);
69 |
70 | gl_FragColor = vec4(color, 0.95);
71 | }
--------------------------------------------------------------------------------
/src/assets/glsl/torus.vert:
--------------------------------------------------------------------------------
1 | attribute float aFrequency;
2 | attribute float aRadian;
3 |
4 | uniform float uRadius;
5 | uniform float uTick;
6 |
7 |
8 | varying vec2 vUv;
9 | varying vec3 vPos;
10 | varying float vFrequency;
11 |
12 |
13 | const float PI = 3.1415926;
14 |
15 |
16 | mat2 calcRotate2D(float _time){
17 | float _sin = sin(_time);
18 | float _cos = cos(_time);
19 | return mat2(_cos, _sin, -_sin, _cos);
20 | }
21 |
22 |
23 | void main(){
24 | vUv = uv;
25 | vFrequency = min(10.0, aFrequency);
26 |
27 | float time = uTick * 0.005;
28 |
29 | vec3 offset = vec3(cos(aRadian), sin(aRadian), 0.0) * uRadius;
30 |
31 | vec3 _position = position - offset;
32 |
33 | _position *= (1.0 + aFrequency);
34 |
35 | _position += offset;
36 |
37 | _position.xy = calcRotate2D(time * 1.2) * _position.xy;
38 |
39 |
40 |
41 | vec4 mvPos = vec4(_position, 1.0);
42 |
43 | mvPos = modelViewMatrix * mvPos;
44 |
45 | vPos = mvPos.xyz;
46 |
47 | gl_Position =projectionMatrix * mvPos;
48 | }
--------------------------------------------------------------------------------
/src/assets/js/lib-head/useragnt-all.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Useragnt
3 | * v0.3.1
4 | *
5 | * Copyright (c) 2016 Yuichiroh Arai
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/mit-license.php
8 | *
9 | * detects: mobile, tablet, pc, windows, mac, linux, ios, android, edge, ie, safari, chrome, firefox, opera
10 | !*/
11 | !function(e,o){function i(e){return n.indexOf(e)!=-1}function r(e){var o=e.split("."),i={};return i.str=e,i.float=parseFloat(e)||0,i.major=o.length>0?parseInt(o[0])||0:0,i.minor=o.length>1?parseInt(o[1])||0:0,i.build=o.length>2?parseInt(o[2])||0:0,i.revision=o.length>3?parseInt(o[3])||0:0,i}var a={};a._detects=["mobile","tablet","pc","windows","mac","linux","ios","android","edge","ie","safari","chrome","firefox","opera"];var n=a.userAgent=e.navigator.userAgent.toLowerCase();a.mobile=i("iphone")||i("ipod")||i("android")&&i("mobile")||i("windows")&&i("phone")||i("firefox")&&i("mobile")||i("blackberry"),a.tablet=i("ipad")||i("android")&&!i("mobile")||i("windows")&&i("touch")&&!i("tablet pc")||i("firefox")&&i("tablet")||i("kindle")||i("silk")||i("playbook"),a.pc=!i("iphone")&&!i("ipod")&&!i("ipad")&&!i("android")&&(!i("windows")||!i("phone")&&(!i("touch")||i("tablet pc")))&&(!i("firefox")||!i("mobile")&&!i("tablet"))&&!i("blackberry")&&!i("kindle")&&!i("silk")&&!i("playbook"),a.windows=i("windows"),a.mac=i("mac os x")&&!i("iphone")&&!i("ipad")&&!i("ipod"),a.linux=i("linux")&&!i("android"),a.ios=i("iphone")||i("ipad")||i("ipod"),a.ios&&(a.ios=new Boolean(!0),n.match(/ os ([\d_]+)/g),a.ios.version=r(RegExp.$1.replace("_","."))),a.android=i("android"),a.android&&(a.android=new Boolean(!0),n.match(/android ([\d\.]+)/g),a.android.version=r(RegExp.$1)),a.edge=i("edge"),a.ie=i("trident")||i("msie"),a.safari=i("safari")&&!i("android")&&!i("edge")&&!i("opera")&&!i("opr")&&!i("chrome"),a.chrome=i("chrome")&&!i("edge")&&!i("opera")&&!i("opr"),a.chrome&&(a.chrome=new Boolean(!0),n.match(/chrome\/([\d.]+)/g),a.chrome.version=r(RegExp.$1)),a.firefox=i("firefox")&&!i("edge"),a.opera=i("opera")||i("opr");var d,t,s,l=a._classPrefix="",p=o.documentElement,c=p.className;for(t=a._detects.length,d=0;d