# Flexible code for colorful bubbles with randomized colors # Language: Simple Inkscape Scripting (SIS) # Details: https://inkscape.org/~pakin/%E2%98%85simple-inkscape-scripting # Github: https://github.com/spakin/SimpInkScr # bubblescript version 0.1 # # Copyright 2022 Joseph Smith # # Permission to use, copy, modify, and/or distribute this software for any purpose with or without # fee is hereby granted, provided that the above copyright notice and this permission notice # appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # ************************************************************************************************************ # User section # Entries below with a DEFAULT value can be commented out # If either of thse is not set, page dimensions of the document are used. Values may differ. #pagewidth = 1000 #pageheight = 1000 minbubblesize= 60 # DEFAULTS TO 40. maxbubblesize = 240 # DEFAULTS TO 200. bubblenum = 21 # DEFAULTS TO 10. #bubbleopacity = 0.3 # DEFAULTS TO 0.6. #bubblestrokewidth = 1 # DEFAULTS TO 0. #bubblestrokecolor = '0c0c0c' # DEFAULTS TO 'ffffff'. pageboundaries = 'yes' # DEFAULTS TO 'no'. pagemargin = 10 # DEFAULTS TO 10. #backgroundcolor = 000000 # DEFAULTS TO 'ffffff'. #bubbleshape = 'square' # DEFAULTS TO 'circle'. palette = 'yes' # DEFAULTS TO 'no'. load palette? requires a palette file. palettefile = '/home/nobody/palette.txt' # MUST BE SET with palette. # ************************************************************************************************************ # Code section if not 'minbubblesize' in globals(): minbubblesize = 40 if not 'maxbubblesize' in globals(): maxbubblesize = 200 if not 'bubblenum' in globals(): bubblenum = 10 if not 'bubbleopacity' in globals(): bubbleopacity = 0.6 if not 'bubblestrokewidth' in globals(): bubblestrokewidth = 0 if not 'bubblestrokecolor' in globals(): bubblestrokecolor = 'ffffff' if not 'pageboundaries' in globals(): pageboundaries = 'no' if not 'pagemargin' in globals(): pagemargin = 10 if not 'backgroundcolor' in globals(): backgroundcolor = 'ffffff' if not 'bubbleshape' in globals(): bubbleshape = 'circle' if not 'palette' in globals(): palette = 'no' # Set page dimensions if not set already. Doc: "SVG works in nominal "pixel" units." # TODO: FIX VIEWBOX/VIEWPORT ISSUES if ('pageheight' in globals()) and ('pagewidth' in globals()): svg_root.set('width', '%spx' % pagewidth) svg_root.set('height', '%spx' % pageheight) width, height = svg_root.width, svg_root.height svg_root.set('viewBox', '0 0 %.0f %.0f' % (width, height)) else: pagewidth = float(svg_root.get('width').rstrip('px')) pageheight = float(svg_root.get('height').rstrip('px')) # ************************************************************************************************************ # Function definitions def getrandposition(): if (pageboundaries == 'yes'): xmin = maxbubblesize / 2 + pagemargin ymin = maxbubblesize / 2 + pagemargin xmax = pagewidth - (maxbubblesize / 2) - pagemargin ymax = pageheight - (maxbubblesize / 2) - pagemargin else: xmin = 0 ymin = 0 xmax = pagewidth ymax = pageheight xpos = uniform(xmin, xmax) ypos = uniform(ymin, ymax) return (xpos, ypos) # function for creating a shape; default is square def makeshape(kind, xpos, ypos, size, sfill, swidth, objfill): if kind == 'bg': obj = rect((0,0 ), (size, size), stroke=sfill, stroke_width=swidth, fill=objfill) elif kind == 'square': obj = rect((xpos, ypos), (xpos + size, ypos + size), stroke=sfill, stroke_width=swidth, fill=objfill) else: radius = size / 2 obj = circle((xpos, ypos), radius, stroke=sfill, stroke_width=swidth, fill=objfill) return obj # Reads a palette file abd returns a list of RGB values and its length # File format: # <six-digit hex rgb><artbitrary text> # Example palette file contents: # # 04d9ff Neon Blue # ff9933 Neon Carrot # fe4164 Neon Fuchsia # # Function will TRY to read the first six characters of each line def getpalette(): rgbl = [] rgbm = 0 with open(palettefile, 'r') as fp: line = fp.readline() while line: line = line.rstrip() # parts = line.split() # line = parts[0] line = line[0:6] rgbl.append(line) line = fp.readline() fp.close() rgbm = len(rgbl) - 1 return(rgbl, rgbm) # Different ways for fetching a color, depending on config # With a matrix, cell colors are accessed by index (flat list) def getcolor(): if palette == 'yes': rgbindex = randrange(rgbmax) clr = '#%s' % rgblist[rgbindex] else: clr = '#%02x%02x%02x' % (randrange(256), randrange(256), randrange(256)) return clr # ************************************************************************************************************ # main code # Two layers: background), bubbles l1 = layer('Background') l2 = layer('Bubbles') # TODO: pageheight background = makeshape('bg', 0, 0, pagewidth, 0, 0, '#%s' % backgroundcolor) l1.add(background) if (palette == 'yes'): (rgblist, rgbmax) = getpalette() # Every single element is created and positioned individually, then added to its layer for i in range(bubblenum): # Create randomly positioned bubble (y, x) = getrandposition() bubblesize = uniform(minbubblesize, maxbubblesize) bubblecolor = getcolor() grad = linear_gradient((0, 0), (0, 0)) grad.add_stop(0, bubblecolor, bubbleopacity) bubble = makeshape(bubbleshape, x, y, bubblesize, bubblestrokecolor, bubblestrokewidth, grad) # ADDING TWO OPACITY BYTES DOESN'T SEEM TO WORK #bubble = makeshape(bubbleshape, x, y, bubblesize, bubblestrokecolor, bubblestrokewidth, '%scc' % bubblecolor) l2.add(bubble)