swirl.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import hyperion, time, random
  2. # Convert x/y (0.0 - 1.0) point to proper int values based on Hyperion image width/height
  3. # Or get a random value
  4. # @param bool rand Randomize point if true
  5. # @param float x Point at the x axis between 0.0-1.0
  6. # @param float y Point at the y axis between 0.0-1.0
  7. # @return Tuple with (x,y) as Integer
  8. def getPoint(rand = True ,x = 0.5, y = 0.5):
  9. if rand:
  10. x = random.uniform(0.0, 1.0)
  11. y = random.uniform(0.0, 1.0)
  12. x = int(round(x*hyperion.imageWidth()))
  13. y = int(round(y*hyperion.imageHeight()))
  14. return (x,y)
  15. # Returns the required sleep time for a interval function based on rotationtime and steps
  16. # Adapts also to led device latchTime if required
  17. # @param float rt RotationTime in seconds (time for one ration, based on steps)
  18. # @param int steps The steps it should calc the rotation time
  19. # @return Tuple with (x,y) as Integer
  20. def getSTime(rt, steps = 360):
  21. rt = float(rt)
  22. sleepTime = max(0.1, rt) / steps
  23. # adapt sleeptime to hardware
  24. minStepTime= float(hyperion.latchTime)/1000.0
  25. if minStepTime == 0: minStepTime = 0.001
  26. if minStepTime > sleepTime:
  27. sleepTime = minStepTime
  28. return sleepTime
  29. # Creates a PRGBA bytearray gradient based on provided colors (RGB or RGBA (0-255, 0-1 for alpha)), the color stop positions are calculated based on color count. Requires at least 2 colors!
  30. # @param tuple cc Colors in a tuple of RGB or RGBA
  31. # @param bool closeCircle If True use last color as first color
  32. # @return bytearray A bytearray of RGBA for hyperion.image*Gradient functions
  33. def buildGradient(cc, closeCircle = True):
  34. if len(cc) > 1:
  35. withAlpha = False
  36. posfac = int(255/len(cc))
  37. ba = bytearray()
  38. pos = 0
  39. if len(cc[0]) == 4:
  40. withAlpha = True
  41. for c in cc:
  42. if withAlpha:
  43. alpha = int(c[3]*255)
  44. else:
  45. alpha = 255
  46. pos += posfac
  47. ba += bytearray([pos,c[0],c[1],c[2],alpha])
  48. if closeCircle:
  49. # last color as first color
  50. lC = cc[-1]
  51. if withAlpha:
  52. alpha = int(lC[3]*255)
  53. else:
  54. alpha = 255
  55. ba += bytearray([0,lC[0],lC[1],lC[2],alpha])
  56. return ba
  57. return bytearray()
  58. def rotateAngle( increment = 1):
  59. global angle
  60. angle += increment
  61. if angle > 360: angle=0
  62. if angle < 0: angle=360
  63. return angle
  64. def rotateAngle2( increment = 1):
  65. global angle2
  66. angle2 += increment
  67. if angle2 > 360: angle2=0
  68. if angle2 < 0: angle2=360
  69. return angle2
  70. # set minimum image size - must be done asap
  71. hyperion.imageMinSize(64,64)
  72. iW = hyperion.imageWidth()
  73. iH = hyperion.imageHeight()
  74. # Get the parameters
  75. rotationTime = float(hyperion.args.get('rotation-time', 10.0))
  76. reverse = bool(hyperion.args.get('reverse', False))
  77. centerX = float(hyperion.args.get('center_x', 0.5))
  78. centerY = float(hyperion.args.get('center_y', 0.5))
  79. randomCenter = bool(hyperion.args.get('random-center', False))
  80. custColors = hyperion.args.get('custom-colors', ((255,0,0),(0,255,0),(0,0,255)))
  81. enableSecond = bool(hyperion.args.get('enable-second', False))
  82. #rotationTime2 = float(hyperion.args.get('rotation-time2', 5.0))
  83. reverse2 = bool(hyperion.args.get('reverse2', True))
  84. centerX2 = float(hyperion.args.get('center_x2', 0.5))
  85. centerY2 = float(hyperion.args.get('center_y2', 0.5))
  86. randomCenter2 = bool(hyperion.args.get('random-center2', False))
  87. custColors2 = hyperion.args.get('custom-colors2', ((255,255,255,0),(0,255,255,0),(255,255,255,1),(0,255,255,0),(0,255,255,0),(0,255,255,0),(255,255,255,1),(0,255,255,0),(0,255,255,0),(0,255,255,0),(255,255,255,1),(0,255,255,0)))
  88. # process parameters
  89. pointS1 = getPoint(randomCenter ,centerX, centerY)
  90. pointS2 = getPoint(randomCenter2 ,centerX2, centerY2)
  91. sleepTime = getSTime(rotationTime)
  92. #sleepTime2 = getSTime(rotationTime2)
  93. angle = 0
  94. angle2 = 0
  95. S2 = False
  96. increment = -1 if reverse else 1
  97. increment2 = -1 if reverse2 else 1
  98. if len(custColors) > 1:
  99. baS1 = buildGradient(custColors)
  100. else:
  101. baS1 = bytearray([
  102. 0 ,255,0 ,0, 255,
  103. 25 ,255,230,0, 255,
  104. 63 ,255,255,0, 255,
  105. 100,0 ,255,0, 255,
  106. 127,0 ,255,200, 255,
  107. 159,0 ,255,255, 255,
  108. 191,0 ,0 ,255, 255,
  109. 224,255,0 ,255, 255,
  110. 255,255,0 ,127, 255,
  111. ])
  112. # check if the second swirl should be build
  113. if enableSecond and len(custColors2) > 1:
  114. S2 = True
  115. baS2 = buildGradient(custColors2)
  116. # effect loop
  117. while not hyperion.abort():
  118. angle += increment
  119. if angle > 360: angle=0
  120. if angle < 0: angle=360
  121. angle2 += increment2
  122. if angle2 > 360: angle2=0
  123. if angle2 < 0: angle2=360
  124. hyperion.imageConicalGradient(pointS1[0], pointS1[1], angle, baS1)
  125. if S2:
  126. hyperion.imageConicalGradient(pointS2[0], pointS2[1], angle2, baS2)
  127. hyperion.imageShow()
  128. time.sleep(sleepTime)