calc_position.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package processing
  2. import (
  3. "math"
  4. "github.com/imgproxy/imgproxy/v3/imath"
  5. "github.com/imgproxy/imgproxy/v3/options"
  6. )
  7. func calcPosition(width, height, innerWidth, innerHeight int, gravity *options.GravityOptions, dpr float64, allowOverflow bool) (left, top int) {
  8. if gravity.Type == options.GravityFocusPoint {
  9. pointX := imath.ScaleToEven(width, gravity.X)
  10. pointY := imath.ScaleToEven(height, gravity.Y)
  11. left = pointX - innerWidth/2
  12. top = pointY - innerHeight/2
  13. } else {
  14. var offX, offY int
  15. if math.Abs(gravity.X) >= 1.0 {
  16. offX = imath.RoundToEven(gravity.X * dpr)
  17. } else {
  18. offX = imath.ScaleToEven(width, gravity.X)
  19. }
  20. if math.Abs(gravity.Y) >= 1.0 {
  21. offY = imath.RoundToEven(gravity.Y * dpr)
  22. } else {
  23. offY = imath.ScaleToEven(height, gravity.Y)
  24. }
  25. left = imath.ShrinkToEven(width-innerWidth+1, 2) + offX
  26. top = imath.ShrinkToEven(height-innerHeight+1, 2) + offY
  27. if gravity.Type == options.GravityNorth || gravity.Type == options.GravityNorthEast || gravity.Type == options.GravityNorthWest {
  28. top = 0 + offY
  29. }
  30. if gravity.Type == options.GravityEast || gravity.Type == options.GravityNorthEast || gravity.Type == options.GravitySouthEast {
  31. left = width - innerWidth - offX
  32. }
  33. if gravity.Type == options.GravitySouth || gravity.Type == options.GravitySouthEast || gravity.Type == options.GravitySouthWest {
  34. top = height - innerHeight - offY
  35. }
  36. if gravity.Type == options.GravityWest || gravity.Type == options.GravityNorthWest || gravity.Type == options.GravitySouthWest {
  37. left = 0 + offX
  38. }
  39. }
  40. var minX, maxX, minY, maxY int
  41. if allowOverflow {
  42. minX, maxX = -innerWidth+1, width-1
  43. minY, maxY = -innerHeight+1, height-1
  44. } else {
  45. minX, maxX = 0, width-innerWidth
  46. minY, maxY = 0, height-innerHeight
  47. }
  48. left = imath.Max(minX, imath.Min(left, maxX))
  49. top = imath.Max(minY, imath.Min(top, maxY))
  50. return
  51. }