TOUCH TO NEW SPIN
Expand Branding
1
<!-- BUG UFO SPINNER! License: GPL2 or Later. Author: Kenta Ishii, Tokyo. -->
2
<!-- If you have any wrong feeling, stop to watch BUG UFO SPINNER! -->
3
<style scoped>
4
div#bugufo-spinner {
5
display: block;
6
position: relative;
7
top: 0;
8
left: 0;
9
width: 100%;
10
height: 100%;
11
padding: 0;
12
margin: 0;
13
}
14
15
canvas#bugufo-spinner-canvas {
16
display: block;
17
position: relative;
18
top: 0;
19
left: 0;
20
padding: 0;
21
margin: 0;
22
}
23
24
div#svg-bugufo-spinner-container1 {
25
display: block;
26
position: absolute;
27
bottom: 0;
28
left: 0;
29
padding: 0;
30
margin: 0;
31
opacity: 0.6;
32
animation-name: svg-bugufo-spinner-container1-keyframes;
33
animation-duration: 10s;
34
animation-direction: alternate;
35
animation-iteration-count: infinite;
36
37
}
38
39
@keyframes svg-bugufo-spinner-container1-keyframes {
40
0% { transform: translateY(-100%); }
41
100% { transform: translateY(0); }
42
}
43
44
/* Magic Word Anyway To Display Correctly */
45
svg {
46
display: block;
47
position: relative;
48
padding: 0;
49
margin: 0;
50
-webkit-user-select: none;
51
-moz-user-select: none;
52
-ms-user-select: none;
53
user-select: none;
54
}
55
56
svg text {
57
-webkit-user-select: none;
58
-moz-user-select: none;
59
-ms-user-select: none;
60
user-select: none;
61
}
62
63
svg#bugufo-spinner-svg1 {
64
opacity: 0;
65
transition: opacity 10s linear;
66
}
67
</style>
68
69
<!-- To get click event, wrap canvas and svg -->
70
<div id="bugufo-spinner">
71
<canvas id="bugufo-spinner-canvas">
72
</canvas>
73
<div id="svg-bugufo-spinner-container1">
74
<svg id="bugufo-spinner-svg1" viewbox="0 0 960 120">
75
<style>
76
@import url(https://fonts.googleapis.com/css?family=Barrio);
77
</style>
78
<defs>
79
<linearGradient id="svg-bugufo-spinner-subtitle1-gradient1" gradientUnits="objectBoundingBox" x1="0" x2="0" y1="0" y2="1">
80
<stop offset="0" stop-color="white" />
81
<stop offset="0.5" stop-color="blue" />
82
<stop offset="1" stop-color="black" stop-opacity="0.6" />
83
</linearGradient>
84
<!-- userSpaceOnUse is just like pixels. objectBoundingBox is 0 to 1 dimension -->
85
<mask id="svg-bugufo-spinner-subtitle1-textmask1" maskUnits="objectBoundingBox" x="0" y="0" width="1" height="1" maskContentUnits="userSpaceOnUse">
86
<g font-family="Barrio" font-size="90" font-weight="bold">
87
<rect fill="white" x="0" y="0" width="960" height="120" />
88
<!-- text-anchor: start, middle, end -->
89
<!-- dominant-baseline: auto, alphabetic, etc. -->
90
<text id="svg-bugufo-spinner-subtitle1-textmask1-text1" fill="black" x="480" y="90" text-anchor="middle">TOUCH TO NEW SPIN</text>
91
</g>
92
</mask>
93
</defs>
94
<g id="svg-bugufo-spinner-subtitle1">
95
<rect id="svg-bugufo-spinner-subtitle1-rect1" x="0" y="0" width="960" height="120" fill="url(#svg-bugufo-spinner-subtitle1-gradient1)" mask="url(#svg-bugufo-spinner-subtitle1-textmask1)" />
96
</g>
97
</svg>
98
</div>
99
</div>
100
101
<!-- Vertex Shader -->
102
<script id="bugufo-spinner-shader-vertex1" type="x-shader/x-vertex">
103
attribute vec3 aVertexPosition;
104
105
uniform mat4 uMMatrix;
106
uniform float uPointSize;
107
108
void main( void ) {
109
gl_Position = uMMatrix * vec4( aVertexPosition, 1.0 );
110
gl_PointSize = uPointSize;
111
}
112
</script>
113
114
<!-- Fragment Shader -->
115
<!-- xyzw for geometry, rgba for color, stpq for texture -->
116
<script id="bugufo-spinner-shader-fragment1" type="x-shader/x-fragment">
117
precision mediump float;
118
precision mediump int;
119
120
uniform sampler2D uSampler;
121
uniform mat2 uRMatrix;
122
uniform mat2 uSMatrix;
123
uniform mat2 uSkewMatrix;
124
125
void main( void ) {
126
// 0 to 1 Coordinates to -1 to 1 Coordinates
127
vec2 center = vec2( gl_PointCoord.s * 2.0 - 1.0, gl_PointCoord.t * 2.0 - 1.0 );
128
vec2 point = uRMatrix * uSkewMatrix * uSMatrix * center;
129
// -1 to 1 Coordinates to 0 to 1 Coordinates
130
point = vec2( point.s / 2.0 + 0.5, point.t / 2.0 + 0.5 );
131
if ( point.s > 1.0 || point.s < 0.0 || point.t > 1.0 || point.t < 0.0 ) {
132
discard;
133
}
134
vec4 texel = texture2D( uSampler, point );
135
if ( texel.a == 0.0 ) {
136
discard;
137
}
138
139
gl_FragColor = texel;
140
}
141
</script>
142
143
<!-- Vertices -->
144
<script id="bugufo-spinner-vertex-point" type="application/json">
145
{
146
"geometry": {
147
"vertices": [
148
[0.0, 0.0, 0.0]
149
],
150
"index": [
151
1
152
]
153
}
154
}
155
</script>
156
157
<!-- Actual JavaScript Code to Run -->
158
<script type="text/javascript" defer>
159
(function() {
160
// Get Elements to Use
161
var wrap_canvas = document.getElementById('bugufo-spinner');
162
var canvas = document.getElementById('bugufo-spinner-canvas');
163
var display = wrap_canvas.parentNode;
164
if ( ! display.classList.contains('jimmy-branding-content') ) {
165
display = null;
166
}
167
var svg1 = document.getElementById('bugufo-spinner-svg1');
168
var svg1_text = document.getElementById('svg-bugufo-spinner-subtitle1-textmask1-text1');
169
var svg1_container = document.getElementById('svg-bugufo-spinner-container1');
170
171
if ( ! display ) {
172
// To Preview
173
canvas.width = '600';
174
canvas.style.width = '600px';
175
canvas.height = '600';
176
canvas.style.height = '600px';
177
}
178
179
// Activate SENOR and Display
180
var THE_SENOR = new SENORWEBGL1();
181
var ATTACHER = new SENORUTL.attachDisplayOfJimmyBranding({ canvas: canvas, display: display, context: THE_SENOR });
182
183
// Sizing SVG to Fit Canvas
184
svg1.setAttribute( 'width', ATTACHER.width );
185
svg1.setAttribute( 'height', Math.round( ATTACHER.width / 8 ) );
186
// To Hide Ugly Style
187
svg1.style.opacity = 1.0;
188
189
THE_SENOR.activate({
190
canvas: canvas,
191
color: [0.0, 1.0, 1.0, 1.0],
192
enable_cullface: false,
193
enable_depthtest: false
194
});
195
196
// Create Rendering Object
197
// For Rotation, Shrink Scale. Caution! it's REVERSAL as opposed to regular scaling!
198
// Because this script uses to expand texture pointing for scaling, not to expand vertices!
199
var theSamplePoint = new THE_SENOR.Object({
200
sx: 1 / 0.7,
201
sy: 1 / 0.7,
202
x_radius: 0.1,
203
y_radius: 0.1,
204
z_radius: 0.1
205
});
206
207
// Get Vertices Object Above
208
var point_object = SENORUTL.object3D( SENORUTL.attachJSONRaw('bugufo-spinner-vertex-point') );
209
210
// Register Vertices and Texture Objects to Rendering Object
211
theSamplePoint.registerVao({
212
vertices:
213
[
214
point_object.geometry
215
],
216
geometry_mode: THE_SENOR.gl.POINTS,
217
textures:
218
[
219
THE_SENOR.texture2DByPath({
220
url: "http://electronics.jimmykenmerchant.com/wp-content/uploads/2017/06/bugufo.png",
221
min_filter: THE_SENOR.gl.NEAREST,
222
mag_filter: THE_SENOR.gl.NEAREST,
223
use_mipmap: false
224
})
225
]
226
});
227
228
// Register Shaders with Attributes
229
theSamplePoint.registerShaders({
230
vertex_shader: "bugufo-spinner-shader-vertex1",
231
fragment_shader: "bugufo-spinner-shader-fragment1",
232
attributes:
233
[
234
"aVertexPosition"
235
],
236
// e.g. if the attribute is vec3 in the shader, unit_length is "3"
237
unit_length: [3]
238
});
239
240
// Register Function by Aliasing
241
theSamplePoint.registerUniforms( setUniforms );
242
243
// Make Array of Rendering Object
244
var thePointArray = new THE_SENOR.ArrayObject( theSamplePoint );
245
246
// Make Adding Function to Array
247
function newThePointArray( count ) {
248
for ( var i = 0; i < count; i++ ) {
249
thePointArray.add({
250
x: 0.0, // Hidden First
251
y: 0.0, // Hidden First
252
z: SENORUTL.getRandomFloat( -1.0, 1.0 ),
253
x_speed: SENORUTL.getRandomFloat( -0.001, 0.001 ),
254
y_speed: SENORUTL.getRandomFloat( -0.001, 0.001 ),
255
z_speed: SENORUTL.getRandomFloat( -0.001, 0.001 ),
256
rx: 0,
257
rx_speed: SENORUTL.getRandomInt( -5, 5 ),
258
reserve: [
259
0.0, // point size initialize
260
SENORUTL.getRandomFloat( 0.1, 1.1 ), // radius
261
0.0, // x radian initialize
262
0.0, // y radian initialize
263
1 // Hit Point
264
]
265
});
266
}
267
}
268
269
// Make Checker Function for Collision
270
function checker() {
271
for ( var i = 0; i < thePointArray.length; i++ ) {
272
// Equivalent to while loop
273
for ( var j = i + 1; j < thePointArray.length; j++ ) {
274
if ( ( SENORUTL.hitCheck( thePointArray[i], thePointArray[j] ) ) ) {
275
thePointArray[i].reserve[4]--;
276
thePointArray[j].reserve[4]--;
277
}
278
}
279
}
280
}
281
282
var timeoutid_touch = null;
283
284
// When Click Canvas, BUG UFOs Will Be Vanished, Then Will Be Created Again
285
// In JavaScript, return false only stop default trigger or NOTHING
286
// In jQuery, stop both by return false
287
// So in JavaScript, you need to declare stopPropagation and/or preventDefault
288
// Using Unlike Bubbling Phase (Up Stream), Capturing Phase (Down Stream)
289
wrap_canvas.addEventListener( 'click', function( e ) {
290
svg1_text.textContent = 'THE BUG NEW SPIN!';
291
292
if ( timeoutid_touch !== null ) {
293
window.clearTimeout( timeoutid_touch );
294
}
295
timeoutid_touch = window.setTimeout( function() {
296
svg1_text.textContent = 'TOUCH TO NEW SPIN';
297
}, 2000 );
298
299
thePointArray.deleteAll();
300
newThePointArray( 5 );
301
302
e.stopPropagation();
303
e.preventDefault();
304
}, false );
305
306
// When Click SVG
307
// Using Unlike Bubbling Phase (Up Stream), Capturing Phase (Down Stream)
308
svg1_container.addEventListener( 'click', function( e ) {
309
svg1_text.textContent = 'Touch Triangle?';
310
311
if ( timeoutid_touch !== null ) {
312
window.clearTimeout( timeoutid_touch );
313
}
314
timeoutid_touch = window.setTimeout( function() {
315
svg1_text.textContent = 'TOUCH TO NEW SPIN';
316
}, 2000 );
317
318
e.stopPropagation();
319
e.preventDefault();
320
}, false );
321
322
// SVG Resizing When Window Resize
323
window.addEventListener( 'resize', function( e ) {
324
svg1.setAttribute( 'width', ATTACHER.width );
325
svg1.setAttribute( 'height', Math.round( ATTACHER.width / 8 ) );
326
}, false );
327
328
// Create Objects in the Array
329
newThePointArray( 5 );
330
331
// The Loop to Render
332
333
var timeoutid_mainloop = null;
334
var previous_time = null;
335
var delta = 0;
336
337
// To Suppress Texture Error on Some Browsers, Add Onload
338
window.addEventListener( 'load', function() {
339
!function() {
340
341
var current_time = (new Date).getTime();
342
if ( previous_time ) {
343
delta = current_time - previous_time;
344
}
345
previous_time = current_time;
346
347
THE_SENOR.clear();
348
349
thePointArray.zSort();
350
//thePointArray.sort( z_sort );
351
352
thePointArray.pict({
353
attributes:
354
{
355
delta: delta
356
}
357
});
358
359
checker();
360
361
for ( var i = 0; i < thePointArray.length; i++ ) {
362
var subject = thePointArray[i];
363
if ( subject.z === 1.0 ) {
364
thePointArray.delete(i);
365
i--;
366
367
newThePointArray( 1 );
368
}
369
}
370
371
// Clear Callback
372
if ( timeoutid_mainloop !== null ) {
373
window.clearTimeout( timeoutid_mainloop );
374
}
375
376
// Repeat This Method
377
timeoutid_mainloop = window.setTimeout( arguments.callee, 40 );
378
379
}();
380
}, false );
381
382
// To Check Original Sort Function with Embedded Sort Function in Array Object
383
// 'SENOR' uses Original Array Object Inherited JavaScript Array Object
384
function z_sort( a, b ) {
385
return ( a.z + 1.0 ) - ( b.z + 1.0 ) ;
386
}
387
388
// To Set Uniforms When Rendering. Attached by 'SENORWEBGL1.Object.registerUniforms'
389
// 'parameter' is defined on 'SENORWEBGL1.Object.pict' or 'SENORWEBGL1.ArrayObject.pict'
390
// Use 'self' instead of 'SENORWEBGL1' Context, Use 'this' insted of 'SENORWEBGL1.Object'
391
function setUniforms( parameter, self ) {
392
if ( typeof parameter.attributes.delta !== "number" || parameter.attributes.delta === null ) {
393
parameter.attributes.delta = 0;
394
}
395
396
// Change Status of Each Object
397
398
var shaders = this.shaders[parameter.shader_index];
399
400
// Change z 0 to 2.0
401
var regulated_z = ( this.z + 1.0 );
402
403
this.reserve[0] = ATTACHER.width * this.x_radius * 2 * regulated_z;
404
405
var delta = parameter.attributes.delta;
406
407
// X Position
408
this.reserve[2] += this.x_speed * delta;
409
if ( this.reserve[2] > 6.28 ) {
410
this.reserve[2] -= 6.28;
411
}
412
if ( this.reserve[2] < -6.28 ) {
413
this.reserve[2] += 6.28;
414
}
415
this.x = Math.sin( this.reserve[2] ) * this.reserve[1];
416
417
// Y Position
418
this.reserve[3] += this.y_speed * delta;
419
if ( this.reserve[3] > 6.28 ) {
420
this.reserve[3] -= 6.28;
421
}
422
if ( this.reserve[3] < -6.28 ) {
423
this.reserve[3] += 6.28;
424
}
425
this.y = Math.cos( this.reserve[3] ) * this.reserve[1];
426
427
// Z Position
428
this.z += this.z_speed * delta;
429
430
if ( this.x > 1.0 ) {
431
this.x = 1.0;
432
this.x_speed = -Math.abs( this.x_speed );
433
}
434
435
if ( this.x < -1.0 ) {
436
this.x = -1.0;
437
this.x_speed = Math.abs( this.x_speed );
438
}
439
440
if ( this.y > 1.0 ) {
441
this.y = 1.0;
442
this.y_speed = -Math.abs( this.y_speed );
443
}
444
445
if ( this.y < -1.0 ) {
446
this.y = -1.0;
447
this.y_speed = Math.abs( this.y_speed );
448
}
449
450
if ( this.z > 1.0 ) {
451
this.z = 1.0;
452
this.z_speed = -Math.abs( this.z_speed );
453
}
454
455
if ( this.z < -1.0 ) {
456
this.z = -1.0;
457
this.z_speed = Math.abs( this.z_speed );
458
}
459
460
if ( this.reserve[4] <= 0 ) {
461
this.reserve[4] = 1;
462
this.x_speed = -this.x_speed;
463
}
464
465
// Rotation
466
this.rx += this.rx_speed;
467
if ( this.rx > 360.0 ) {
468
this.rx -= 360.0;
469
}
470
if ( this.rx < -360.0 ) {
471
this.rx += 360.0;
472
}
473
474
// Uniform Settings Below
475
476
self.gl.activeTexture( self.gl.TEXTURE0 );
477
self.gl.bindTexture( self.gl.TEXTURE_2D, this.textures[this.vao_index][0] );
478
self.gl.uniform1i( self.gl.getUniformLocation( shaders.program, "uSampler" ), 0 );
479
480
var uMMatrix = self.gl.getUniformLocation( shaders.program, "uMMatrix" );
481
var trans_mat4 = SENORUTL.translateMat4([this.x, this.y, this.z]);
482
self.gl.uniformMatrix4fv( uMMatrix, false, new Float32Array( trans_mat4 ) );
483
484
var uPointSize = self.gl.getUniformLocation( shaders.program, "uPointSize" );
485
self.gl.uniform1f( uPointSize, this.reserve[0] );
486
487
var uRMatrix = self.gl.getUniformLocation( shaders.program, "uRMatrix" );
488
var rotate_mat2 = SENORUTL.rotateMat2( this.rx );
489
self.gl.uniformMatrix2fv( uRMatrix, false, new Float32Array( rotate_mat2 ) );
490
491
// Scaling S and T of Texture Pointing
492
// The result is reversal than scaling vertices
493
var uSMatrix = self.gl.getUniformLocation( shaders.program, "uSMatrix" );
494
var scale_mat2 = SENORUTL.scaleMat2( this.sx, this.sy );
495
self.gl.uniformMatrix2fv( uSMatrix, false, new Float32Array( scale_mat2 ) );
496
497
var uSkewMatrix = self.gl.getUniformLocation( shaders.program, "uSkewMatrix" );
498
var skew_mat2 = SENORUTL.skewMat2( 0, 0 );
499
self.gl.uniformMatrix2fv( uSkewMatrix, false, new Float32Array( skew_mat2 ) );
500
}
501
})();
502
</script>
441 Views