[開発ログ] ASR でプリミティブの描画テスト
2D プリミティブ(文字、画像、長方形)は表示出来た。
現状で Tk よりよいと思う点は
- 画像の拡大縮小表示ができる
- アニメーションに GIF アニメが使える
- HTML なので馴染みやすい
- IE の安定感
- HTML なのでフラッシュムービーとか音も簡単に組み込めそう
- 最終的に JavaScript に移植すれば非常に多くの環境で動く
あたりだろうか。デメリットとしては Tk は多角形(ポリゴン)が表示できたが HTML ではできなそう。
上記 2 つが嬉しくて、これができるとドラクエ 7 のような 3D っぽいキャラクタ表示が可能。
この手の実験的なコードを日記に張っておくと後にたいへん役立つので実験用スクリプトを張っておく。 Prim のインターフェースはまだまだいい加減。
test.hta
<html>
<head>
<HTA:APPLICATION ID="ERProt"
ApplicationName="ERProtOnASR"
/>
<script language="RubyScript">
$KCODE = "SJIS"
require 'main.rb'
</script>
</head>
<body onload="init" language="RubyScript">
<div id="top_div"></div>
</body>
</html>
main.rb
require 'er.rb'
def main_loop
@counter += 1
@font.elm.style.top = @counter * 4 % 480
end
def init
@screen = init_window(640, 480, '#ccccff')
@counter = 0
@cwin = @screen.create_prim Box, :box01, 0,@screen.h-100,0, @screen.w-16, 100-16, '#ffcccc'
@cwin.margin = "8 8"
@cwin.padding = "8 8"
@cwin.onmouseover = "__self__.test00"
@cwin.create_prim Font, :id00, 0,0,0, 16, 'ABC'*20
@font = Font.new :id01, 100,120,0, 16, 'ABC'
@screen.add_prim @font
@font.create_prim Font, :id02, 100,140,0, 16, 'ABC'
@screen.create_prim Image, :image00, 140,100,0, 'i_31.gif'
start_window(50, :main_loop)if @window
end
if $0 == __FILE__
init
puts @screen.html
end
er.rb
class Prim
attr_accessor :id, :str, :src
attr_accessor :margin, :padding, :bgcolor
attr_accessor :position_type, :x, :y, :z, :w, :h, :size
attr_accessor :onmouseover
@@prims = {}
@@window = nil
def self.find(id)
@@prims[id]
end
def self.window=(win)
@@window = win
end
def initialize *arg
@prims = []
@html_tag = 'div'
@position_type = 'absolute'
([:id] + initialize_params).each do |meth|
break unless v = arg.shift
__send__ "#{meth}=", v
end
raise unless id.is_a? Symbol
raise id.inspect if @@prims[id]
@@prims[id] = self
end
def initialize_params
[:x, :y, :z, :size, :str]
end
def create_prim klass, *arg
@prims << klass.new(*arg)
@prims.last
end
def add_prim prim
@prims << prim
end
def inside_of_html
str
end
def style_params
params = []
{
:margin => 'margin',
:padding => 'padding',
:position_type => 'position',
:y => 'top',
:x => 'left',
:w => 'width',
:h => 'height',
:bgcolor => 'background-color',
}.each do |k, v|
if __send__ k
params << "#{v}:#{__send__ k}; "
end
end
params
end
def events
params = []
{
:onmouseover => 'onmouseover',
#:setInterval => 'setInterval',
}.each do |k, v|
value = __send__ k
if value
params << %Q|#{v}="#{value.gsub('__self__', "Prim.find(:#{id})")}" |
end
end
params
end
def html
%Q|<#{@html_tag} id="#{id}" language="RubyScript" #{events.join}style="#{style_params.join}">\n#{inside_of_html}#{children_html}</#{@html_tag}>|
end
def children_html
@prims.map{|prim| prim.html}.join("\n")
end
def elm
@elm ||= @@window.__send__ id
end
def test00
elm.style.width = "200"
elm.style.backgroundColor = "#FF0000"
end
end
class Font < Prim
end
class Box < Prim
def initialize_params
[:x, :y, :z, :w, :h, :bgcolor]
end
end
class Image < Prim
def initialize_params
[:x, :y, :z, :src]
end
def inside_of_html
%Q|<img src="#{src}">|
end
end
def init_window(w, h, bgcolor)
if @window
Prim.window = @window
@top_div = @window.top_div
@window.resizeTo w+40, h+40
end
Box.new :__screen__, 0,0,0, w,h, bgcolor
end
def start_window(interval, func)
@top_div.innerHTML = @screen.html
@timer = @window.setInterval func.to_s, interval, "RubyScript"
end