Navigation

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Users
    • Groups
    • Solved
    • Unsolved
    • Search
    1. Home
    2. eduairet
    3. Posts
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Posts made by eduairet

    • RE: Script to Standalone app

      Thanks Frederik πŸ™‚ you've helped me a lot!!!

      posted in Code snippets
      eduairet
      eduairet
    • RE: Script to Standalone app

      @eduairet I tried this and now opens the script and it's not giving me errors but it still doesn't run entirely:

      openWindows = Quartz.CGWindowListCopyWindowInfo(
          Quartz.kCGWindowListOptionOnScreenOnly | Quartz.kCGWindowListExcludeDesktopElements, Quartz.kCGNullWindowID
      )
      openWindows = [window.get('kCGWindowName', u'Unknown').encode('ascii','ignore') for window in openWindows if window['kCGWindowOwnerName'] == 'DrawBot']
      if b'main.py' not in openWindows:
          os.system(f'open -a DrawBot {__file__}')
      
      posted in Code snippets
      eduairet
      eduairet
    • RE: Script to Standalone app

      Debugger shows the problem now:

      Traceback (most recent call last):
        File "main.py", line 45, in <module>
        File "drawBot/drawBotDrawingTools.pyc", line 2548, in Variable
      drawBot.misc.DrawBotError: There is no document open
      

      It works if I run main.py does it need to open a window first and then run Variable? πŸ€”

      posted in Code snippets
      eduairet
      eduairet
    • RE: Script to Standalone app

      @frederik thanks!!! I just got curious about it. I'm having a problem with the package, it doesn't open the script when I open it in DrawBot, this is the tree I have

      myPackage.drawbot
      β”œβ”€β”€ info.plist
      └── lib
          β”œβ”€β”€ squareAdjustments.py
          β”œβ”€β”€ logoAdjustments.py
          β”œβ”€β”€ fontAdjustments.py
          β”œβ”€β”€ userText.py
          β”œβ”€β”€ main.py
          β”œβ”€β”€ resources
          β”‚Β Β  └── fonts
          β”‚Β Β      β”œβ”€β”€ VF.ttf
          β”‚Β Β      └── Logo.otf
          └── save.py
      

      When I open main by itself it runs

      posted in Code snippets
      eduairet
      eduairet
    • RE: Script to Standalone app

      Is there a way to execute the Run command using shell or applescript?

      posted in Code snippets
      eduairet
      eduairet
    • RE: Script to Standalone app

      @frederik sweet, I’ll give the package a try, I thought about using the app because it needs to be an executable and avoid the run part of the workflow.

      posted in Code snippets
      eduairet
      eduairet
    • Script to Standalone app

      Hey there!

      I'm attempting to make a standalone app with a drawbot script using py2app and drawBot as a module. I'm having a lot of trouble with the Variable menu, the error I'm having so far is raise DrawBotError("There is no document open") when the script gets to Variable(menuElements, globals()) I'm speculating about how to solve it, Do I need to assign a document to the class or something like that?

      posted in Code snippets
      eduairet
      eduairet
    • RE: Chess board in one loop

      @monomonnik Wow! This is beautiful, thanks for taking your time making an approach, and also for sharing it. It makes sense how you solve it and gives me more ideas to make more challenges like this!

      posted in General Discussion
      eduairet
      eduairet
    • Chess board in one loop

      Hi everyone, I'm putting some effort making basic exercises more challenging, right now I'm struggling with a chess board, I usually solve this with two loops and conditionals, but my challenge is to do it in one loop and with no conditionals, here is what I've done so far:

      side = 800
      newPage(side, side)
      square = side//8
      with savedState(): fill(1), rect(0, 0, side, side)
      y, advance = 0, 0
      while y < side:
          rect(square * (advance%2), y, square, square)
          rect(square * (advance%2) + square*2, y, square, square)
          rect(square * (advance%2) + square*4, y, square, square)
          rect(square * (advance%2) + square*6, y, square, square)
          y += square
          advance += 1
      

      Do you have any smarter idea to solve this coding challenge?
      Thanks!

      posted in General Discussion
      eduairet
      eduairet
    • RE: Gradient rings from Python for Designers tutorial

      @frederik thank you very much! 😊 I'll implement this way

      posted in Tutorials
      eduairet
      eduairet
    • Gradient rings from Python for Designers tutorial

      Hello everyone!!!

      I'm attempting to solve the exΒ­erΒ­cise 14.4 of @roberto-arista 's pythonfordesigners.com/chapters/workbook/ I'm having a problem with my approach, I decided to use circles instead of lines and I couldn't find a way to make a smooth gradient without having a weird hole πŸ•³ in the middle of the right top and right bottom blending, here's a photo of it:

      Screen Shot 2021-01-11 at 13.55.29.png

      # 14.4
      def donuts(circSize=10, cnvSize=200):
          
          def intrp(factor, val1, val2):
              return val1 + (val2 - val1) * factor
              
          def intrRgb(factor, col1, col2):
              r = intrp(factor, col1[0], col2[0])
              g = intrp(factor, col1[1], col2[1])
              b = intrp(factor, col1[2], col2[2])
              return r, g, b
              
          def circCoords(radius, circSize=10):
              cirCoords = []
              an = 0
              anMulti = 0
              for i in range(cnvSize+1):
                  for j in range(cnvSize):
                      cirCoords.append([
                          radius * sin(pi * 2 * an / 360) - halfCirc,
                          radius * cos(pi * 2 * an / 360) - halfCirc
                      ])
                      an += 360/(cnvSize*cnvSize)
              return sorted(cirCoords)
              
          def mapColors(c1, c2, c3, c4):
              colors = []
              for x in range(cnvSize):
                  xFactor = x/cnvSize
                  for y in range(cnvSize):
                      yFactor = y / cnvSize
                      lftClr = intrRgb(yFactor, c4, c1)
                      rgtClr = intrRgb(yFactor, c3, c2)
                      colors.append(intrRgb(xFactor, lftClr, rgtClr))       
              return colors
          
          halfCirc = circSize/2
          colors = {'lftTop': (1, 0, 0.8), 'rgtTop': (1, 1, 0.3), 'rgtBtm': (1, .8, 0), 'lftBtm': (0, 0.5, 1)} 
          
          colors = mapColors(colors['lftTop'], colors['rgtTop'], colors['rgtBtm'], colors['lftBtm'])
          circles = [circCoords(cnvSize*0.4, circSize), circCoords(cnvSize*0.25, circSize), circCoords(cnvSize*0.1, circSize)]
          
          newPage(cnvSize, cnvSize)
          inc = 0
          for x in range(cnvSize):
              for y in range(cnvSize):
                  fill(*colors[inc])
                  if x == 0 and y == 0 or x == 0 and y == cnvSize-1 or x == cnvSize-1 and y == 0 or x == cnvSize-1 and y == cnvSize-1:
                      oval(x - halfCirc, y - halfCirc, circSize, circSize)
                  if y == int(circles[0][inc][1]) + cnvSize/2 - 1 or y == int(circles[0][inc][1]) + cnvSize - 100:
                      for circ in circles:
                          with savedState():
                              translate(cnvSize/2, cnvSize/2)
                              oval(circ[inc][0], circ[inc][1], circSize, circSize)
                  inc += 1
      
      # Call the function
      donuts()
      

      Hope you can help me, feedback on my approach would be great too, thank you!!!!!!!

      posted in Tutorials
      eduairet
      eduairet
    • RE: how to code a gif that gradually transform one picture into another

      Hi, hope this helps:

      # Get your gif routes
      gifsFolder = '.' # Your gifs directory
      gifs = ['gif1.gif', 'gif2.gif'] # These are the files I'll use
      gifPaths = [f'{gifsFolder}/{gif}' for gif in gifs] # Create the paths for your with string formattingx
      
      # Create a function to interpolate between gifs
      
      def scaleFactor(path, pageNumber, canvasSize): # Get a scale factor to match the canvas size you want
          gifw, gifh = imageSize(path, pageNumber=pageNumber)
          factorMeasure = gifw
          if gifw > gifh:
              factorMeasure = gifh
          return  canvasSize / factorMeasure
      
      def gifTransition(path1, path2):
          # Canvas and images dimensions
          w, h = 200, 200 # Canvas size
          
          # Define your frames
          introFrames = numberOfPages(path1)
          endingFrames = numberOfPages(path2)
          crossfadeFrames = 12 # Change this value for a longer transition
          totalFrames = int(
              (introFrames - crossfadeFrames/2)+(endingFrames - crossfadeFrames/2)
              ) # Get the total frames by merging the crossfade in the middle 
          
          # Make a loop for the animation
          gif1Frames, gif2Frames = 0, 0
          gif1alpha, gif2alpha = 1, 0
          for frame in range(1, totalFrames+1):
              newPage(w, h)
              fill(1)
              rect(0, 0, w, h)
              with savedState():
                  scale(scaleFactor(path1, gif1Frames, w))
                  image(path1, (0, 0), pageNumber=gif1Frames, alpha=gif1alpha)
              if gif1Frames < introFrames:
                  gif1Frames += 1
              if frame > introFrames - crossfadeFrames/2: # Run the second gif
                  with savedState():
                      scale(scaleFactor(path2, gif2Frames, w))
                      image(path2, (0, 0), pageNumber=gif2Frames, alpha=gif2alpha)
                  gif2Frames += 1
                  if gif1alpha >= 0 or gif2alpha <= 1: # Crossfade transparency
                      gif1alpha -= 1 / crossfadeFrames
                      gif2alpha += 1 / crossfadeFrames
                  
      gifTransition(gifPaths[0], gifPaths[1]) # Call the function
      saveImage('~/Desktop/gifCrossfade.gif') # Save your gif
      
      posted in General Discussion
      eduairet
      eduairet
    • RE: Tutorial Request: Delay Animation

      @vitorcarvalho wow, this is lovely!!!

      posted in Tutorials
      eduairet
      eduairet
    • RE: Tutorial Request: Delay Animation

      I found this very interesting so I tried to do it without a lot of success, I ended with something like this:

      w, h = 1000, 1000
      divs = 10
      colSize, rowSize = w//divs, h//divs
      fps = 12
      seconds = 1
      duration = 1 / fps
      totalFrames = seconds * fps
      
      def circles(step):
          for x in range(0, w, colSize):
              for y in range(0, h, rowSize):
                  d = rowSize * sin(y/(divs/2)+step)
                  if d > 0:
                      fill(1)
                  else:
                      fill(1, 0, 0)
                  oval(x + colSize/2 - d/2, y + rowSize/2 - d/2 , d, d)
       
      for frame in range(totalFrames):
          newPage(w, h)
          frameDuration(duration)
          fill(0)
          rect(0, 0, w, h)
          circles(frame)
              
      saveImage("~/Desktop/circleTest.gif")
      

      I'm not understanding how the time works in the reference to achieve the smooth variation

      posted in Tutorials
      eduairet
      eduairet
    • Vertical Align

      I'm looking for a property to work with textBox() to align the text to the vertical center. What I'm imagining is something like this:

      textBox(
          'DrawBot is great',
          (
              width()*0.2,
              height()*0.2,
              width()*0.6,
              height()*0.6
          ),
          align = 'center',
          verticalAlign = 'center'
      )
      

      This way you can come up with a random playing with that verticalAlign or something like that 😊

      posted in Feature Requests
      eduairet
      eduairet
    • RE: Loop image generation breaks at index 16

      @frederik OMG it works now!!! thank you very much!!!! 😊 Happy holidays!!!

      posted in General Discussion
      eduairet
      eduairet
    • RE: Loop image generation breaks at index 16

      Here a handy script to generate files to test, if you use it this way you should change the following line:

      if len(row['\ufeffNAME']) > 0:
                data.append(row['\ufeffNAME'])
      

      to

      if len(row['NAME']) > 0:
                data.append(row['NAME'])
      
      import os
      import csv
      
      def fullNameGenerator():
          name = ''
          lastName = ''
          for letter in range(randint(4,10)):
              name += choice(letters)
          for letter in range(randint(4,10)):
              lastName += choice(letters)      
          fullName = name.title() + ' ' + lastName.title()
          return fullName
      
      letters = 'abcdefghijklmnopqrstuvwxyz'
      myMessage ='I wish you the best holidays ever! With All my love for you:'
      
      myPath = './'
      myDir = 'dataFiles'
      myDirPath = myPath + myDir
      if myDir not in os.listdir(myPath):
          os.mkdir(myPath + myDir)
      
      with open(myDirPath + '/xmasMessage.txt', 'w') as xmasMsg: 
          xmasMsg.write(myMessage)
          
      with open(myDirPath + '/xmasList.csv', 'w', newline='') as xmasList:
          csv_writter = csv.writer(xmasList)
          
          csv_writter.writerow(['NAME'])
          
          names = []
          for i in range(40):
              names.append([fullNameGenerator()])
      
          for row in names:
              csv_writter.writerow(row)
      

      And the snowflake pdf
      https://drive.google.com/file/d/1EZxopDsOjd-K7ur-QQm-Xc_0zj7dGPkv/view?usp=sharing

      Thanks again!!

      posted in General Discussion
      eduairet
      eduairet
    • Loop image generation breaks at index 16

      Hi, I'm making custom Christmas gif postcards, everything's working until the loop reaches the 16th value of my list, I tried making them individually and it works, but when I try a for loop it gets stuck like in an infinite loop but I don't know why. Does anyone know what's happening?

      import csv
      import unicodedata
      import os
      
      def strip_accents(text):
          try:
              text = unicode(text, 'utf-8')
          except NameError: # unicode is a default on python 3 
              pass
          text = unicodedata.normalize('NFD', text)\
                 .encode('ascii', 'ignore')\
                 .decode("utf-8")
          return str(text)
      
      # Typeface
      canelaUnordered = []
      for font in installedFonts():
          if 'Canela' in font:
              canelaUnordered.append(font)
      canelaIndexes = [2, 3, 0, 1, 8, 9, 6, 7, 4, 5, 14, 15, 12, 13, 10, 11]
      canela = []
      for i in range(len(canelaUnordered)):
          canela.append(canelaUnordered[canelaIndexes[i]])    
      
      # Data for custom images
      data = []
      with open('./xmasList.csv', newline='', encoding='UTF-8') as data_csv:
        data_reader = csv.DictReader(data_csv,  delimiter=',', quotechar='|')
        for row in data_reader:
            if len(row['\ufeffNAME']) > 0:
                data.append(row['\ufeffNAME'])
                
      # Main copywrite
      cw = open('./xmasMessage.txt', 'r', encoding='UTF-8')
      cw = cw.read()  
                
      # Design class
      class Postcard():
          
          def __init__(self, x=1600, y=1600, m=160):
              self.x = x
              self.y = y
              self.m = m 
              self.tree = BezierPath()
              self.tree.moveTo((self.m, self.y*0.18))
              self.tree.lineTo((self.x/2, self.y *0.90))
              self.tree.lineTo((self.x - (self.m), self.y*0.18))
              self.tree.closePath()
      
          def c(self, val):
              if type(isinstance(val, (int, float))):
                  if val <= 255:
                      return val / 255
                  else:
                      raise Exception("Sorry, just numbers below 255")
          
          def hexToRGB(self, val):
              val = val.lstrip('#')
              lv = len(val)
              color = [int(val[i:i + lv // 3], 16) for i in range(0, lv, lv // 3)]
              r, g, b = color[0], color[1], color[2]
              return self.c(r), self.c(g), self.c(b)
          
          def copy(self, cw = cw):
              self.cw = cw
              words = self.cw.split()
              txtFillone = self.hexToRGB('#FFFFFF')
              txt = FormattedString(
                  'β€’\n',
                  font = canela[1],
                  fontSize=160,
                  lineHeight=200,
                  fill = (txtFillone[0], txtFillone[1], txtFillone[2]),
                  align = 'center'
                  )
              
              txt.append('2020\n'.upper(), font=canela[1], fontSize=158, lineHeight=159)
              txt.append('Merry '.upper(), font = canela[4], fontSize=94, lineHeight=100)
              txt.append('Xmas'.upper() + '\nβ€’\n', font = canela[2])
              
              boldWords = ['holidays']
              breakWords = ['ever!']
              
              for word in words:
                  txt.append('', fontSize=48, lineHeight=52, paragraphBottomSpacing=52)
                  if word in boldWords:
                      txt.append(word + ' ', font = canela[13])
                  elif word in breakWords:
                      txt.append(word + '\n', font = canela[13])
                  else:
                      txt.append(word + ' ', font = canela[11])
                  
              logo = FormattedString(
                  'Sincerely eat\n',
                   align='center', font = canela[10], fontSize=80, lineHeight=180, fill=(1)
                  )
                  
              textBox(txt, self.tree)
              text(logo, (self.x/2, self.m))
              
          def receiver(self, tx, limit = 100):
              rFnt = canela[2]
              textSize = FormattedString(tx, font = rFnt, fontSize=1, lineHeight=1, align='center')
              rSz = 1180 / textSize.size()[0]
              if rSz > limit:
                  rSz = limit
              receiver = FormattedString(tx,font=rFnt, fontSize=rSz, lineHeight=rSz, align='center', fill=(1))
              text(receiver, (self.x/2, self.y*0.20))
              stroke(2)
              strokeWidth(6)
              line((self.x*0.17, self.y*0.28), (self.x*0.83, self.y*0.28))
              
          def snow(self, copos=30, path='./snowFlake.pdf'):
              w, h = imageSize(path)
              copo = ImageObject(path)
              for i in range(copos):
                  scaleFactor = randint(1, 5) * 0.1
                  with savedState():
                      translate(randint(0, self.x), randint(self.y*0.12, self.y))
                      scale(scaleFactor)
                      image(copo, (-w/2, -h/2))
          
          def canvas(self, bgColor='#FF5900'):
              newPage(self.x, self.y)
          
              if type(bgColor) == list:
                  self.bgColor = self.c(bgColor[0]), self.c(bgColor[1]), self.c(bgColor[2])
              elif type(bgColor) == str:
                  if len(bgColor) == 7 or len(bgColor) == 4 or len(bgColor) == 6 or len(bgColor) == 3: 
                      self.bgColor = self.hexToRGB(bgColor)
                  else:
                      raise Exception("Sorry, incorrect HexValue")
              else:
                  raise Exception("Sorry, use one of the following formats: [r, g, b] or Hex value")
      
              fill(self.bgColor[0], self.bgColor[1], self.bgColor[2])
              rect(0, 0, self.x, self.y)
          
          def drawTree(self, deg):
              fill(0.1, 0.4, 0.3)
              stroke(0.1, 0.4, 0.3)
              strokeWidth(100)
              with savedState():
                  rotate(deg, center=(self.x/2, self.y/2))
                  drawPath(self.tree)
              
          def save(self, tx, user='eat', message='merryXmas2020'):
              fileName = strip_accents(tx).lower().strip().replace(' ', '_')
              saveDir = '2020_xmasCards'
              saveLoc = '/Users/{}/Desktop/'.format(user)
              if saveDir not in os.listdir(path=saveLoc):
                  os.mkdir(saveLoc + saveDir)
              saveImage(saveLoc + saveDir + '/' + message + '_{}.gif'.format(fileName), imageResolution = 72)
              print(message + '_{}.gif'.format(fileName) + ' Done')
              newDrawing()
      
      def postcardGenerator(data, save=True, frames = 2):
          deg = 2
          rot = -2
          for i in range(frames): 
              card = Postcard()    
              card.canvas()
              card.drawTree(deg)
              card.snow()
              card.copy()
              card.receiver(data)
              if i == int(frames/2):
                  rot *= -1
              deg += rot
          if save:
              card.save(data)
      
      # Ceate postcards
      for field in data:
          postcardGenerator(field)
      
      # testNum = 0
      # postcardGenerator(data[testNum], False)
      

      If you make the whole list with the testNum it works which makes me think that the problem is not in the external files I'm using.

      Thank you for your help!!

      posted in General Discussion
      eduairet
      eduairet
    • RE: QRCodeGenerator(size, message)

      @gferreira WOW!!!! you saved my ass again, you're amazing, thanks a lot!!!

      posted in General Discussion
      eduairet
      eduairet
    • QRCodeGenerator(size, message)

      Hi DrawBot fellas!!

      I'm struggling with the QRCodeGenerator() ImageObject() property, I got two errors, the first one is TypeError: Expecting byte-buffer, got str when I try to pass a URL, and when I try to encode the URL TypeError: cannot unpack non-iterable float object

      Is it possible that you can help me to figure out what's happening?

      Here's the way I'd love to use it:

      path = 'https://www.mypath.com'
      
      newPage(1000, 1000)
      qr = ImageObject()
      path = path.encode('utf-8')
      qr.QRCodeGenerator(100, path)
      
      image(qr, (0, 0, width(), height()))
      

      And here's the way I made it with the qrcode module by making a png first and then using it inside my drawbot image

      import qrcode
      path = 'https//:www.mypath.com'
      qr = qrcode.QRCode(
          version = 1,
          error_correction = qrcode.constants.ERROR_CORRECT_L,
          box_size = 40,
          border = 0,
      )
      qr.add_data(path)
      qr.make(fit=True)
      img = qr.make_image(fill_color='black', back_color='white')
      qrpath = 'myQr.png'
      img.save(qrpath)
      image(qrpath, (0, 0))
      

      Thank you!!!

      posted in General Discussion
      eduairet
      eduairet