aboutsummaryrefslogtreecommitdiff
path: root/bin/logo-0/gen-logo.rb
diff options
context:
space:
mode:
Diffstat (limited to 'bin/logo-0/gen-logo.rb')
-rwxr-xr-xbin/logo-0/gen-logo.rb181
1 files changed, 181 insertions, 0 deletions
diff --git a/bin/logo-0/gen-logo.rb b/bin/logo-0/gen-logo.rb
new file mode 100755
index 0000000..7dcffef
--- /dev/null
+++ b/bin/logo-0/gen-logo.rb
@@ -0,0 +1,181 @@
+#!/usr/bin/env ruby
+
+#
+# gen-logo.rb: generate svg logo
+#
+#
+# notes:
+# * used #4e86b1 as base color
+# * used color wheel to generate complimentary colors:
+# https://www.sessions.edu/color-calculator/
+#
+
+require 'luigi-template'
+
+CONFIG = {
+ # svg dimensions
+ # FIXME: these aren't working
+ svg_width: 108,
+ svg_height: 90,
+
+ # show background?
+ bg: false,
+
+ # animation duration, in seconds
+ duration: 20,
+
+ # animation delay coefficients
+ # delay = (y - 1) * YC + (x - 1) * XC
+ delay_coefficients: {
+ y: 1.0,
+ x: 0.2,
+ },
+
+ # animation color keyframes
+ colors: [
+ { c: '#ffffff', t: 0 },
+ { c: '#4e86b1', t: 0.333 },
+ { c: '#4eb179', t: 0.666 },
+ { c: '#ffffff', t: 1 },
+ ],
+
+ # dot sizes
+ dot_width: 12,
+ dot_height: 10,
+
+ # square coordinates
+ dots: [
+ # P (0)
+ { x: 1, y: 1 },
+ { x: 1, y: 2 },
+ { x: 1, y: 3 },
+ { x: 1, y: 4 },
+ { x: 1, y: 5 },
+ { x: 1, y: 5 },
+
+ # P (1)
+ { x: 2, y: 1 },
+ { x: 2, y: 3 },
+
+ # P (2)
+ { x: 3, y: 1 },
+ { x: 3, y: 2 },
+ { x: 3, y: 3 },
+
+ # T (0)
+ { x: 5, y: 1 },
+
+ # T (1)
+ { x: 6, y: 1 },
+ { x: 6, y: 2 },
+ { x: 6, y: 3 },
+ { x: 6, y: 4 },
+ { x: 6, y: 5 },
+
+ # T (2)
+ { x: 7, y: 1 },
+
+ # _ (0-7)
+ { x: 1, y: 7 },
+ { x: 2, y: 7 },
+ { x: 3, y: 7 },
+ { x: 4, y: 7 },
+ { x: 5, y: 7 },
+ { x: 6, y: 7 },
+ { x: 7, y: 7 },
+ ],
+}
+
+# build template cache
+TEMPLATES = Luigi::Cache.new({
+ svg: %{
+ <?xml version="1.0"?>
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ viewBox="0 0 %{width} %{height}"
+ >
+ %{bg}
+
+ <g fill='white' stroke='black'>
+ %{dots}
+ </g>
+ </svg>
+ },
+
+ bg: %{
+ <rect x='0' y='0' width='100%' height='100%' fill='black'/>
+ },
+
+ dot: %{
+ <rect x='%{x}' y='%{y}' width='%{width}' height='%{height}'>
+ <animate
+ dur='%{duration}s'
+ begin='%{begin}'
+ values='%{values}'
+ keyTimes='%{times}'
+ attributeName='fill'
+ repeatCount='indefinite'
+ />
+ </rect>
+ },
+}.reduce({}) do |r, row|
+ r[row[0]] = row[1].strip.gsub(/(?<!\?\>)\s+/, ' ')
+ r
+end)
+
+# keyframe color values
+VALUES = CONFIG[:colors].map { |row|
+ row[:c]
+}.join(';').freeze
+
+# keyframe times
+TIMES = CONFIG[:colors].map { |row|
+ ('%1.3f' % row[:t]).gsub(/0+$/, '').gsub(/\.$/, '')
+}.join(';').freeze
+
+# get delay coefficients
+YC = CONFIG[:delay_coefficients][:y]
+XC = CONFIG[:delay_coefficients][:x]
+
+# generate svg
+svg = TEMPLATES[:svg].run({
+ # svg dimensions
+ width: CONFIG[:svg_width],
+ height: CONFIG[:svg_height],
+
+ # background
+ bg: CONFIG[:bg] ? TEMPLATES[:bg].run({}) : '',
+
+ # dots
+ dots: CONFIG[:dots].map { |row|
+ y = row[:y] * CONFIG[:dot_height]
+ x = row[:x] * CONFIG[:dot_width]
+
+ # calculate animation delay
+ delay = (row[:y] - 1) * YC + (row[:x] - 1) * XC
+
+ TEMPLATES[:dot].run(row.merge({
+ x: x - 5,
+ y: y,
+ width: CONFIG[:dot_width],
+ height: CONFIG[:dot_height],
+
+ duration: CONFIG[:duration],
+ begin: '%1.1fs' % [delay],
+ values: VALUES,
+ times: TIMES,
+ }))
+ }.join,
+})
+
+# apply cleanups to svg, then write it to stdout
+puts([
+ [ /> +</, '><' ],
+ [ /\s+>/m, '>' ],
+ [ / +\/>/, '/>' ],
+ [ / +<svg/, '<svg' ],
+].reduce(svg) do |r, row|
+ # apply cleanup
+ r.gsub(row[0], row[1])
+end)