index.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { isNodePattern } from '@jimp/utils';
  2. /**
  3. * Creates a circle out of an image.
  4. * @param {object} options (optional) r: radius of effect
  5. * @param {function(Error, Jimp)} cb (optional) a callback for when complete
  6. * @returns {Jimp} this for chaining of methods
  7. */
  8. export default () => ({
  9. fisheye(options = { r: 2.5 }, cb) {
  10. if (typeof options === 'function') {
  11. cb = options;
  12. options = { r: 2.5 };
  13. }
  14. const source = this.cloneQuiet();
  15. const { width, height } = source.bitmap;
  16. source.scanQuiet(0, 0, width, height, (x, y) => {
  17. const hx = x / width;
  18. const hy = y / height;
  19. const r = Math.sqrt(Math.pow(hx - 0.5, 2) + Math.pow(hy - 0.5, 2));
  20. const rn = 2 * Math.pow(r, options.r);
  21. const cosA = (hx - 0.5) / r;
  22. const sinA = (hy - 0.5) / r;
  23. const newX = Math.round((rn * cosA + 0.5) * width);
  24. const newY = Math.round((rn * sinA + 0.5) * height);
  25. const color = source.getPixelColor(newX, newY);
  26. this.setPixelColor(color, x, y);
  27. });
  28. /* Set center pixel color, otherwise it will be transparent */
  29. this.setPixelColor(
  30. source.getPixelColor(width / 2, height / 2),
  31. width / 2,
  32. height / 2
  33. );
  34. if (isNodePattern(cb)) {
  35. cb.call(this, null, this);
  36. }
  37. return this;
  38. }
  39. });