Ajax Loader
HTML
<div class='info'>
1
<div class='info'>
2
  <hgroup class='about'>
3
    <h1>Kaleidoscope</h1>
4
    <h2>Canvas kaleidoscope implementation with drag & drop</h2>
5
    <h3>Drop an image</h3>
6
  </hgroup>
7
</div>
 
CSS
@charset "UTF-8";
1
@charset "UTF-8";
2
@import url(http://fonts.googleapis.com/css?family=Quantico);
3
html, body {
4
  background: #ffffff;
5
}
6
 
7
/* Info */
8
@keyframes show-info {
9
  0% {
10
    transform: rotateY(120deg);
11
  }
12
  100% {
13
    transform: rotateY(0deg);
14
  }
15
}
16
.info {
17
  transition: all 180ms ease-out;
18
  transform-style: preserve-3d;
19
  transform: perspective(800px);
20
  font-family: "Quantico", sans-serif;
21
  position: absolute;
22
  font-size: 12px;
23
  opacity: 0.8;
24
  color: #fff;
25
  width: 240px;
26
  left: 0px;
27
  top: 20px;
28
}
29
.info:hover {
30
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.05);
31
  opacity: 1;
32
}
33
.info h1, .info h2, .info h3 {
34
  line-height: 1;
35
  margin: 5px 0;
36
}
37
.info a {
38
  transition: all 200ms ease-out;
39
  border-bottom: 1px dotted rgba(255, 255, 255, 0.4);
40
  text-decoration: none;
41
  opacity: 0.6;
42
  color: #fff;
43
}
44
.info a:hover {
45
  opacity: 0.99;
46
}
47
.info .about,
48
.info .more {
49
  transform-origin: 0% 50%;
50
  transform: rotateY(120deg);
51
  margin-bottom: 1px;
52
  background: rgba(0, 0, 0, 0.8);
53
  padding: 12px 15px 12px 20px;
54
}
55
.info .about {
56
  animation: show-info 500ms cubic-bezier(0.23, 1, 0.32, 1) 600ms 1 normal forwards;
57
  padding-bottom: 15px;
58
}
59
.info .about a {
60
  opacity: 0.9;
61
}
62
.info .about h1 {
63
  letter-spacing: -1px;
64
  font-weight: 300;
65
  font-size: 19px;
66
  opacity: 0.95;
67
}
68
.info .about h2 {
69
  font-weight: 300;
70
  font-size: 13px;
71
  opacity: 0.8;
72
}
73
.info .about h3 {
74
  text-transform: uppercase;
75
  margin-top: 10px;
76
  font-size: 11px;
77
}
78
.info .about h3:before {
79
  margin-right: 2px;
80
  font-size: 14px;
81
  content: "›";
82
}
83
.info .more {
84
  animation: show-info 500ms cubic-bezier(0.23, 1, 0.32, 1) 500ms 1 normal forwards;
85
  padding: 5px 15px 10px 20px;
86
}
87
.info .more a {
88
  text-transform: uppercase;
89
  margin-right: 10px;
90
  font-size: 10px;
91
}
92
 
 
JavaScript
(function() {
1
(function() {
2
  var DragDrop, Kaleidoscope, c, dragger, gui, i, image, kaleidoscope, len, onChange, onMouseMoved, options, ref, tr, tx, ty, update,
3
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
4
 
5
  Kaleidoscope = (function() {
6
    Kaleidoscope.prototype.HALF_PI = Math.PI / 2;
7
 
8
    Kaleidoscope.prototype.TWO_PI = Math.PI * 2;
9
 
10
    function Kaleidoscope(options1) {
11
      var key, ref, ref1, val;
12
      this.options = options1 != null ? options1 : {};
13
      this.defaults = {
14
        offsetRotation: 0.0,
15
        offsetScale: 1.0,
16
        offsetX: 0.0,
17
        offsetY: 0.0,
18
        radius: 500,
19
        slices: 5,
20
        zoom: 1.0
21
      };
22
      ref = this.defaults;
23
      for (key in ref) {
24
        val = ref[key];
25
        this[key] = val;
26
      }
27
      ref1 = this.options;
28
      for (key in ref1) {
29
        val = ref1[key];
30
        this[key] = val;
31
      }
32
      if (this.domElement == null) {
33
        this.domElement = document.createElement('canvas');
34
      }
35
      if (this.context == null) {
36
        this.context = this.domElement.getContext('2d');
37
      }
38
      if (this.image == null) {
39
        this.image = document.createElement('img');
40
      }
41
    }
42
 
43
    Kaleidoscope.prototype.draw = function() {
44
      var cx, i, index, ref, results, scale, step;
45
      this.domElement.width = this.domElement.height = this.radius * 2;
46
      this.context.fillStyle = this.context.createPattern(this.image, 'repeat');
47
      scale = this.zoom * (this.radius / Math.min(this.image.width, this.image.height));
48
      step = this.TWO_PI / this.slices;
49
      cx = this.image.width / 2;
50
      results = [];
51
      for (index = i = 0, ref = this.slices; 0 <= ref ? i <= ref : i >= ref; index = 0 <= ref ? ++i : --i) {
52
        this.context.save();
53
        this.context.translate(this.radius, this.radius);
54
        this.context.rotate(index * step);
55
        this.context.beginPath();
56
        this.context.moveTo(-0.5, -0.5);
57
        this.context.arc(0, 0, this.radius, step * -0.51, step * 0.51);
58
        this.context.lineTo(0.5, 0.5);
59
        this.context.closePath();
60
        this.context.rotate(this.HALF_PI);
61
        this.context.scale(scale, scale);
62
        this.context.scale([-1, 1][index % 2], 1);
63
        this.context.translate(this.offsetX - cx, this.offsetY);
64
        this.context.rotate(this.offsetRotation);
65
        this.context.scale(this.offsetScale, this.offsetScale);
66
        this.context.fill();
67
        results.push(this.context.restore());
68
      }
69
      return results;
70
    };
71
 
72
    return Kaleidoscope;
73
 
74
  })();
75
 
76
  DragDrop = (function() {
77
    function DragDrop(callback, context, filter) {
78
      var disable;
79
      this.callback = callback;
80
      this.context = context != null ? context : document;
81
      this.filter = filter != null ? filter : /^image/i;
82
      this.onDrop = bind(this.onDrop, this);
83
      disable = function(event) {
84
        event.stopPropagation();
85
        return event.preventDefault();
86
      };
87
      this.context.addEventListener('dragleave', disable);
88
      this.context.addEventListener('dragenter', disable);
89
      this.context.addEventListener('dragover', disable);
90
      this.context.addEventListener('drop', this.onDrop, false);
91
    }
92
 
93
    DragDrop.prototype.onDrop = function(event) {
94
      var file, reader;
95
      event.stopPropagation();
96
      event.preventDefault();
97
      file = event.dataTransfer.files[0];
98
      if (this.filter.test(file.type)) {
99
        reader = new FileReader;
100
        reader.onload = (function(_this) {
101
          return function(event) {
102
            return typeof _this.callback === "function" ? _this.callback(event.target.result) : void 0;
103
          };
104
        })(this);
105
        return reader.readAsDataURL(file);
106
      }
107
    };
108
 
109
    return DragDrop;
110
 
111
  })();
112
 
113
  image = new Image;
114
 
115
  image.onload = (function(_this) {
116
    return function() {
117
      return kaleidoscope.draw();
118
    };
119
  })(this);
120
 
121
  image.src = 'https://40.media.tumblr.com/a5ec5aa4d800cbcf895ec473c06b57ec/tumblr_nnlc1jOBDr1qzgaw0o1_500.png';
122
 
123
  kaleidoscope = new Kaleidoscope({
124
    image: image,
125
    slices: 10
126
  });
127
 
128
  kaleidoscope.domElement.style.position = 'absolute';
129
 
130
  kaleidoscope.domElement.style.marginLeft = -kaleidoscope.radius + 'px';
131
 
132
  kaleidoscope.domElement.style.marginTop = -kaleidoscope.radius + 'px';
133
 
134
  kaleidoscope.domElement.style.left = '50%';
135
 
136
  kaleidoscope.domElement.style.top = '50%';
137
 
138
  document.body.appendChild(kaleidoscope.domElement);
139
 
140
  dragger = new DragDrop(function(data) {
141
    return kaleidoscope.image.src = data;
142
  });
143
 
144
  tx = kaleidoscope.offsetX;
145
 
146
  ty = kaleidoscope.offsetY;
147
 
148
  tr = kaleidoscope.offsetRotation;
149
 
150
  onMouseMoved = (function(_this) {
151
    return function(event) {
152
      var cx, cy, dx, dy, hx, hy;
153
      cx = window.innerWidth / 2;
154
      cy = window.innerHeight / 2;
155
      dx = event.pageX / window.innerWidth;
156
      dy = event.pageY / window.innerHeight;
157
      hx = dx - 0.5;
158
      hy = dy - 0.5;
159
      tx = hx * kaleidoscope.radius * -2;
160
      ty = hy * kaleidoscope.radius * 2;
161
      return tr = Math.atan2(hy, hx);
162
    };
163
  })(this);
164
 
165
  window.addEventListener('mousemove', onMouseMoved, false);
166
 
167
  options = {
168
    interactive: true,
169
    ease: 0.1
170
  };
171
 
172
  (update = (function(_this) {
173
    return function() {
174
      var delta, theta;
175
      if (options.interactive) {
176
        delta = tr - kaleidoscope.offsetRotation;
177
        theta = Math.atan2(Math.sin(delta), Math.cos(delta));
178
        kaleidoscope.offsetX += (tx - kaleidoscope.offsetX) * options.ease;
179
        kaleidoscope.offsetY += (ty - kaleidoscope.offsetY) * options.ease;
180
        kaleidoscope.offsetRotation += (theta - kaleidoscope.offsetRotation) * options.ease;
181
        kaleidoscope.draw();
182
      }
183
      return setTimeout(update, 1000 / 60);
184
    };
185
  })(this))();
186
 
187
  gui = new dat.GUI;
188
 
189
  gui.add(kaleidoscope, 'zoom').min(0.25).max(2.0);
190
 
191
  gui.add(kaleidoscope, 'slices').min(6).max(32).step(2);
192
 
193
  gui.add(kaleidoscope, 'radius').min(200).max(500);
194
 
195
  gui.add(kaleidoscope, 'offsetX').min(-kaleidoscope.radius).max(kaleidoscope.radius).listen();
196
 
197
  gui.add(kaleidoscope, 'offsetY').min(-kaleidoscope.radius).max(kaleidoscope.radius).listen();
198
 
199
  gui.add(kaleidoscope, 'offsetRotation').min(-Math.PI).max(Math.PI).listen();
200
 
201
  gui.add(kaleidoscope, 'offsetScale').min(0.5).max(4.0);
202
 
203
  gui.add(options, 'interactive').listen();
204
 
205
  gui.close();
206
 
207
  onChange = (function(_this) {
208
    return function() {
209
      kaleidoscope.domElement.style.marginLeft = -kaleidoscope.radius + 'px';
210
      kaleidoscope.domElement.style.marginTop = -kaleidoscope.radius + 'px';
211
      options.interactive = false;
212
      return kaleidoscope.draw();
213
    };
214
  })(this);
215
 
216
  ref = gui.__controllers;
217
  for (i = 0, len = ref.length; i < len; i++) {
218
    c = ref[i];
219
    if (c.property !== 'interactive') {
220
      c.onChange(onChange);
221
    }
222
  }
223
 
224
}).call(this);
225
 
 

Hex Kaleidoscope #1

CSSDeck G+