ringpalette.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. define(function(require, exports, module) {
  2. var Group = require('graphic/group');
  3. var Circle = require('graphic/circle');
  4. var Color = require('graphic/color');
  5. var Text = require('graphic/text');
  6. var Pen = require('graphic/pen');
  7. var Matrix = require('graphic/matrix');
  8. var Pie = require('../ringpalette/pie');
  9. var Draggable = require('../public/draggable');
  10. return require('core/class').createClass({
  11. base: Group,
  12. mixins: [Draggable],
  13. constructor: function(innerRadius, outerRadius, trackCount, trackPieCount, initSaturation) {
  14. this.callBase();
  15. this.innerRadius = innerRadius || 200;
  16. this.outerRadius = outerRadius || 400;
  17. this.trackCount = trackCount || 12;
  18. this.trackHeight = (this.outerRadius - this.innerRadius) / this.trackCount;
  19. this.trackPieCount = trackPieCount || 60;
  20. this.saturation = initSaturation || 50;
  21. this.generate();
  22. this.control();
  23. this.callMixin();
  24. this.drag();
  25. },
  26. generate: function() {
  27. this.generateCircle();
  28. this.generateTracks();
  29. this.generateLabels();
  30. },
  31. generateCircle: function() {
  32. this.circle = new Circle(this.innerRadius);
  33. this.circle.stroke(new Pen('white', 5));
  34. this.circle.setStyle('cursor', 'move');
  35. this.addShape(this.circle);
  36. },
  37. generateTracks: function() {
  38. this.pies = new Group();
  39. for (var trackNumber = 0; trackNumber < this.trackCount; trackNumber++) {
  40. this.pies.addShapes(this.generateTrackPies(trackNumber));
  41. }
  42. this.addShape(this.pies.rotate(0));
  43. },
  44. generateTrackPies: function(trackNumber) {
  45. var trackInnerRadius = this.innerRadius + this.trackHeight * trackNumber,
  46. trackOuterRadius = trackInnerRadius + this.trackHeight;
  47. var h,
  48. s = this.saturation,
  49. l = this.getTrackLightness(trackNumber);
  50. var color, pie;
  51. var hStep = 360 / this.trackPieCount;
  52. var trackPies = [];
  53. for (h = 0; h < 360; h += hStep) {
  54. color = Color.createHSL(h, s, l);
  55. pie = new Pie(trackInnerRadius + 1, trackOuterRadius, h + 0.2, h + hStep - 0.2);
  56. pie.fill(pie.color = color);
  57. trackPies.push(pie);
  58. }
  59. return trackPies;
  60. },
  61. getTrackLightness: function(trackNumber) {
  62. var lMin = 20,
  63. lMax = 95;
  64. return lMin + trackNumber / this.trackCount * (lMax - lMin);
  65. },
  66. generateLabels: function() {
  67. var fontSize = this.innerRadius / 6;
  68. this.rgbLabel = new Text().setTextAnchor('middle').setSize(fontSize).setY(-this.innerRadius / 8);
  69. this.hslLabel = new Text().setTextAnchor('middle').setSize(fontSize).setY(this.innerRadius / 4);
  70. this.addShape(this.rgbLabel);
  71. this.addShape(this.hslLabel);
  72. },
  73. control: function() {
  74. var ring = this;
  75. this.on('mouseover', function(e) {
  76. var pie = e.targetShape;
  77. if (pie.getClass() == Pie) {
  78. var color = pie.color;
  79. pie.setScale(2).setTranslate(-pie.center.x, -pie.center.y);
  80. pie.stroke('white');
  81. ring.setCircleColor(color);
  82. ring.bringFront(pie);
  83. }
  84. e.stopPropagation();
  85. e.preventDefault();
  86. });
  87. this.on('mouseout', function(e) {
  88. var pie = e.targetShape;
  89. if (pie.getClass() == Pie) {
  90. pie.setScale(1).setTranslate(0, 0);
  91. pie.stroke('none');
  92. ring.showSelected();
  93. }
  94. });
  95. this.on('click', function(e) {
  96. var pie = e.targetShape;
  97. if (pie.getClass() == Pie) {
  98. ring.selectedPie(pie);
  99. }
  100. });
  101. },
  102. selectedPie: function(pie) {
  103. if (this.selected) {
  104. this.selected.stroke('none');
  105. }
  106. this.selected = pie;
  107. },
  108. showSelected: function() {
  109. var pie = this.selected,
  110. pen;
  111. if (pie) {
  112. pen = new Pen().setWidth(5).setColor('white');
  113. pie.stroke(pen);
  114. this.bringFront(pie);
  115. this.setCircleColor(pie.color);
  116. }
  117. },
  118. setCircleColor: function(color) {
  119. this.circle.color = color;
  120. this.circle.fill(color);
  121. var labelColor = color.get('l') >= 50 ?
  122. color.dec('l', 50).set('s', 10) :
  123. color.inc('l', 50).set('s', 10);
  124. this.rgbLabel.setContent(color.toRGB()).fill(labelColor);
  125. this.hslLabel.setContent(color.toHSL()).fill(labelColor);
  126. },
  127. bringFront: function(obj) {
  128. obj.container.removeShape(obj).addShape(obj);
  129. },
  130. updateSaturation: function(s) {
  131. this.s = s;
  132. this.pies.eachItem(function(index, pie) {
  133. pie.fill(pie.color.set('s', s));
  134. });
  135. if (this.circle.color) {
  136. this.setCircleColor(this.circle.color.set('s', s));
  137. }
  138. },
  139. getPan: function() {
  140. this.pan = this.pan || {
  141. min: -this.outerRadius * 0.8,
  142. max: this.outerRadius * 0.8,
  143. length: this.outerRadius * 1.6,
  144. value: 0
  145. };
  146. return this.pan;
  147. },
  148. drag: function() {
  149. return this.callMixin({
  150. target: this.circle,
  151. move: function(e) {
  152. var pan = this.getPan();
  153. pan.value += e.delta.x;
  154. pan.value = Math.min(pan.value, pan.max);
  155. pan.value = Math.max(pan.value, pan.min);
  156. this.updateSaturation(100 * (pan.value - pan.min) / pan.length);
  157. this.updatePosition(pan.value);
  158. }
  159. });
  160. },
  161. updatePosition: function(x) {
  162. this.setTranslate(x, 0);
  163. }
  164. });
  165. });