Forum Archive

Marching ants / looping dashed lines using animate

rb

Hi
How would I go about making a marching ants/continuously shifting dashed line effect between 2 fixed points using ui.animate anyone?

JonB

Path.set_line_dash(sequence[, phase])

Depending if you want this in scene or ui, the solution might be a little different. For ui, you would implement a custom draw () method that uses set_line_dash with an advancing phase before stroking.

cvp

@rb exemple of @jonb post

import ui

#Path.set_line_dash(sequence[, phase])
#Set the line-stroking pattern for the path. sequence is a list of numbers that contain the lengths of the line segments and gaps in the pattern. It starts with the first line segment length. phase is the offset at which to start drawing the pattern. For example, a phase value of 6 for the pattern [5, 2, 3, 2] would cause drawing to begin in the middle of the first gap.

class MyClass(ui.View):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.phase = 0
        self.seq = [3,3,1,1]
        self.update_interval = 0.1

    def update(self):
        self.phase = (self.phase + 1) % sum(self.seq)
        self.set_needs_display()

    def draw(self):
        s = ui.Path()
        s.move_to(100,100)
        s.line_to(200,200)
        ui.set_color('black')
        s.line_width = 1
        s.set_line_dash(self.seq,self.phase)
        s.stroke()

if __name__ == '__main__':
    w, h = 600, 800
    f = (0, 0, w, h)
    mc = MyClass(frame=f, bg_color='white')
    mc.present('sheet')
cvp

@rb of course, if you prefer real 🐜 you could try this πŸ˜‚

import ui
from objc_util import *
from math import cos,sin,pi

#Path.set_line_dash(sequence[, phase])
#Set the line-stroking pattern for the path. sequence is a list of numbers that contain the lengths of the line segments and gaps in the pattern. It starts with the first line segment length. phase is the offset at which to start drawing the pattern. For example, a phase value of 6 for the pattern [5, 2, 3, 2] would cause drawing to begin in the middle of the first gap.



class MyClass(ui.View):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        #self.phase = 0
        #self.seq = [3,3,1,1]
        #self.path = ui.Path()
        self.label_view = ui.View(name='label_view')
        o = ObjCInstance(self.label_view)
        self.label_view.frame = (150,100,200,20)
        l = ui.Label(name='l')
        l.frame = (0,0,self.label_view.width,self.label_view.height)
        l.font = ('Menlo',12)
        l.line_break_mode = ui.LB_CLIP
        l.text = '🐜'*200
        self.label_view.add_subview(l)
        a = -pi/4
        rot = CGAffineTransform(cos(a),-sin(a),sin(a),cos(a),0,0)
        o.transform = rot
        self.add_subview(self.label_view)
        self.update_interval = 0.1

    def update(self):
        #self.phase = (self.phase + 1) % sum(self.seq)
        self['label_view']['l'].x -= 1
        #if self['label_view']['l'].x < -20:
        #    self['label_view']['l'].x = 0
        self.set_needs_display()

    #def draw(self):
        #self.path.move_to(200,200)
        #self.path.line_to(100,100)
        #ui.set_color('black')
        #self.path.line_width = 1
        #self.path.set_line_dash(self.seq,self.phase)
        #self.path.stroke()

if __name__ == '__main__':
    w, h = 400,300
    f = (0, 0, w, h)
    mc = MyClass(frame=f, bg_color='white')
    mc.present('sheet')
rb

Yeah the real ants is what I was looking for obvs!

Thanks guys :)
I think I just really needed to understand that it’s not
.set_line_dash(sequence [,phase])
but more like:
.set_line_dash([10,15,10,15] ,phase)

Which is what was confusing me..
Duh