define(function(require, exports, module) { var Group = require('graphic/group'); var Circle = require('graphic/circle'); var Color = require('graphic/color'); var Text = require('graphic/text'); var Pen = require('graphic/pen'); var Matrix = require('graphic/matrix'); var Pie = require('../ringpalette/pie'); var Draggable = require('../public/draggable'); return require('core/class').createClass({ base: Group, mixins: [Draggable], constructor: function(innerRadius, outerRadius, trackCount, trackPieCount, initSaturation) { this.callBase(); this.innerRadius = innerRadius || 200; this.outerRadius = outerRadius || 400; this.trackCount = trackCount || 12; this.trackHeight = (this.outerRadius - this.innerRadius) / this.trackCount; this.trackPieCount = trackPieCount || 60; this.saturation = initSaturation || 50; this.generate(); this.control(); this.callMixin(); this.drag(); }, generate: function() { this.generateCircle(); this.generateTracks(); this.generateLabels(); }, generateCircle: function() { this.circle = new Circle(this.innerRadius); this.circle.stroke(new Pen('white', 5)); this.circle.setStyle('cursor', 'move'); this.addShape(this.circle); }, generateTracks: function() { this.pies = new Group(); for (var trackNumber = 0; trackNumber < this.trackCount; trackNumber++) { this.pies.addShapes(this.generateTrackPies(trackNumber)); } this.addShape(this.pies.rotate(0)); }, generateTrackPies: function(trackNumber) { var trackInnerRadius = this.innerRadius + this.trackHeight * trackNumber, trackOuterRadius = trackInnerRadius + this.trackHeight; var h, s = this.saturation, l = this.getTrackLightness(trackNumber); var color, pie; var hStep = 360 / this.trackPieCount; var trackPies = []; for (h = 0; h < 360; h += hStep) { color = Color.createHSL(h, s, l); pie = new Pie(trackInnerRadius + 1, trackOuterRadius, h + 0.2, h + hStep - 0.2); pie.fill(pie.color = color); trackPies.push(pie); } return trackPies; }, getTrackLightness: function(trackNumber) { var lMin = 20, lMax = 95; return lMin + trackNumber / this.trackCount * (lMax - lMin); }, generateLabels: function() { var fontSize = this.innerRadius / 6; this.rgbLabel = new Text().setTextAnchor('middle').setSize(fontSize).setY(-this.innerRadius / 8); this.hslLabel = new Text().setTextAnchor('middle').setSize(fontSize).setY(this.innerRadius / 4); this.addShape(this.rgbLabel); this.addShape(this.hslLabel); }, control: function() { var ring = this; this.on('mouseover', function(e) { var pie = e.targetShape; if (pie.getClass() == Pie) { var color = pie.color; pie.setScale(2).setTranslate(-pie.center.x, -pie.center.y); pie.stroke('white'); ring.setCircleColor(color); ring.bringFront(pie); } e.stopPropagation(); e.preventDefault(); }); this.on('mouseout', function(e) { var pie = e.targetShape; if (pie.getClass() == Pie) { pie.setScale(1).setTranslate(0, 0); pie.stroke('none'); ring.showSelected(); } }); this.on('click', function(e) { var pie = e.targetShape; if (pie.getClass() == Pie) { ring.selectedPie(pie); } }); }, selectedPie: function(pie) { if (this.selected) { this.selected.stroke('none'); } this.selected = pie; }, showSelected: function() { var pie = this.selected, pen; if (pie) { pen = new Pen().setWidth(5).setColor('white'); pie.stroke(pen); this.bringFront(pie); this.setCircleColor(pie.color); } }, setCircleColor: function(color) { this.circle.color = color; this.circle.fill(color); var labelColor = color.get('l') >= 50 ? color.dec('l', 50).set('s', 10) : color.inc('l', 50).set('s', 10); this.rgbLabel.setContent(color.toRGB()).fill(labelColor); this.hslLabel.setContent(color.toHSL()).fill(labelColor); }, bringFront: function(obj) { obj.container.removeShape(obj).addShape(obj); }, updateSaturation: function(s) { this.s = s; this.pies.eachItem(function(index, pie) { pie.fill(pie.color.set('s', s)); }); if (this.circle.color) { this.setCircleColor(this.circle.color.set('s', s)); } }, getPan: function() { this.pan = this.pan || { min: -this.outerRadius * 0.8, max: this.outerRadius * 0.8, length: this.outerRadius * 1.6, value: 0 }; return this.pan; }, drag: function() { return this.callMixin({ target: this.circle, move: function(e) { var pan = this.getPan(); pan.value += e.delta.x; pan.value = Math.min(pan.value, pan.max); pan.value = Math.max(pan.value, pan.min); this.updateSaturation(100 * (pan.value - pan.min) / pan.length); this.updatePosition(pan.value); } }); }, updatePosition: function(x) { this.setTranslate(x, 0); } }); });