Skip to content

Instantly share code, notes, and snippets.

@jsbain
Created Jan 8, 2015
Embed
What would you like to do?
path_edit.py
'''
useless path editor.
tap to add a point. tap again to add a control point.
then, another control point, and finally another point on the curve.
existing points and control points can be dragged around, to change the curve.
clicking save button saves an image of the path, without the handles.
'''
import ui
LINE_COLOR=(0,0,0,1)
PT_COLOR=(1,0,0,0.5)
CP_COLOR=(0,0,1,0.5)
ACTIVE_COLOR=(1,0,1,0.5)
class path_editor(ui.View):
def __init__(self):
self.pts=[]
self.touch_enabled=True
self.idx_active=None
def touch_began(self,touch):
# first, find nearby point
xt,yt=touch.location
self.idx_active=None
for i,(x,y) in enumerate( self.pts):
#simple hit check.. will find last point within 10 pix
if (xt-x)**2+(yt-y)**2 < 20**2:
self.idx_active=i
if self.idx_active is None:
self.pts.append(touch.location)
self.idx_active=len(self.pts)-1
self.set_needs_display()
def touch_moved(self,touch):
self.pts[self.idx_active]=touch.location
self.set_needs_display()
def touch_ended(self,touch):
#pass
self.idx_active=None
self.set_needs_display()
def _draw(self,show_handles=False ):
# draw spline, optionally with handles shown
P=ui.Path()
if not self.pts:
return
#handles
if show_handles:
cp=0
for i,(x,y) in enumerate(self.pts):
if cp:
ui.set_color(ACTIVE_COLOR if self.idx_active==i else CP_COLOR)
ui.Path.oval(x-10,y-10,20,20).fill()
else:
ui.set_color(PT_COLOR)
ui.Path.rect(x-10,y-10,20,20).stroke()
if self.idx_active==i:
ui.Path.rect(x-10,y-10,20,20).fill()
cp=(cp+1)%3
#draw tangent lines connecting points to handles
i=0
P2=ui.Path()
ui.set_color((.5,.5,.5,.2))
while (i+1)<len(self.pts):
P2.move_to(*self.pts[i])
P2.line_to(*self.pts[i+1])
i=i+3
i=2
while (i+1)<len(self.pts):
P2.move_to(*self.pts[i])
P2.line_to(*self.pts[i+1])
i=i+3
P2.stroke()
#draw curve
P.move_to(*self.pts[0])
i=1
while (i+2)<len(self.pts):
ui.set_color(LINE_COLOR)
P.add_curve(*(self.pts[i+2]+self.pts[i]+self.pts[i+1]))
i=i+3
P.stroke()
def draw(self):
#called by ui system to redraw view
self._draw(True )
def save_img(self,sender):
#save curve.png, and show in console.
import StringIO, ImageFile
with ui.ImageContext(self.width,self.height) as ctx:
self._draw(False )
img=ctx.get_image()
img.show()
parser=ImageFile.Parser()
parser.feed(img.to_png())
pil_image=parser.close()
pil_image.save('curve.png')
v=path_editor()
b=ui.Button(title='save',bg_color=(.9,.9,.9))
b.frame=(0,0,50,50)
b.action=v.save_img
v.add_subview(b)
v.bg_color=(1,1,1)
v.present('sheet')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment