Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 40 additions & 95 deletions Kaleidoscope/Kaleidoscope.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Visit http://createjs.com/ for documentation, updates and examples.
*
* Copyright (c) 2013 gskinner.com, inc.
*
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
Expand All @@ -12,10 +12,10 @@
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -35,88 +35,41 @@
* @class Kaleidoscope
* @param radius {Number} The radius of the kaleidoscope.
* @param source {DisplayObject} The DisplayObject to use as the source.
* The DisplayObject that will be drawn into each slice. Any transformations on the
* source display object will be applied when the slice is drawn.
* The source will be drawn multiple times (ex. 20 times for a 10 slice kaleidoscope).
* If the source is expensive to draw (a complex Shape, or Container with
* many children), then you may wish to pre-render the source a single time using
* the cache() method.
* @param [slices=8] {Number} The number of slices to draw.
* @param [pattern] {Array} Pattern of relative ratios for the slice sizes. For example, passing [1,2] would result in every second slice being twice as large as it's neighbors.
* @param [pad=0] {Number}
* Specifies the amount to overlap each slice with its neighbours to reduce seams
* between them. Generally a value of 0.6 works well, but you may wish to adjust this
* for sources with transparency.
* You may still see seams if your source draws multiple times into each slice. For
* example, a Container with multiple children. Pre-rendering the source by using the
* cache() method should resolve this.
* @extends DisplayObject
* @constructor
**/
var Kaleidoscope = function(radius, source, slices, pattern) {
this.initialize(radius, source, slices, pattern);
function Kaleidoscope (radius, source, slices, pattern, pad) {
this.DisplayObject_constructor();
if (!pattern) { pattern = [1]; }
if (!slices) { slices = 8; }
if (!pad) { pad = 0; }
this.radius = radius;
this.source = source;
this.pad = pad;
var l = pattern.length;
if (slices/pattern.length%1 != 0) { throw "slices must be divisible by pattern length"; }
var ttl = 0;
for (var i=0; i<slices; i++) { ttl += pattern[i%l]; }
var s = this._slices = [];
for (var i=0; i<slices; i++) { s[i] = pattern[i%l]/ttl*Math.PI; }
}
var p = Kaleidoscope.prototype = new createjs.DisplayObject();
var p = createjs.extend(Kaleidoscope, createjs.DisplayObject);

// public properties:
/**
* The DisplayObject that will be drawn into each slice. Any transformations on the
* source display object will be applied when the slice is drawn.
*
* The source will be drawn multiple times (ex. 20 times for a 10 slice kaleidoscope).
* If the source is expensive to draw (a complex Shape, or Container with
* many children), then you may wish to pre-render the source a single time using
* the cache() method.
* @property source
* @type DisplayObject
* @default null
**/
p.source = null;

/**
* The radius of the kaleidoscope in pixels.
* @property radius
* @type Number
* @default 0
**/
p.radius = 0;

/**
* Specifies the amount to overlap each slice with its neighbours to reduce seams
* between them. Generally a value of 0.6 works well, but you may wish to adjust this
* for sources with transparency.
*
* You may still see seams if your source draws multiple times into each slice. For
* example, a Container with multiple children. Pre-rendering the source by using the
* cache() method should resolve this.
* @property pad
* @type Number
* @default 0
**/
p.pad = 0;

// private properties:
/**
* @property _slices
* @type Array
* @private
**/
p._slices = null; // size in radians of each slice.

// constructor:
/**
* @property DisplayObject_initialize
* @type Function
* @private
**/
p.DisplayObject_initialize = p.initialize;

/**
* Initialization method.
* @method initialize
* @protected
*/
p.initialize = function(radius, source, slices, pattern) {
this.DisplayObject_initialize();
if (!pattern) { pattern = [1]; }
if (!slices) { slices = 8; }
this.radius = radius;
this.source = source;
var l = pattern.length;
if (slices/pattern.length%1 != 0) { throw "slices must be divisible by pattern length"; }
var ttl = 0;
for (var i=0; i<slices; i++) { ttl += pattern[i%l]; }
var s = this._slices = [];
for (var i=0; i<slices; i++) { s[i] = pattern[i%l]/ttl*Math.PI; }
}

// public methods:
/**
* Returns true or false indicating whether the display object would be visible if drawn to a canvas.
Expand All @@ -127,16 +80,9 @@ var p = Kaleidoscope.prototype = new createjs.DisplayObject();
**/
p.isVisible = function() {
var hasContent = this.cacheCanvas || (this._slices && this.source);
return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && hasContent);
}

/**
* @property DisplayObject_draw
* @type Function
* @private
**/
p.DisplayObject_draw = p.draw;

/**
* Draws the display object into the specified context ignoring it's visible, alpha, shadow, and transform.
* Returns true if the draw was handled (useful for overriding functionality).
Expand All @@ -158,10 +104,10 @@ var p = Kaleidoscope.prototype = new createjs.DisplayObject();
this._drawSlice(ctx, r-a, a, false, pad);
r += a*2;
}

return true;
}

/**
* Returns a string representation of this object.
* @method toString
Expand All @@ -171,11 +117,10 @@ var p = Kaleidoscope.prototype = new createjs.DisplayObject();
return "[Kaleidoscope]";
}


// private methods:
p._drawSlice = function(ctx, r, a, mirror, pad) {
ctx.save();

ctx.rotate(r+a);
if (mirror) { ctx.scale(1,-1); }
ctx.beginPath();
Expand All @@ -184,12 +129,12 @@ var p = Kaleidoscope.prototype = new createjs.DisplayObject();
ctx.lineTo(-this.pad,this.pad);
ctx.closePath();
ctx.clip();

this.source.updateContext(ctx);
this.source.draw(ctx);

ctx.restore();
}
window.Kaleidoscope = Kaleidoscope;
}());

window.Kaleidoscope = createjs.promote(Kaleidoscope, "DisplayObject");
}());
26 changes: 13 additions & 13 deletions Kaleidoscope/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,51 @@
<canvas id="demo" width="800" height="800">
</canvas><br>
Nebula image by NASA.


<script src="http://code.createjs.com/createjs-2013.02.12.min.js"></script>

<script src="https://code.createjs.com/createjs-2015.05.21.min.js"></script>
<script src="Kaleidoscope.js"></script><script>
var imagePath = "imgs/pic.jpg";
var c = createjs;
var q, radius, stage, source, kal;

(function init() {
q = new c.LoadQueue(false);
q.loadFile(imagePath);
q.addEventListener("complete", run);
q.on("complete", run);
})();

function run(evt) {
stage = new c.Stage("demo");
var w = stage.canvas.width;
var h = stage.canvas.height

// calculate the radius of the kaleidoscope:
radius = w/2-10;

source = new c.Bitmap(q.getResult(imagePath));
// set the center point:
source.regX = source.image.width/2;
source.regY = source.image.height/2;
// scale to fill the radius:
source.scaleX = radius/source.image.width*2;
source.scaleY = radius/source.image.height*2;

// create the kaleidoscope:
kal = stage.addChild(new Kaleidoscope(radius, source, 6, [3,5,3,1,7,1]));
kal.rotation = 18; // straighten it (necessary because of complex pattern)
// center on the stage:
kal.x = w/2;
kal.x = w/2;
kal.y = h/2;
c.Ticker.addEventListener("tick", tick);

c.Ticker.on("tick", tick);
}

function tick() {
source.rotation -= 1;
stage.update();
}

</script>
</body>
</html>
</html>