From b4e614397f1df2680411d8c8b4b462a4f367d4ef Mon Sep 17 00:00:00 2001 From: Andy Maleh Date: Sun, 14 Nov 2021 18:28:28 -0500 Subject: [PATCH 1/4] Initially working Glimmer DSL with canvas element --- .gladiator | 31 ++++++++ pixelart/.gitignore | 6 +- .../dsl/pixelart/attribute_expression.rb | 17 ++++ pixelart/lib/glimmer/dsl/pixelart/dsl.rb | 16 ++++ .../dsl/pixelart/element_expression.rb | 28 +++++++ pixelart/lib/glimmer/pixelart/element.rb | 46 +++++++++++ .../lib/glimmer/pixelart/element/canvas.rb | 46 +++++++++++ pixelart/lib/pixelart/glimmer.rb | 3 + pixelart/sandbox/test_glimmer.rb | 78 +++++++++++++++++++ 9 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 .gladiator create mode 100644 pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb create mode 100644 pixelart/lib/glimmer/dsl/pixelart/dsl.rb create mode 100644 pixelart/lib/glimmer/dsl/pixelart/element_expression.rb create mode 100644 pixelart/lib/glimmer/pixelart/element.rb create mode 100644 pixelart/lib/glimmer/pixelart/element/canvas.rb create mode 100644 pixelart/lib/pixelart/glimmer.rb create mode 100644 pixelart/sandbox/test_glimmer.rb diff --git a/.gladiator b/.gladiator new file mode 100644 index 0000000..8ff2e79 --- /dev/null +++ b/.gladiator @@ -0,0 +1,31 @@ +--- +:selected_child_path: "/Users/andymaleh/code/pixel/pixelart/sandbox/test_glimmer.rb" +:split_orientation: horizontal +:caret_position: 1091 +:top_pixel: 949 +:shell_width: 1280 +:shell_height: 732 +:shell_x: 0 +:shell_y: 23 +:open_file_paths1: +- "/Users/andymaleh/code/pixel/pixelart/sandbox/test_vector.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/pixelart/vector.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/dsl/pixelart/dsl.rb" +- "/Users/andymaleh/code/pixel/pixelart/sandbox/test_glimmer.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/pixelart/glimmer.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/dsl/pixelart/element_expression.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/pixelart/element.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/pixelart/element/canvas.rb" +- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb" +:open_file_paths2: [] +:ignore_paths: +- ".gladiator" +- ".gladiator-scratchpad" +- ".git" +- coverage +- packages +- node_modules +- tmp +- vendor +- pkg +- dist diff --git a/pixelart/.gitignore b/pixelart/.gitignore index 38b7fd8..462488c 100644 --- a/pixelart/.gitignore +++ b/pixelart/.gitignore @@ -28,9 +28,11 @@ build/ # for a library or gem, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # Gemfile.lock -# .ruby-version -# .ruby-gemset +.ruby-version +.ruby-gemset # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: .rvmrc +# Gladiator (Glimmer Editor) +.gladiator diff --git a/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb b/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb new file mode 100644 index 0000000..5592a33 --- /dev/null +++ b/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb @@ -0,0 +1,17 @@ +require 'glimmer/dsl/expression' + +module Glimmer + module DSL + module Pixelart + class AttributeExpression < Expression + def can_interpret?(parent, keyword, *args, &block) + parent.respond_to?("#{keyword}=") && !args.empty? && block.nil? + end + + def interpret(parent, keyword, *args, &block) + parent.send(keyword, *args) + end + end + end + end +end diff --git a/pixelart/lib/glimmer/dsl/pixelart/dsl.rb b/pixelart/lib/glimmer/dsl/pixelart/dsl.rb new file mode 100644 index 0000000..22817d1 --- /dev/null +++ b/pixelart/lib/glimmer/dsl/pixelart/dsl.rb @@ -0,0 +1,16 @@ +require 'glimmer/dsl/engine' +Dir[File.expand_path('*_expression.rb', __dir__)].each {|f| require f} + +module Glimmer + module DSL + module Pixelart + Engine.add_dynamic_expressions( + Pixelart, + %w[ + attribute + element + ] + ) + end + end +end diff --git a/pixelart/lib/glimmer/dsl/pixelart/element_expression.rb b/pixelart/lib/glimmer/dsl/pixelart/element_expression.rb new file mode 100644 index 0000000..99cc3a1 --- /dev/null +++ b/pixelart/lib/glimmer/dsl/pixelart/element_expression.rb @@ -0,0 +1,28 @@ +require 'glimmer/dsl/expression' +require 'glimmer/dsl/parent_expression' +require 'glimmer/dsl/top_level_expression' +require_relative '../../pixelart/element' + +module Glimmer + module DSL + module Pixelart + class ElementExpression < Expression + include ParentExpression + include TopLevelExpression + + def can_interpret?(parent, keyword, *args, &block) + Glimmer::Pixelart::Element.element_exist?(keyword) + end + + def interpret(parent, keyword, *args, &block) + Glimmer::Pixelart::Element.element_class(keyword).new(parent, keyword, *args, &block) + end + + def add_content(element, keyword, *args, &block) + super + element.post_add_content + end + end + end + end +end diff --git a/pixelart/lib/glimmer/pixelart/element.rb b/pixelart/lib/glimmer/pixelart/element.rb new file mode 100644 index 0000000..9bc0409 --- /dev/null +++ b/pixelart/lib/glimmer/pixelart/element.rb @@ -0,0 +1,46 @@ +require 'facets/string/camelcase' + +module Glimmer + module Pixelart + class Element + class << self + def element_exist?(keyword) + constants.include?(element_class_name(keyword)) && element_class(keyword).respond_to?(:new) + end + + def element_class(keyword) + const_get(element_class_name(keyword)) + end + + def element_class_name(keyword) + keyword.to_s.camelcase(:upper).to_sym + end + end + + def initialize(parent, keyword, *args, &block) + @parent = parent + @keyword = keyword + @args = args + @block = block + @children = [] + @parent&.post_initialize_child(self) + post_add_content if @block.nil? + end + + def build + # No Op (subclasses may override to do something at the closing of the element) + end + + def post_initialize_child(child) + @children << child + end + + # subclasses may optionally override and call super + def post_add_content + build + end + end + end +end + +Dir[File.expand_path('./element/*.rb', __dir__)].each {|f| require f} diff --git a/pixelart/lib/glimmer/pixelart/element/canvas.rb b/pixelart/lib/glimmer/pixelart/element/canvas.rb new file mode 100644 index 0000000..4ceee51 --- /dev/null +++ b/pixelart/lib/glimmer/pixelart/element/canvas.rb @@ -0,0 +1,46 @@ +require 'pixelart/base' + +module Glimmer + module Pixelart + class Element + class Canvas < Element + attr_reader :vector + attr_accessor :file, :zoom + + def width + @args[0] + end + + def height + @args[1] + end + + def width=(new_width) + @args[0] = new_width + end + + def height=(new_height) + @args[1] = new_height + end + + def build + @vector = ::PixelArt::Vector.new(*@args) + @vector.zoom(@zoom) if @zoom + @vector.save(@file) if @file + end + + def respond_to?(method_name, include_private = false) + super || @vector.respond_to?(method_name, include_private) + end + + def method_missing(method_name, *args, &block) + if @vector.respond_to?(method_name, include_private) + @vector.send(method_name, *args, &block) + else + super + end + end + end + end + end +end diff --git a/pixelart/lib/pixelart/glimmer.rb b/pixelart/lib/pixelart/glimmer.rb new file mode 100644 index 0000000..66e7335 --- /dev/null +++ b/pixelart/lib/pixelart/glimmer.rb @@ -0,0 +1,3 @@ +require 'glimmer' + +require_relative '../glimmer/dsl/pixelart/dsl' diff --git a/pixelart/sandbox/test_glimmer.rb b/pixelart/sandbox/test_glimmer.rb new file mode 100644 index 0000000..bc214de --- /dev/null +++ b/pixelart/sandbox/test_glimmer.rb @@ -0,0 +1,78 @@ +### +# to run use +# ruby -I ./lib sandbox/test_vector.rb + + +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + +require 'pixelart/glimmer' + + +include Glimmer # activates Glimmer DSL for Pixelart (in real apps, mix into a class instead) + +def face + line { + coordinates 6, 23, 6, 14, + 5, 14, 5, 13, 4, 12, + 5, 11, 6, 11, 6, 7, 7, 6, 8, 5, + 14, 5, 15, 6, + 16, 7, 16, 19, 15, 20, 14, 21, 10, 21, 10, 23 + fill '#c8fbfb' + stroke 'black' + } +end + +def mouth + line( 10, 18, 14, 18 ) { + stroke 'black' + } +end + +def nose + line( 12, 16, 12, 14 ) { + stroke '#9be0e0' + } +end + +def eyes + path { + line( 9, 13, 9, 12 ) + line( 10, 12, 10, 11 ) + line( 14, 13, 14, 12 ) + line( 15, 12, 15, 11 ) + + stroke 'black' + } + + path { + line( 10, 13, 10, 12 ) + line( 15, 13, 15, 12 ) + + stroke '#9be0e0' + } + + line( 9, 12, 9, 11 ) { + stroke '#75bdbd' + } +end + +def headband + line( 7, 8, 15, 8 ) { + stroke '#1a6ed5' + } + + line( 7, 7, 15, 7 ) { + stroke 'white' + } +end + +canvas(24, 24) { +# file './tmp/punk3100.svg' +# zoom 4 # zoom automatically multiplies canvas dimensions (no need to multiply manually) +# +# face +# mouth +# nose +# eyes +# headband +} From 0960631b719c8697b59e298e3767f1c5cb03158a Mon Sep 17 00:00:00 2001 From: Andy Maleh Date: Sun, 14 Nov 2021 18:55:10 -0500 Subject: [PATCH 2/4] Support line in Glimmer DSL --- .gitignore | 2 ++ .gladiator | 31 ------------------- .../dsl/pixelart/attribute_expression.rb | 2 +- pixelart/lib/glimmer/pixelart/element.rb | 6 ++-- .../lib/glimmer/pixelart/element/canvas.rb | 14 ++++++--- pixelart/lib/glimmer/pixelart/element/line.rb | 22 +++++++++++++ pixelart/sandbox/test_glimmer.rb | 13 ++++---- pixelart/sandbox/test_vector.rb | 4 +-- 8 files changed, 45 insertions(+), 49 deletions(-) create mode 100644 .gitignore delete mode 100644 .gladiator create mode 100644 pixelart/lib/glimmer/pixelart/element/line.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d84a725 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Gladiator (Glimmer Editor) +.gladiator diff --git a/.gladiator b/.gladiator deleted file mode 100644 index 8ff2e79..0000000 --- a/.gladiator +++ /dev/null @@ -1,31 +0,0 @@ ---- -:selected_child_path: "/Users/andymaleh/code/pixel/pixelart/sandbox/test_glimmer.rb" -:split_orientation: horizontal -:caret_position: 1091 -:top_pixel: 949 -:shell_width: 1280 -:shell_height: 732 -:shell_x: 0 -:shell_y: 23 -:open_file_paths1: -- "/Users/andymaleh/code/pixel/pixelart/sandbox/test_vector.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/pixelart/vector.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/dsl/pixelart/dsl.rb" -- "/Users/andymaleh/code/pixel/pixelart/sandbox/test_glimmer.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/pixelart/glimmer.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/dsl/pixelart/element_expression.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/pixelart/element.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/pixelart/element/canvas.rb" -- "/Users/andymaleh/code/pixel/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb" -:open_file_paths2: [] -:ignore_paths: -- ".gladiator" -- ".gladiator-scratchpad" -- ".git" -- coverage -- packages -- node_modules -- tmp -- vendor -- pkg -- dist diff --git a/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb b/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb index 5592a33..6674b55 100644 --- a/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb +++ b/pixelart/lib/glimmer/dsl/pixelart/attribute_expression.rb @@ -9,7 +9,7 @@ def can_interpret?(parent, keyword, *args, &block) end def interpret(parent, keyword, *args, &block) - parent.send(keyword, *args) + parent.send("#{keyword}=", *args) end end end diff --git a/pixelart/lib/glimmer/pixelart/element.rb b/pixelart/lib/glimmer/pixelart/element.rb index 9bc0409..5574b0c 100644 --- a/pixelart/lib/glimmer/pixelart/element.rb +++ b/pixelart/lib/glimmer/pixelart/element.rb @@ -27,17 +27,17 @@ def initialize(parent, keyword, *args, &block) post_add_content if @block.nil? end + # Subclasses may optionally override and call super to have children built def build - # No Op (subclasses may override to do something at the closing of the element) + @children&.each(&:build) end def post_initialize_child(child) @children << child end - # subclasses may optionally override and call super def post_add_content - build + # No Op (subclasses may override to do something at the closing of the element) end end end diff --git a/pixelart/lib/glimmer/pixelart/element/canvas.rb b/pixelart/lib/glimmer/pixelart/element/canvas.rb index 4ceee51..759794e 100644 --- a/pixelart/lib/glimmer/pixelart/element/canvas.rb +++ b/pixelart/lib/glimmer/pixelart/element/canvas.rb @@ -22,20 +22,24 @@ def width=(new_width) def height=(new_height) @args[1] = new_height end + + def post_add_content + build + end def build @vector = ::PixelArt::Vector.new(*@args) - @vector.zoom(@zoom) if @zoom + super @vector.save(@file) if @file end - def respond_to?(method_name, include_private = false) + def respond_to?(method_name, include_private = true) super || @vector.respond_to?(method_name, include_private) end - def method_missing(method_name, *args, &block) - if @vector.respond_to?(method_name, include_private) - @vector.send(method_name, *args, &block) + def method_missing(method_name, *args, **kwargs, &block) + if @vector.respond_to?(method_name, true) + @vector.send(method_name, *args, **kwargs, &block) else super end diff --git a/pixelart/lib/glimmer/pixelart/element/line.rb b/pixelart/lib/glimmer/pixelart/element/line.rb new file mode 100644 index 0000000..4ebf53c --- /dev/null +++ b/pixelart/lib/glimmer/pixelart/element/line.rb @@ -0,0 +1,22 @@ +module Glimmer + module Pixelart + class Element + class Line < Element + attr_accessor :fill, :stroke + + def coordinates + @args + end + + def coordinates=(*new_coordinates) + new_coordinates = new_coordinates.first if new_coordinates.size == 1 && new_coordinates.first.is_a?(Array) + @args = *new_coordinates + end + + def build + @parent.path(stroke: @stroke, fill: @fill).line(*coordinates) + end + end + end + end +end diff --git a/pixelart/sandbox/test_glimmer.rb b/pixelart/sandbox/test_glimmer.rb index bc214de..6c940a5 100644 --- a/pixelart/sandbox/test_glimmer.rb +++ b/pixelart/sandbox/test_glimmer.rb @@ -67,12 +67,11 @@ def headband end canvas(24, 24) { -# file './tmp/punk3100.svg' -# zoom 4 # zoom automatically multiplies canvas dimensions (no need to multiply manually) -# -# face -# mouth -# nose + file './tmp/punk3100.svg' + + face + mouth + nose # eyes # headband -} +}.zoom diff --git a/pixelart/sandbox/test_vector.rb b/pixelart/sandbox/test_vector.rb index 5e56b59..59440a9 100644 --- a/pixelart/sandbox/test_vector.rb +++ b/pixelart/sandbox/test_vector.rb @@ -3,6 +3,8 @@ # ruby -I ./lib sandbox/test_vector.rb +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + require 'pixelart/base' @@ -38,5 +40,3 @@ canvas.save( "./tmp/punk3100.svg" ) - - From 6af28561bcdb8b72aa87a23449a34f576d021d1e Mon Sep 17 00:00:00 2001 From: Andy Maleh Date: Sun, 14 Nov 2021 19:10:04 -0500 Subject: [PATCH 3/4] Support path and circle in Glimmer DSL --- pixelart/lib/glimmer/pixelart/element.rb | 2 + .../lib/glimmer/pixelart/element/circle.rb | 43 +++++++++++++++++++ pixelart/lib/glimmer/pixelart/element/line.rb | 7 ++- pixelart/lib/glimmer/pixelart/element/path.rb | 9 ++++ pixelart/sandbox/test_glimmer.rb | 13 ++++-- 5 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 pixelart/lib/glimmer/pixelart/element/circle.rb create mode 100644 pixelart/lib/glimmer/pixelart/element/path.rb diff --git a/pixelart/lib/glimmer/pixelart/element.rb b/pixelart/lib/glimmer/pixelart/element.rb index 5574b0c..c968a8b 100644 --- a/pixelart/lib/glimmer/pixelart/element.rb +++ b/pixelart/lib/glimmer/pixelart/element.rb @@ -16,6 +16,8 @@ def element_class_name(keyword) keyword.to_s.camelcase(:upper).to_sym end end + + attr_reader :parent, :keyword, :args, :block def initialize(parent, keyword, *args, &block) @parent = parent diff --git a/pixelart/lib/glimmer/pixelart/element/circle.rb b/pixelart/lib/glimmer/pixelart/element/circle.rb new file mode 100644 index 0000000..5d383f6 --- /dev/null +++ b/pixelart/lib/glimmer/pixelart/element/circle.rb @@ -0,0 +1,43 @@ +module Glimmer + module Pixelart + class Element + class Circle < Element + attr_accessor :fill + + def cx + @args[0] + end + alias center_x cx + + def cy + @args[1] + end + alias center_y cy + + def r + @args[2] + end + alias radius r + + def cx=(new_cx) + @args[0] = new_cx + end + alias center_x cx + + def cy=(new_cy) + @args[1] = new_cy + end + alias center_y cy + + def r=(new_r) + @args[2] = new_r + end + alias radius r + + def build + @parent.circle(cx: cx, cy: cy, r: r, fill: @fill) + end + end + end + end +end diff --git a/pixelart/lib/glimmer/pixelart/element/line.rb b/pixelart/lib/glimmer/pixelart/element/line.rb index 4ebf53c..e6aa734 100644 --- a/pixelart/lib/glimmer/pixelart/element/line.rb +++ b/pixelart/lib/glimmer/pixelart/element/line.rb @@ -14,7 +14,12 @@ def coordinates=(*new_coordinates) end def build - @parent.path(stroke: @stroke, fill: @fill).line(*coordinates) + case @parent + when Glimmer::Pixelart::Element::Canvas + @parent.path(stroke: @stroke, fill: @fill).line(*coordinates) + when Glimmer::Pixelart::Element::Path + @parent.parent.path(stroke: @parent.stroke, fill: @parent.fill).line(*coordinates) + end end end end diff --git a/pixelart/lib/glimmer/pixelart/element/path.rb b/pixelart/lib/glimmer/pixelart/element/path.rb new file mode 100644 index 0000000..f90d99b --- /dev/null +++ b/pixelart/lib/glimmer/pixelart/element/path.rb @@ -0,0 +1,9 @@ +module Glimmer + module Pixelart + class Element + class Path < Element + attr_accessor :fill, :stroke + end + end + end +end diff --git a/pixelart/sandbox/test_glimmer.rb b/pixelart/sandbox/test_glimmer.rb index 6c940a5..21cd1ef 100644 --- a/pixelart/sandbox/test_glimmer.rb +++ b/pixelart/sandbox/test_glimmer.rb @@ -32,6 +32,10 @@ def nose line( 12, 16, 12, 14 ) { stroke '#9be0e0' } + # You may enable circle as an alternative nose and disable line above + # circle( 12, 15, 1 ) { + # fill '#9be0e0' + # } end def eyes @@ -51,7 +55,10 @@ def eyes stroke '#9be0e0' } - line( 9, 12, 9, 11 ) { + path { + line( 9, 12, 9, 11 ) + line( 14, 12, 14, 11 ) + stroke '#75bdbd' } end @@ -72,6 +79,6 @@ def headband face mouth nose -# eyes -# headband + eyes + headband }.zoom From 7cedf0d4a93d56b27ea1743da4e8b2fbc5b5bf84 Mon Sep 17 00:00:00 2001 From: Andy Maleh Date: Sun, 14 Nov 2021 19:18:15 -0500 Subject: [PATCH 4/4] Document Glimmer DSL for Pixelart + some fixes --- .gitignore | 1 + pixelart/.gitignore | 1 + pixelart/README.md | 143 +++++++++++++++++- pixelart/i/punk3100-round-nose.svg | 16 ++ pixelart/i/punk3100.svg | 15 ++ pixelart/lib/glimmer/pixelart/element.rb | 5 + .../lib/glimmer/pixelart/element/canvas.rb | 2 +- pixelart/sandbox/test_glimmer.rb | 22 +-- pixelart/sandbox/test_vector.rb | 2 - 9 files changed, 194 insertions(+), 13 deletions(-) create mode 100644 pixelart/i/punk3100-round-nose.svg create mode 100644 pixelart/i/punk3100.svg diff --git a/.gitignore b/.gitignore index d84a725..87237d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # Gladiator (Glimmer Editor) .gladiator +.DS_Store diff --git a/pixelart/.gitignore b/pixelart/.gitignore index 462488c..0d3f038 100644 --- a/pixelart/.gitignore +++ b/pixelart/.gitignore @@ -36,3 +36,4 @@ build/ # Gladiator (Glimmer Editor) .gladiator +.DS_Store diff --git a/pixelart/README.md b/pixelart/README.md index 96fb4d0..4c4c092 100644 --- a/pixelart/README.md +++ b/pixelart/README.md @@ -277,6 +277,148 @@ require 'pixelart/base' +## Canvas Vector Graphics + +You may utilize inline-DSL (Domain Specific Language) syntax for building vector graphics via a canvas `PixelArt::Vector` object: + +```ruby +require 'pixelart/base' + + +canvas = PixelArt::Vector.new( 24, 24 ) + +## face +canvas.path( stroke: 'black', fill: '#c8fbfb' ).line( + 6, 23, 6, 14, + 5, 14, 5, 13, 4, 12, + 5, 11, 6, 11, 6, 7, 7, 6, 8, 5, + 14, 5, 15, 6, + 16, 7, 16, 19, 15, 20, 14, 21, 10, 21, 10, 23 ) + +## mouth +canvas.path( stroke: 'black' ).line( 10, 18, 14, 18 ) +## nose +canvas.path( stroke: '#9be0e0' ).line( 12, 16, 12, 14 ) + + +## eyes +canvas.path( stroke: 'black' ).line( 9, 13, 9, 12 ) + .line( 10, 12, 10, 11 ) + .line( 14, 13, 14, 12 ) + .line( 15, 12, 15, 11 ) +canvas.path( stroke: '#9be0e0' ).line( 10, 13, 10, 12 ) + .line( 15, 13, 15, 12 ) +canvas.path( stroke: '#75bdbd' ).line( 9, 12, 9, 11 ) + .line( 14, 12, 14, 11 ) + +## headband +canvas.path( stroke: '#1a6ed5' ).line( 7, 8, 15, 8 ) +canvas.path( stroke: 'white' ).line( 7, 7, 15, 7 ) + + +canvas.save( "./tmp/punk3100.svg" ) +``` + +Voila! + + + +## Modular "Glimmer" Version + +You may utilize a [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Pixelart vector graphics by requiring `'pixelart/glimmer'` and including `Glimmer` module: + +```ruby +require 'pixelart/glimmer' +include Glimmer # activates Glimmer DSL for Pixelart (in real apps, mix into a class instead) +``` + +Afterwards, you may build canvas vector graphics declaratively and hierarchically: + +```ruby +def face + line { + coordinates 6, 23, 6, 14, + 5, 14, 5, 13, 4, 12, + 5, 11, 6, 11, 6, 7, 7, 6, 8, 5, + 14, 5, 15, 6, + 16, 7, 16, 19, 15, 20, 14, 21, 10, 21, 10, 23 + fill '#c8fbfb' + stroke 'black' + } +end + +def mouth + line( 10, 18, 14, 18 ) { + stroke 'black' + } +end + +def nose + line( 12, 16, 12, 14 ) { + stroke '#9be0e0' + } +end + +def eyes + path { + line( 9, 13, 9, 12 ) + line( 10, 12, 10, 11 ) + line( 14, 13, 14, 12 ) + line( 15, 12, 15, 11 ) + + stroke 'black' + } + + path { + line( 10, 13, 10, 12 ) + line( 15, 13, 15, 12 ) + + stroke '#9be0e0' + } + + path { + line( 9, 12, 9, 11 ) + line( 14, 12, 14, 11 ) + + stroke '#75bdbd' + } +end + +def headband + line( 7, 8, 15, 8 ) { + stroke '#1a6ed5' + } + + line( 7, 7, 15, 7 ) { + stroke 'white' + } +end + +image = canvas(24, 24) { + file './tmp/punk3100.svg' # auto-saves file when canvas expression closes + + face + mouth + nose + eyes + headband +} + +# Re-open content to modify attributes and add more shapes +image.content { + file './tmp/punk3100-round-nose.svg' # auto-saves file when content closes + + ## Round Nose + circle( 12, 15, 1 ) { + fill '#9be0e0' + } +} +``` + +Voila! + + + ## Install Just install the gem: @@ -288,4 +430,3 @@ Just install the gem: The scripts are dedicated to the public domain. Use it as you please with no restrictions whatsoever. - diff --git a/pixelart/i/punk3100-round-nose.svg b/pixelart/i/punk3100-round-nose.svg new file mode 100644 index 0000000..f1db205 --- /dev/null +++ b/pixelart/i/punk3100-round-nose.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pixelart/i/punk3100.svg b/pixelart/i/punk3100.svg new file mode 100644 index 0000000..6356c83 --- /dev/null +++ b/pixelart/i/punk3100.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pixelart/lib/glimmer/pixelart/element.rb b/pixelart/lib/glimmer/pixelart/element.rb index c968a8b..50c1645 100644 --- a/pixelart/lib/glimmer/pixelart/element.rb +++ b/pixelart/lib/glimmer/pixelart/element.rb @@ -41,6 +41,11 @@ def post_initialize_child(child) def post_add_content # No Op (subclasses may override to do something at the closing of the element) end + + # Enables re-opening content and adding new shapes + def content(&block) + Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Pixelart::ElementExpression.new, @keyword, &block) + end end end end diff --git a/pixelart/lib/glimmer/pixelart/element/canvas.rb b/pixelart/lib/glimmer/pixelart/element/canvas.rb index 759794e..e45e027 100644 --- a/pixelart/lib/glimmer/pixelart/element/canvas.rb +++ b/pixelart/lib/glimmer/pixelart/element/canvas.rb @@ -5,7 +5,7 @@ module Pixelart class Element class Canvas < Element attr_reader :vector - attr_accessor :file, :zoom + attr_accessor :file def width @args[0] diff --git a/pixelart/sandbox/test_glimmer.rb b/pixelart/sandbox/test_glimmer.rb index 21cd1ef..bd545fb 100644 --- a/pixelart/sandbox/test_glimmer.rb +++ b/pixelart/sandbox/test_glimmer.rb @@ -3,8 +3,6 @@ # ruby -I ./lib sandbox/test_vector.rb -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - require 'pixelart/glimmer' @@ -32,10 +30,6 @@ def nose line( 12, 16, 12, 14 ) { stroke '#9be0e0' } - # You may enable circle as an alternative nose and disable line above - # circle( 12, 15, 1 ) { - # fill '#9be0e0' - # } end def eyes @@ -73,12 +67,22 @@ def headband } end -canvas(24, 24) { - file './tmp/punk3100.svg' +image = canvas(24, 24) { + file './tmp/punk3100.svg' # auto-saves file when canvas expression closes face mouth nose eyes headband -}.zoom +} + +# Re-open content to modify attributes and add more shapes +image.content { + file './tmp/punk3100-round-nose.svg' # auto-saves file when content closes + + ## Round Nose + circle( 12, 15, 1 ) { + fill '#9be0e0' + } +} diff --git a/pixelart/sandbox/test_vector.rb b/pixelart/sandbox/test_vector.rb index 59440a9..88cbae6 100644 --- a/pixelart/sandbox/test_vector.rb +++ b/pixelart/sandbox/test_vector.rb @@ -3,8 +3,6 @@ # ruby -I ./lib sandbox/test_vector.rb -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - require 'pixelart/base'