From 32a50e75aefaeaa138e178deab174e305ea224d1 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 15 Nov 2019 21:52:08 -0800 Subject: [PATCH 01/14] Make security fox demo --- example/example.js | 2 ++ index.js | 25 ++++++++++++++++++++++++- package-lock.json | 5 +++++ package.json | 3 ++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/example/example.js b/example/example.js index 302410da..97db2d86 100644 --- a/example/example.js +++ b/example/example.js @@ -1,5 +1,6 @@ var copy = require('copy-to-clipboard') + document.addEventListener('keypress', function (event) { if (event.keyCode === 99) { // the c key var svg = document.querySelector('svg') @@ -22,6 +23,7 @@ var viewer = createViewer({ height: 0.4, followMouse: true, followMotion: true, + colorSeed: Math.floor(Math.random() * 100000), }) document.body.appendChild(viewer.container) diff --git a/index.js b/index.js index 40ffa9a2..03dac673 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,19 @@ var invert = require('gl-mat4/invert') var rotate = require('gl-mat4/rotate') var transform = require('gl-vec3/transformMat4') var foxJSON = require('./fox.json') +var colors = [ + '#01888C', // teal + '#FC7500', // bright orange + '#034F5D', // dark teal + '#F73F01', // orangered + '#FC1960', // magenta + '#C7144C', // raspberry + '#F3C100', // goldenrod + '#1598F2', // lightning blue + '#2465E1', // sail blue + '#F19E02', // gold +] +var MersenneTwister = require('mersenne-twister'); var SVG_NS = 'http://www.w3.org/2000/svg' @@ -22,6 +35,11 @@ module.exports = function createLogo (options_) { var followCursor = !!options.followMouse var followMotion = !!options.followMotion var slowDrift = !!options.slowDrift + var colorSeed = options.colorSeed + var twister + if (colorSeed) { + twister = new MersenneTwister(colorSeed) + } var shouldRender = true var DISTANCE = 400 @@ -85,7 +103,12 @@ module.exports = function createLogo (options_) { var polygons = [] for (var i = 0; i < foxJSON.chunks.length; ++i) { var chunk = foxJSON.chunks[i] - var color = 'rgb(' + chunk.color + ')' + var color + if (twister) { + color = colors[Math.floor(twister.random() * colors.length)] + } else { + color = 'rgb(' + chunk.color + ')' + } var faces = chunk.faces for (var j = 0; j < faces.length; ++j) { var f = faces[j] diff --git a/package-lock.json b/package-lock.json index 9c08d685..2ed5c8d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1904,6 +1904,11 @@ "inherits": "^2.0.1" } }, + "mersenne-twister": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", + "integrity": "sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o=" + }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", diff --git a/package.json b/package.json index c2e692f2..2dc164ab 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "license": "ISC", "dependencies": { "gl-mat4": "1.1.4", - "gl-vec3": "1.0.3" + "gl-vec3": "1.0.3", + "mersenne-twister": "^1.1.0" }, "devDependencies": { "browserify": "^16.2.2", From 4c8263e630367d4db7294b5d49eb1424e5daa72e Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 15 Nov 2019 21:53:37 -0800 Subject: [PATCH 02/14] Build security fox demo script --- bundle.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bundle.js b/bundle.js index b68ddd79..9c8052d8 100644 --- a/bundle.js +++ b/bundle.js @@ -1,5 +1,5 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i '+r+"")}});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0});document.body.appendChild(viewer.container); +var copy=require("copy-to-clipboard");document.addEventListener("keypress",function(e){if(99===e.keyCode){var o=document.querySelector("svg").innerHTML;copy(' '+o+"")}});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:Math.floor(1e5*Math.random())});document.body.appendChild(viewer.container); },{"../index":3,"copy-to-clipboard":4}],2:[function(require,module,exports){ module.exports={ @@ -1430,12 +1430,12 @@ module.exports={ } },{}],3:[function(require,module,exports){ -var perspective=require("gl-mat4/perspective"),multiply=require("gl-mat4/multiply"),lookAt=require("gl-mat4/lookAt"),invert=require("gl-mat4/invert"),rotate=require("gl-mat4/rotate"),transform=require("gl-vec3/transformMat4"),foxJSON=require("./fox.json"),SVG_NS="http://www.w3.org/2000/svg";function createNode(t){return document.createElementNS(SVG_NS,t)}function setAttribute(t,e,n){t.setAttributeNS(null,e,n)}module.exports=function(t){var e=t||{},n=!!e.followMouse,r=!!e.followMotion,i=!!e.slowDrift,o=!0,a=[0,0],l=.3,u=e.width||400,s=e.height||400,h=createNode("svg"),f={x:0,y:0},d=foxJSON.positions.length,c=new Float32Array(3*d),w=new Float32Array(3*d),g=[];function v(t){var e=h.getBoundingClientRect();f.x=1-2*(t.x-e.left)/e.width,f.y=1-2*(t.y-e.top)/e.height}function m(t,e){this.svg=t,this.indices=e,this.zIndex=0}e.pxNotRatio||(u=window.innerWidth*(e.width||.25)|0,s=0|(window.innerHeight*e.height||u),"minWidth"in e&&u>>0,this.mti=1;this.mti>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},MersenneTwister.prototype.init_by_array=function(t,i){var s,h,n;for(this.init_seed(19650218),s=1,h=0,n=this.N>i?this.N:i;n;n--){var r=this.mt[s-1]^this.mt[s-1]>>>30;this.mt[s]=(this.mt[s]^(1664525*((4294901760&r)>>>16)<<16)+1664525*(65535&r))+t[h]+h,this.mt[s]>>>=0,h++,++s>=this.N&&(this.mt[0]=this.mt[this.N-1],s=1),h>=i&&(h=0)}for(n=this.N-1;n;n--){r=this.mt[s-1]^this.mt[s-1]>>>30;this.mt[s]=(this.mt[s]^(1566083941*((4294901760&r)>>>16)<<16)+1566083941*(65535&r))-s,this.mt[s]>>>=0,++s>=this.N&&(this.mt[0]=this.mt[this.N-1],s=1)}this.mt[0]=2147483648},MersenneTwister.prototype.random_int=function(){var t,i=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var s;for(this.mti==this.N+1&&this.init_seed(5489),s=0;s>>1^i[1&t];for(;s>>1^i[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^i[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},MersenneTwister.prototype.random_int31=function(){return this.random_int()>>>1},MersenneTwister.prototype.random_incl=function(){return this.random_int()*(1/4294967295)},MersenneTwister.prototype.random=function(){return this.random_int()*(1/4294967296)},MersenneTwister.prototype.random_excl=function(){return(this.random_int()+.5)*(1/4294967296)},MersenneTwister.prototype.random_long=function(){return(67108864*(this.random_int()>>>5)+(this.random_int()>>>6))*(1/9007199254740992)},module.exports=MersenneTwister; + +},{}],13:[function(require,module,exports){ module.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var n=document.activeElement,t=[],a=0;a Date: Fri, 15 Nov 2019 21:54:21 -0800 Subject: [PATCH 03/14] Add title --- index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 6cb5d071..ef97c103 100644 --- a/index.html +++ b/index.html @@ -2,10 +2,11 @@ ---- +Security fox demo +

Reload to get a fresh unique fox

From ca8b1ad72d1d353e0a3ee8165922cbea9fc5745b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 15 Nov 2019 21:57:38 -0800 Subject: [PATCH 04/14] Manual rebuild --- bundle.js | 1035 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1023 insertions(+), 12 deletions(-) diff --git a/bundle.js b/bundle.js index 9c8052d8..340fa7c6 100644 --- a/bundle.js +++ b/bundle.js @@ -1,5 +1,33 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i '+o+"")}});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:Math.floor(1e5*Math.random())});document.body.appendChild(viewer.container); +var copy = require('copy-to-clipboard') + + +document.addEventListener('keypress', function (event) { + if (event.keyCode === 99) { // the c key + var svg = document.querySelector('svg') + var inner = svg.innerHTML + var head = ' ' + + '' + var foot = '' + + var full = head + inner + foot; + + copy(full) + } +}) + +var createViewer = require('../index') + +var viewer = createViewer({ + width: 0.4, + height: 0.4, + followMouse: true, + followMotion: true, + colorSeed: Math.floor(Math.random() * 100000), +}) + +document.body.appendChild(viewer.container) },{"../index":3,"copy-to-clipboard":4}],2:[function(require,module,exports){ module.exports={ @@ -1430,36 +1458,1019 @@ module.exports={ } },{}],3:[function(require,module,exports){ -var perspective=require("gl-mat4/perspective"),multiply=require("gl-mat4/multiply"),lookAt=require("gl-mat4/lookAt"),invert=require("gl-mat4/invert"),rotate=require("gl-mat4/rotate"),transform=require("gl-vec3/transformMat4"),foxJSON=require("./fox.json"),colors=["#01888C","#FC7500","#034F5D","#F73F01","#FC1960","#C7144C","#F3C100","#1598F2","#2465E1","#F19E02"],MersenneTwister=require("mersenne-twister"),SVG_NS="http://www.w3.org/2000/svg";function createNode(t){return document.createElementNS(SVG_NS,t)}function setAttribute(t,e,n){t.setAttributeNS(null,e,n)}module.exports=function(t){var e,n=t||{},r=!!n.followMouse,o=!!n.followMotion,i=!!n.slowDrift,a=n.colorSeed;a&&(e=new MersenneTwister(a));var l=!0,s=[0,0],u=.3,h=n.width||400,f=n.height||400,c=createNode("svg"),d={x:0,y:0},w=foxJSON.positions.length,v=new Float32Array(3*w),g=new Float32Array(3*w),m=[];function p(t){var e=c.getBoundingClientRect();d.x=1-2*(t.x-e.left)/e.width,d.y=1-2*(t.y-e.top)/e.height}function A(t,e){this.svg=t,this.indices=e,this.zIndex=0}n.pxNotRatio||(h=window.innerWidth*(n.width||.25)|0,f=0|(window.innerHeight*n.height||h),"minWidth"in n&&h>>0,this.mti=1;this.mti>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},MersenneTwister.prototype.init_by_array=function(t,i){var s,h,n;for(this.init_seed(19650218),s=1,h=0,n=this.N>i?this.N:i;n;n--){var r=this.mt[s-1]^this.mt[s-1]>>>30;this.mt[s]=(this.mt[s]^(1664525*((4294901760&r)>>>16)<<16)+1664525*(65535&r))+t[h]+h,this.mt[s]>>>=0,h++,++s>=this.N&&(this.mt[0]=this.mt[this.N-1],s=1),h>=i&&(h=0)}for(n=this.N-1;n;n--){r=this.mt[s-1]^this.mt[s-1]>>>30;this.mt[s]=(this.mt[s]^(1566083941*((4294901760&r)>>>16)<<16)+1566083941*(65535&r))-s,this.mt[s]>>>=0,++s>=this.N&&(this.mt[0]=this.mt[this.N-1],s=1)}this.mt[0]=2147483648},MersenneTwister.prototype.random_int=function(){var t,i=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var s;for(this.mti==this.N+1&&this.init_seed(5489),s=0;s>>1^i[1&t];for(;s>>1^i[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^i[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},MersenneTwister.prototype.random_int31=function(){return this.random_int()>>>1},MersenneTwister.prototype.random_incl=function(){return this.random_int()*(1/4294967295)},MersenneTwister.prototype.random=function(){return this.random_int()*(1/4294967296)},MersenneTwister.prototype.random_excl=function(){return(this.random_int()+.5)*(1/4294967296)},MersenneTwister.prototype.random_long=function(){return(67108864*(this.random_int()>>>5)+(this.random_int()>>>6))*(1/9007199254740992)},module.exports=MersenneTwister; +/* + https://github.com/banksean wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace + so it's better encapsulated. Now you can have multiple random number generators + and they won't stomp all over eachother's state. + + If you want to use this as a substitute for Math.random(), use the random() + method like so: + + var m = new MersenneTwister(); + var randomNumber = m.random(); + + You can also call the other genrand_{foo}() methods on the instance. + + If you want to use a specific seed in order to get a repeatable random + sequence, pass an integer into the constructor: + + var m = new MersenneTwister(123); + + and that will always produce the same random sequence. + + Sean McCullough (banksean@gmail.com) +*/ + +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_seed(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +var MersenneTwister = function(seed) { + if (seed == undefined) { + seed = new Date().getTime(); + } + + /* Period parameters */ + this.N = 624; + this.M = 397; + this.MATRIX_A = 0x9908b0df; /* constant vector a */ + this.UPPER_MASK = 0x80000000; /* most significant w-r bits */ + this.LOWER_MASK = 0x7fffffff; /* least significant r bits */ + + this.mt = new Array(this.N); /* the array for the state vector */ + this.mti=this.N+1; /* mti==N+1 means mt[N] is not initialized */ + + if (seed.constructor == Array) { + this.init_by_array(seed, seed.length); + } + else { + this.init_seed(seed); + } +} + +/* initializes mt[N] with a seed */ +/* origin name init_genrand */ +MersenneTwister.prototype.init_seed = function(s) { + this.mt[0] = s >>> 0; + for (this.mti=1; this.mti>> 30); + this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) + + this.mti; + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + this.mt[this.mti] >>>= 0; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +MersenneTwister.prototype.init_by_array = function(init_key, key_length) { + var i, j, k; + this.init_seed(19650218); + i=1; j=0; + k = (this.N>key_length ? this.N : key_length); + for (; k; k--) { + var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30) + this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) + + init_key[j] + j; /* non linear */ + this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=this.N-1; k; k--) { + var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30); + this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) + - i; /* non linear */ + this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ + i++; + if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } + } + + this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +/* origin name genrand_int32 */ +MersenneTwister.prototype.random_int = function() { + var y; + var mag01 = new Array(0x0, this.MATRIX_A); + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (this.mti >= this.N) { /* generate N words at one time */ + var kk; + + if (this.mti == this.N+1) /* if init_seed() has not been called, */ + this.init_seed(5489); /* a default initial seed is used */ + + for (kk=0;kk>> 1) ^ mag01[y & 0x1]; + } + for (;kk>> 1) ^ mag01[y & 0x1]; + } + y = (this.mt[this.N-1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK); + this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1]; + + this.mti = 0; + } + + y = this.mt[this.mti++]; + + /* Tempering */ + y ^= (y >>> 11); + y ^= (y << 7) & 0x9d2c5680; + y ^= (y << 15) & 0xefc60000; + y ^= (y >>> 18); + + return y >>> 0; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +/* origin name genrand_int31 */ +MersenneTwister.prototype.random_int31 = function() { + return (this.random_int()>>>1); +} + +/* generates a random number on [0,1]-real-interval */ +/* origin name genrand_real1 */ +MersenneTwister.prototype.random_incl = function() { + return this.random_int()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +MersenneTwister.prototype.random = function() { + return this.random_int()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +/* origin name genrand_real3 */ +MersenneTwister.prototype.random_excl = function() { + return (this.random_int() + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +/* origin name genrand_res53 */ +MersenneTwister.prototype.random_long = function() { + var a=this.random_int()>>>5, b=this.random_int()>>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} + +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +module.exports = MersenneTwister; },{}],13:[function(require,module,exports){ -module.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var n=document.activeElement,t=[],a=0;a Date: Fri, 15 Nov 2019 22:03:41 -0800 Subject: [PATCH 05/14] Rebuild --- bundle.js | 1035 +--------------------------------------------------- index.html | 2 +- 2 files changed, 13 insertions(+), 1024 deletions(-) diff --git a/bundle.js b/bundle.js index 340fa7c6..9c8052d8 100644 --- a/bundle.js +++ b/bundle.js @@ -1,33 +1,5 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i ' - + '' - var foot = '' - - var full = head + inner + foot; - - copy(full) - } -}) - -var createViewer = require('../index') - -var viewer = createViewer({ - width: 0.4, - height: 0.4, - followMouse: true, - followMotion: true, - colorSeed: Math.floor(Math.random() * 100000), -}) - -document.body.appendChild(viewer.container) +var copy=require("copy-to-clipboard");document.addEventListener("keypress",function(e){if(99===e.keyCode){var o=document.querySelector("svg").innerHTML;copy(' '+o+"")}});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:Math.floor(1e5*Math.random())});document.body.appendChild(viewer.container); },{"../index":3,"copy-to-clipboard":4}],2:[function(require,module,exports){ module.exports={ @@ -1458,1019 +1430,36 @@ module.exports={ } },{}],3:[function(require,module,exports){ -var perspective = require('gl-mat4/perspective') -var multiply = require('gl-mat4/multiply') -var lookAt = require('gl-mat4/lookAt') -var invert = require('gl-mat4/invert') -var rotate = require('gl-mat4/rotate') -var transform = require('gl-vec3/transformMat4') -var foxJSON = require('./fox.json') -var colors = [ - '#01888C', // teal - '#FC7500', // bright orange - '#034F5D', // dark teal - '#F73F01', // orangered - '#FC1960', // magenta - '#C7144C', // raspberry - '#F3C100', // goldenrod - '#1598F2', // lightning blue - '#2465E1', // sail blue - '#F19E02', // gold -] -var MersenneTwister = require('mersenne-twister'); - -var SVG_NS = 'http://www.w3.org/2000/svg' - -function createNode (type) { - return document.createElementNS(SVG_NS, type) -} - -function setAttribute (node, attribute, value) { - node.setAttributeNS(null, attribute, value) -} - -module.exports = function createLogo (options_) { - var options = options_ || {} - - var followCursor = !!options.followMouse - var followMotion = !!options.followMotion - var slowDrift = !!options.slowDrift - var colorSeed = options.colorSeed - var twister - if (colorSeed) { - twister = new MersenneTwister(colorSeed) - } - var shouldRender = true - - var DISTANCE = 400 - var lookCurrent = [0, 0] - var lookRate = 0.3 - - var width = options.width || 400 - var height = options.height || 400 - var container = createNode('svg') - var mouse = { - x: 0, - y: 0 - } - - var NUM_VERTS = foxJSON.positions.length - - var positions = new Float32Array(3 * NUM_VERTS) - var transformed = new Float32Array(3 * NUM_VERTS) - - var toDraw = [] - - if (!options.pxNotRatio) { - width = (window.innerWidth * (options.width || 0.25)) | 0 - height = ((window.innerHeight * options.height) || width) | 0 - - if ('minWidth' in options && width < options.minWidth) { - width = options.minWidth - height = (options.minWidth * options.height / options.width) | 0 - } - } - - setAttribute(container, 'width', width + 'px') - setAttribute(container, 'height', height + 'px') - - function setLookAt (target) { - var bounds = container.getBoundingClientRect() - mouse.x = 1.0 - 2.0 * (target.x - bounds.left) / bounds.width - mouse.y = 1.0 - 2.0 * (target.y - bounds.top) / bounds.height - } - - document.body.appendChild(container) - - ;(function () { - var pp = foxJSON.positions - var ptr = 0 - for (var i = 0; i < pp.length; ++i) { - var p = pp[i] - for (var j = 0; j < 3; ++j) { - positions[ptr++] = p[j] - } - } - })() - - function Polygon (svg, indices) { - this.svg = svg - this.indices = indices - this.zIndex = 0 - } - - var polygons = (function () { - var polygons = [] - for (var i = 0; i < foxJSON.chunks.length; ++i) { - var chunk = foxJSON.chunks[i] - var color - if (twister) { - color = colors[Math.floor(twister.random() * colors.length)] - } else { - color = 'rgb(' + chunk.color + ')' - } - var faces = chunk.faces - for (var j = 0; j < faces.length; ++j) { - var f = faces[j] - var polygon = createNode('polygon') - setAttribute( - polygon, - 'fill', - color) - setAttribute( - polygon, - 'stroke', - color) - setAttribute( - polygon, - 'points', - '0,0, 10,0, 0,10') - container.appendChild(polygon) - polygons.push(new Polygon(polygon, f)) - } - } - return polygons - })() - - var computeMatrix = (function () { - var objectCenter = new Float32Array(3) - var up = new Float32Array([0, 1, 0]) - var projection = new Float32Array(16) - var model = new Float32Array(16) - var view = lookAt( - new Float32Array(16), - new Float32Array([0, 0, DISTANCE]), - objectCenter, - up) - var invView = invert(new Float32Array(16), view) - var invProjection = new Float32Array(16) - var target = new Float32Array(3) - var transformed = new Float32Array(16) - - var X = new Float32Array([1, 0, 0]) - var Y = new Float32Array([0, 1, 0]) - var Z = new Float32Array([0, 0, 1]) - - return function () { - var rect = container.getBoundingClientRect() - var viewportWidth = rect.width - var viewportHeight = rect.height - perspective( - projection, - Math.PI / 4.0, - viewportWidth / viewportHeight, - 100.0, - 1000.0) - invert(invProjection, projection) - target[0] = lookCurrent[0] - target[1] = lookCurrent[1] - target[2] = 1.2 - transform(target, target, invProjection) - transform(target, target, invView) - lookAt( - model, - objectCenter, - target, - up) - if (slowDrift) { - var time = (Date.now() / 1000.0) - rotate(model, model, 0.1 + (Math.sin(time / 3) * 0.2), X) - rotate(model, model, -0.1 + (Math.sin(time / 2) * 0.03), Z) - rotate(model, model, 0.5 + (Math.sin(time / 3) * 0.2), Y) - } - - multiply(transformed, projection, view) - multiply(transformed, transformed, model) - - return transformed - } - })() - - function updatePositions (M) { - var m00 = M[0] - var m01 = M[1] - var m02 = M[2] - var m03 = M[3] - var m10 = M[4] - var m11 = M[5] - var m12 = M[6] - var m13 = M[7] - var m20 = M[8] - var m21 = M[9] - var m22 = M[10] - var m23 = M[11] - var m30 = M[12] - var m31 = M[13] - var m32 = M[14] - var m33 = M[15] - - for (var i = 0; i < NUM_VERTS; ++i) { - var x = positions[3 * i] - var y = positions[3 * i + 1] - var z = positions[3 * i + 2] - - var tw = x * m03 + y * m13 + z * m23 + m33 - transformed[3 * i] = - (x * m00 + y * m10 + z * m20 + m30) / tw - transformed[3 * i + 1] = - (x * m01 + y * m11 + z * m21 + m31) / tw - transformed[3 * i + 2] = - (x * m02 + y * m12 + z * m22 + m32) / tw - } - } - - function compareZ (a, b) { - return b.zIndex - a.zIndex - } - - function updateFaces () { - var i - var rect = container.getBoundingClientRect() - var w = rect.width - var h = rect.height - toDraw.length = 0 - for (i = 0; i < polygons.length; ++i) { - var poly = polygons[i] - var indices = poly.indices - - var i0 = indices[0] - var i1 = indices[1] - var i2 = indices[2] - var ax = transformed[3 * i0] - var ay = transformed[3 * i0 + 1] - var bx = transformed[3 * i1] - var by = transformed[3 * i1 + 1] - var cx = transformed[3 * i2] - var cy = transformed[3 * i2 + 1] - var det = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) - if (det < 0) { - continue - } - - var points = [] - var zmax = -Infinity - var zmin = Infinity - var element = poly.svg - for (var j = 0; j < 3; ++j) { - var idx = indices[j] - points.push( - 0.5 * w * (1.0 - transformed[3 * idx]) + ',' + - 0.5 * h * (1.0 - transformed[3 * idx + 1])) - var z = transformed[3 * idx + 2] - zmax = Math.max(zmax, z) - zmin = Math.min(zmin, z) - } - poly.zIndex = zmax + 0.25 * zmin - var joinedPoints = points.join(' ') - - if (joinedPoints.indexOf('NaN') === -1) { - setAttribute(element, 'points', joinedPoints) - } - - toDraw.push(poly) - } - toDraw.sort(compareZ) - container.innerHTML = '' - for (i = 0; i < toDraw.length; ++i) { - container.appendChild(toDraw[i].svg) - } - } - - function stopAnimation () { shouldRender = false } - function startAnimation () { shouldRender = true } - function setFollowMouse (state) { followCursor = state } - function setFollowMotion (state) { followMotion = state } - - window.addEventListener('mousemove', function (ev) { - if (!shouldRender) { startAnimation() } - if (followCursor) { - setLookAt({ - x: ev.clientX, - y: ev.clientY - }) - renderScene() - } - }) - - window.addEventListener('deviceorientation', function (event) { - if (!shouldRender) { startAnimation() } - if (followMotion) { - // gamma: left to right - const leftToRight = event.gamma - // beta: front back motion - const frontToBack = event.beta - // x offset: needed to correct the intial position - const xOffset = 200 - // y offset: needed to correct the intial position - const yOffset = -300 - // acceleration - const acceleration = 10 - - setLookAt({ - x: xOffset + leftToRight * acceleration, - y: yOffset + frontToBack * acceleration - }) - renderScene() - } - }) - - function renderScene () { - if (!shouldRender) return - window.requestAnimationFrame(renderScene) - - var li = (1.0 - lookRate) - var bounds = container.getBoundingClientRect() - - lookCurrent[0] = li * lookCurrent[0] + lookRate * mouse.x - lookCurrent[1] = li * lookCurrent[1] + lookRate * mouse.y + 0.085 - - var matrix = computeMatrix() - updatePositions(matrix) - updateFaces() - stopAnimation() - } - - renderScene() - - return { - container: container, - lookAt: setLookAt, - setFollowMouse: setFollowMouse, - setFollowMotion: setFollowMotion, - stopAnimation: stopAnimation, - startAnimation: startAnimation - } -} +var perspective=require("gl-mat4/perspective"),multiply=require("gl-mat4/multiply"),lookAt=require("gl-mat4/lookAt"),invert=require("gl-mat4/invert"),rotate=require("gl-mat4/rotate"),transform=require("gl-vec3/transformMat4"),foxJSON=require("./fox.json"),colors=["#01888C","#FC7500","#034F5D","#F73F01","#FC1960","#C7144C","#F3C100","#1598F2","#2465E1","#F19E02"],MersenneTwister=require("mersenne-twister"),SVG_NS="http://www.w3.org/2000/svg";function createNode(t){return document.createElementNS(SVG_NS,t)}function setAttribute(t,e,n){t.setAttributeNS(null,e,n)}module.exports=function(t){var e,n=t||{},r=!!n.followMouse,o=!!n.followMotion,i=!!n.slowDrift,a=n.colorSeed;a&&(e=new MersenneTwister(a));var l=!0,s=[0,0],u=.3,h=n.width||400,f=n.height||400,c=createNode("svg"),d={x:0,y:0},w=foxJSON.positions.length,v=new Float32Array(3*w),g=new Float32Array(3*w),m=[];function p(t){var e=c.getBoundingClientRect();d.x=1-2*(t.x-e.left)/e.width,d.y=1-2*(t.y-e.top)/e.height}function A(t,e){this.svg=t,this.indices=e,this.zIndex=0}n.pxNotRatio||(h=window.innerWidth*(n.width||.25)|0,f=0|(window.innerHeight*n.height||h),"minWidth"in n&&h>> 0; - for (this.mti=1; this.mti>> 30); - this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) - + this.mti; - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - this.mt[this.mti] >>>= 0; - /* for >32 bit machines */ - } -} - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -/* slight change for C++, 2004/2/26 */ -MersenneTwister.prototype.init_by_array = function(init_key, key_length) { - var i, j, k; - this.init_seed(19650218); - i=1; j=0; - k = (this.N>key_length ? this.N : key_length); - for (; k; k--) { - var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30) - this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) - + init_key[j] + j; /* non linear */ - this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ - i++; j++; - if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } - if (j>=key_length) j=0; - } - for (k=this.N-1; k; k--) { - var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30); - this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) - - i; /* non linear */ - this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ - i++; - if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } - } - - this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ -} - -/* generates a random number on [0,0xffffffff]-interval */ -/* origin name genrand_int32 */ -MersenneTwister.prototype.random_int = function() { - var y; - var mag01 = new Array(0x0, this.MATRIX_A); - /* mag01[x] = x * MATRIX_A for x=0,1 */ - - if (this.mti >= this.N) { /* generate N words at one time */ - var kk; - - if (this.mti == this.N+1) /* if init_seed() has not been called, */ - this.init_seed(5489); /* a default initial seed is used */ - - for (kk=0;kk>> 1) ^ mag01[y & 0x1]; - } - for (;kk>> 1) ^ mag01[y & 0x1]; - } - y = (this.mt[this.N-1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK); - this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1]; - - this.mti = 0; - } - - y = this.mt[this.mti++]; - - /* Tempering */ - y ^= (y >>> 11); - y ^= (y << 7) & 0x9d2c5680; - y ^= (y << 15) & 0xefc60000; - y ^= (y >>> 18); - - return y >>> 0; -} - -/* generates a random number on [0,0x7fffffff]-interval */ -/* origin name genrand_int31 */ -MersenneTwister.prototype.random_int31 = function() { - return (this.random_int()>>>1); -} - -/* generates a random number on [0,1]-real-interval */ -/* origin name genrand_real1 */ -MersenneTwister.prototype.random_incl = function() { - return this.random_int()*(1.0/4294967295.0); - /* divided by 2^32-1 */ -} - -/* generates a random number on [0,1)-real-interval */ -MersenneTwister.prototype.random = function() { - return this.random_int()*(1.0/4294967296.0); - /* divided by 2^32 */ -} - -/* generates a random number on (0,1)-real-interval */ -/* origin name genrand_real3 */ -MersenneTwister.prototype.random_excl = function() { - return (this.random_int() + 0.5)*(1.0/4294967296.0); - /* divided by 2^32 */ -} - -/* generates a random number on [0,1) with 53-bit resolution*/ -/* origin name genrand_res53 */ -MersenneTwister.prototype.random_long = function() { - var a=this.random_int()>>>5, b=this.random_int()>>>6; - return(a*67108864.0+b)*(1.0/9007199254740992.0); -} - -/* These real versions are due to Isaku Wada, 2002/01/09 added */ - -module.exports = MersenneTwister; +var MersenneTwister=function(t){null==t&&(t=(new Date).getTime()),this.N=624,this.M=397,this.MATRIX_A=2567483615,this.UPPER_MASK=2147483648,this.LOWER_MASK=2147483647,this.mt=new Array(this.N),this.mti=this.N+1,t.constructor==Array?this.init_by_array(t,t.length):this.init_seed(t)};MersenneTwister.prototype.init_seed=function(t){for(this.mt[0]=t>>>0,this.mti=1;this.mti>>30;this.mt[this.mti]=(1812433253*((4294901760&t)>>>16)<<16)+1812433253*(65535&t)+this.mti,this.mt[this.mti]>>>=0}},MersenneTwister.prototype.init_by_array=function(t,i){var s,h,n;for(this.init_seed(19650218),s=1,h=0,n=this.N>i?this.N:i;n;n--){var r=this.mt[s-1]^this.mt[s-1]>>>30;this.mt[s]=(this.mt[s]^(1664525*((4294901760&r)>>>16)<<16)+1664525*(65535&r))+t[h]+h,this.mt[s]>>>=0,h++,++s>=this.N&&(this.mt[0]=this.mt[this.N-1],s=1),h>=i&&(h=0)}for(n=this.N-1;n;n--){r=this.mt[s-1]^this.mt[s-1]>>>30;this.mt[s]=(this.mt[s]^(1566083941*((4294901760&r)>>>16)<<16)+1566083941*(65535&r))-s,this.mt[s]>>>=0,++s>=this.N&&(this.mt[0]=this.mt[this.N-1],s=1)}this.mt[0]=2147483648},MersenneTwister.prototype.random_int=function(){var t,i=new Array(0,this.MATRIX_A);if(this.mti>=this.N){var s;for(this.mti==this.N+1&&this.init_seed(5489),s=0;s>>1^i[1&t];for(;s>>1^i[1&t];t=this.mt[this.N-1]&this.UPPER_MASK|this.mt[0]&this.LOWER_MASK,this.mt[this.N-1]=this.mt[this.M-1]^t>>>1^i[1&t],this.mti=0}return t=this.mt[this.mti++],t^=t>>>11,t^=t<<7&2636928640,t^=t<<15&4022730752,(t^=t>>>18)>>>0},MersenneTwister.prototype.random_int31=function(){return this.random_int()>>>1},MersenneTwister.prototype.random_incl=function(){return this.random_int()*(1/4294967295)},MersenneTwister.prototype.random=function(){return this.random_int()*(1/4294967296)},MersenneTwister.prototype.random_excl=function(){return(this.random_int()+.5)*(1/4294967296)},MersenneTwister.prototype.random_long=function(){return(67108864*(this.random_int()>>>5)+(this.random_int()>>>6))*(1/9007199254740992)},module.exports=MersenneTwister; },{}],13:[function(require,module,exports){ - -module.exports = function () { - var selection = document.getSelection(); - if (!selection.rangeCount) { - return function () {}; - } - var active = document.activeElement; - - var ranges = []; - for (var i = 0; i < selection.rangeCount; i++) { - ranges.push(selection.getRangeAt(i)); - } - - switch (active.tagName.toUpperCase()) { // .toUpperCase handles XHTML - case 'INPUT': - case 'TEXTAREA': - active.blur(); - break; - - default: - active = null; - break; - } - - selection.removeAllRanges(); - return function () { - selection.type === 'Caret' && - selection.removeAllRanges(); - - if (!selection.rangeCount) { - ranges.forEach(function(range) { - selection.addRange(range); - }); - } - - active && - active.focus(); - }; -}; +module.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var n=document.activeElement,t=[],a=0;aReload to get a fresh unique fox
- + -

Press C to copy the SVG text of the image.

+

Press C to save the SVG image.

From 0ca00656f6d2c4dc2aee312d1c21c7278df12ef0 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 15 Nov 2019 22:51:57 -0800 Subject: [PATCH 09/14] Add save button and C to save --- bundle.js | 2 +- example/example.js | 24 ++++++++++++++++-------- index.html | 3 ++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/bundle.js b/bundle.js index a2cd2d75..b80aa0e7 100644 --- a/bundle.js +++ b/bundle.js @@ -1,5 +1,5 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i '+document.querySelector("svg").innerHTML+"",`custom-fox-${colorSeed}.svg`,"image/svg+xml")}});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:colorSeed});function download(e,o,t){var n=new Blob([e],{type:t});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(n,o);else{var r=document.createElement("a"),d=URL.createObjectURL(n);r.href=d,r.download=o,document.body.appendChild(r),r.click(),setTimeout(function(){document.body.removeChild(r),window.URL.revokeObjectURL(d)},0)}}document.body.appendChild(viewer.container); +const colorSeed=Math.floor(1e5*Math.random());function saveImage(){download(' '+document.querySelector("svg").innerHTML+"",`custom-fox-${colorSeed}.svg`,"image/svg+xml")}window.addEventListener("load",()=>{document.querySelector("button.save").addEventListener("click",saveImage)}),document.addEventListener("keypress",e=>{99===e.keyCode&&saveImage()});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:colorSeed});function download(e,o,t){var n=new Blob([e],{type:t});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(n,o);else{var d=document.createElement("a"),r=URL.createObjectURL(n);d.href=r,d.download=o,document.body.appendChild(d),d.click(),setTimeout(function(){document.body.removeChild(d),window.URL.revokeObjectURL(r)},0)}}document.body.appendChild(viewer.container); },{"../index":3}],2:[function(require,module,exports){ module.exports={ diff --git a/example/example.js b/example/example.js index e241a6c1..8c8bc5e8 100644 --- a/example/example.js +++ b/example/example.js @@ -1,19 +1,27 @@ const colorSeed = Math.floor(Math.random() * 100000) -document.addEventListener('keypress', function (event) { - if (event.keyCode === 99) { // the c key +window.addEventListener('load', () => { + const saveButton = document.querySelector('button.save') + saveButton.addEventListener('click', saveImage) +}) + +document.addEventListener('keypress', (event) => { + if (event.keyCode === 99) { // the C key + saveImage() + } +}) + +function saveImage () { var svg = document.querySelector('svg') var inner = svg.innerHTML var head = ' ' + '' - var foot = '' + var foot = '' - var full = head + inner + foot; - - download(full, `custom-fox-${colorSeed}.svg`, 'image/svg+xml') - } -}) + var full = head + inner + foot; + download(full, `custom-fox-${colorSeed}.svg`, 'image/svg+xml') +} var createViewer = require('../index') diff --git a/index.html b/index.html index 500a7b9d..1944b394 100644 --- a/index.html +++ b/index.html @@ -14,5 +14,6 @@

Reload to get a fresh unique fox

--> -

Press C to save the SVG image.

+

Press C to save SVG

+ From 9267b96fa1ea38f44e1377b71802b0b126ac76ed Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 15 Nov 2019 23:04:03 -0800 Subject: [PATCH 10/14] Build --- bundle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundle.js b/bundle.js index b80aa0e7..1aefb2b3 100644 --- a/bundle.js +++ b/bundle.js @@ -1,5 +1,5 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i '+document.querySelector("svg").innerHTML+"",`custom-fox-${colorSeed}.svg`,"image/svg+xml")}window.addEventListener("load",()=>{document.querySelector("button.save").addEventListener("click",saveImage)}),document.addEventListener("keypress",e=>{99===e.keyCode&&saveImage()});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:colorSeed});function download(e,o,t){var n=new Blob([e],{type:t});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(n,o);else{var d=document.createElement("a"),r=URL.createObjectURL(n);d.href=r,d.download=o,document.body.appendChild(d),d.click(),setTimeout(function(){document.body.removeChild(d),window.URL.revokeObjectURL(r)},0)}}document.body.appendChild(viewer.container); +var createViewer=require("../index");const colorSeed=Math.floor(1e5*Math.random());function saveImage(){download(' '+document.querySelector("svg").innerHTML+"",`custom-fox-${colorSeed}.svg`,"image/svg+xml")}window.addEventListener("load",()=>{document.querySelector("button.save").addEventListener("click",saveImage)}),document.addEventListener("keypress",e=>{99===e.keyCode&&saveImage()});var viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0});function download(e,o,t){var n=new Blob([e],{type:t});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(n,o);else{var r=document.createElement("a"),d=URL.createObjectURL(n);r.href=d,r.download=o,document.body.appendChild(r),r.click(),setTimeout(function(){document.body.removeChild(r),window.URL.revokeObjectURL(d)},0)}}document.body.appendChild(viewer.container); },{"../index":3}],2:[function(require,module,exports){ module.exports={ From a116a89a6dc018ed8b33af695dc99825062139c2 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Sat, 16 Nov 2019 13:04:16 -0800 Subject: [PATCH 11/14] Nice improvements --- example/example.js | 29 +++++++++++++++++++++++++++-- index.html | 4 +++- index.js | 41 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/example/example.js b/example/example.js index 8c8bc5e8..d1f6124c 100644 --- a/example/example.js +++ b/example/example.js @@ -3,8 +3,28 @@ const colorSeed = Math.floor(Math.random() * 100000) window.addEventListener('load', () => { const saveButton = document.querySelector('button.save') saveButton.addEventListener('click', saveImage) + + const recolorButton = document.querySelector('button.recolor') + recolorButton.addEventListener('click', recolor) + + const cycleButton = document.querySelector('button.cycle') + cycleButton.addEventListener('click', toggleCycle) }) +let cycling = false +let cycleInterval +function toggleCycle () { + if (cycling && cycleInterval) { + console.dir(cycleInterval) + clearInterval(cycleInterval) + cycling = false + } else if (!cycling) { + cycleInterval = setInterval(recolor, 500) + cycling = true + } +} + + document.addEventListener('keypress', (event) => { if (event.keyCode === 99) { // the C key saveImage() @@ -30,10 +50,15 @@ var viewer = createViewer({ height: 0.4, followMouse: true, followMotion: true, - colorSeed, + // colorSeed, }) -document.body.appendChild(viewer.container) +function recolor() { + viewer.recolor(Math.floor(Math.random() * 10000000)) +} + +const foxDiv = document.querySelector('body div.fox') +foxDiv.appendChild(viewer.container) // Function to download data to a file function download(data, filename, type) { diff --git a/index.html b/index.html index 1944b394..1e67cba0 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@

Reload to get a fresh unique fox

-
+

Press C to save SVG

+ + diff --git a/index.js b/index.js index 03dac673..ec72fce7 100644 --- a/index.js +++ b/index.js @@ -93,16 +93,22 @@ module.exports = function createLogo (options_) { } })() - function Polygon (svg, indices) { + function Polygon (svg, indices, chunk) { this.svg = svg this.indices = indices this.zIndex = 0 + this.chunk = chunk } var polygons = (function () { var polygons = [] for (var i = 0; i < foxJSON.chunks.length; ++i) { var chunk = foxJSON.chunks[i] + + if (!chunk.polygons) { + chunk.polygons = [] + } + var color if (twister) { color = colors[Math.floor(twister.random() * colors.length)] @@ -126,7 +132,9 @@ module.exports = function createLogo (options_) { 'points', '0,0, 10,0, 0,10') container.appendChild(polygon) - polygons.push(new Polygon(polygon, f)) + const poly = new Polygon(polygon, f, chunk) + polygons.push(poly) + chunk.polygons.push(poly) } } return polygons @@ -330,11 +338,40 @@ module.exports = function createLogo (options_) { stopAnimation() } + function recolor (colorSeed) { + var twister + if (colorSeed) { + twister = new MersenneTwister(colorSeed) + } + + for(const chunk of foxJSON.chunks) { + let color + if (twister) { + color = colors[Math.floor(twister.random() * colors.length)] + } else { + color = 'rgb(' + chunk.color + ')' + } + + for (const polygon of chunk.polygons) { + setAttribute( + polygon.svg, + 'fill', + color) + setAttribute( + polygon.svg, + 'stroke', + color) + } + } + renderScene() + } + renderScene() return { container: container, lookAt: setLookAt, + recolor: recolor, setFollowMouse: setFollowMouse, setFollowMotion: setFollowMotion, stopAnimation: stopAnimation, From 5b1d0ba949fdae8e4468f13204a9c542ccc354bc Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Sat, 16 Nov 2019 13:04:26 -0800 Subject: [PATCH 12/14] Rebuild --- bundle.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundle.js b/bundle.js index b80aa0e7..d30c969b 100644 --- a/bundle.js +++ b/bundle.js @@ -1,5 +1,5 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i '+document.querySelector("svg").innerHTML+"",`custom-fox-${colorSeed}.svg`,"image/svg+xml")}window.addEventListener("load",()=>{document.querySelector("button.save").addEventListener("click",saveImage)}),document.addEventListener("keypress",e=>{99===e.keyCode&&saveImage()});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0,colorSeed:colorSeed});function download(e,o,t){var n=new Blob([e],{type:t});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(n,o);else{var d=document.createElement("a"),r=URL.createObjectURL(n);d.href=r,d.download=o,document.body.appendChild(d),d.click(),setTimeout(function(){document.body.removeChild(d),window.URL.revokeObjectURL(r)},0)}}document.body.appendChild(viewer.container); +const colorSeed=Math.floor(1e5*Math.random());window.addEventListener("load",()=>{document.querySelector("button.save").addEventListener("click",saveImage),document.querySelector("button.recolor").addEventListener("click",recolor),document.querySelector("button.cycle").addEventListener("click",toggleCycle)});let cycleInterval,cycling=!1;function toggleCycle(){cycling&&cycleInterval?(console.dir(cycleInterval),clearInterval(cycleInterval),cycling=!1):cycling||(cycleInterval=setInterval(recolor,500),cycling=!0)}function saveImage(){download(' '+document.querySelector("svg").innerHTML+"",`custom-fox-${colorSeed}.svg`,"image/svg+xml")}document.addEventListener("keypress",e=>{99===e.keyCode&&saveImage()});var createViewer=require("../index"),viewer=createViewer({width:.4,height:.4,followMouse:!0,followMotion:!0});function recolor(){viewer.recolor(Math.floor(1e7*Math.random()))}const foxDiv=document.querySelector("body div.fox");function download(e,o,t){var n=new Blob([e],{type:t});if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(n,o);else{var c=document.createElement("a"),r=URL.createObjectURL(n);c.href=r,c.download=o,document.body.appendChild(c),c.click(),setTimeout(function(){document.body.removeChild(c),window.URL.revokeObjectURL(r)},0)}}foxDiv.appendChild(viewer.container); },{"../index":3}],2:[function(require,module,exports){ module.exports={ @@ -1430,7 +1430,7 @@ module.exports={ } },{}],3:[function(require,module,exports){ -var perspective=require("gl-mat4/perspective"),multiply=require("gl-mat4/multiply"),lookAt=require("gl-mat4/lookAt"),invert=require("gl-mat4/invert"),rotate=require("gl-mat4/rotate"),transform=require("gl-vec3/transformMat4"),foxJSON=require("./fox.json"),colors=["#01888C","#FC7500","#034F5D","#F73F01","#FC1960","#C7144C","#F3C100","#1598F2","#2465E1","#F19E02"],MersenneTwister=require("mersenne-twister"),SVG_NS="http://www.w3.org/2000/svg";function createNode(t){return document.createElementNS(SVG_NS,t)}function setAttribute(t,e,n){t.setAttributeNS(null,e,n)}module.exports=function(t){var e,n=t||{},r=!!n.followMouse,o=!!n.followMotion,i=!!n.slowDrift,a=n.colorSeed;a&&(e=new MersenneTwister(a));var l=!0,s=[0,0],u=.3,h=n.width||400,f=n.height||400,c=createNode("svg"),d={x:0,y:0},w=foxJSON.positions.length,v=new Float32Array(3*w),g=new Float32Array(3*w),m=[];function p(t){var e=c.getBoundingClientRect();d.x=1-2*(t.x-e.left)/e.width,d.y=1-2*(t.y-e.top)/e.height}function A(t,e){this.svg=t,this.indices=e,this.zIndex=0}n.pxNotRatio||(h=window.innerWidth*(n.width||.25)|0,f=0|(window.innerHeight*n.height||h),"minWidth"in n&&h Date: Sat, 16 Nov 2019 13:10:41 -0800 Subject: [PATCH 13/14] Styling --- index.html | 17 ++++++----------- style.css | 4 ++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/index.html b/index.html index 1e67cba0..5abb1373 100644 --- a/index.html +++ b/index.html @@ -1,21 +1,16 @@ - + Security fox demo -

Reload to get a fresh unique fox

-
+
+

Press C to save SVG

+ + + - -

Press C to save SVG

- - - diff --git a/style.css b/style.css index c6d71951..9d562cdd 100644 --- a/style.css +++ b/style.css @@ -9,9 +9,9 @@ body{ font-family: roboto; } -div{ - height:140px; +div.fox{ overflow: visible; + cursor: none; } svg { From c13b5cf240466fdb958d8a20947ff7024ef544bb Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Sat, 16 Nov 2019 13:13:58 -0800 Subject: [PATCH 14/14] Adjust style link --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 5abb1373..fb845507 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - + Security fox demo