221 lines
4.6 KiB
Plaintext
221 lines
4.6 KiB
Plaintext
var math = use('math')
|
|
var color = use('color')
|
|
|
|
var draw = {}
|
|
draw[cell.DOC] = `
|
|
A collection of 2D drawing functions that create drawing command lists.
|
|
These are pure functions that return plain JavaScript objects representing
|
|
drawing operations. No rendering or actor communication happens here.
|
|
`
|
|
|
|
// Create a new command list
|
|
draw.list = function() {
|
|
var commands = []
|
|
|
|
return {
|
|
// Add a command to this list
|
|
push: function(cmd) {
|
|
commands.push(cmd)
|
|
},
|
|
|
|
// Get all commands
|
|
get: function() {
|
|
return commands
|
|
},
|
|
|
|
// Clear all commands
|
|
clear: function() {
|
|
commands = []
|
|
},
|
|
|
|
// Get command count
|
|
length: function() {
|
|
return commands.length
|
|
}
|
|
}
|
|
}
|
|
|
|
// Default command list for convenience
|
|
var current_list = draw.list()
|
|
|
|
// Set the current list
|
|
draw.set_list = function(list) {
|
|
current_list = list
|
|
}
|
|
|
|
// Get current list
|
|
draw.get_list = function() {
|
|
return current_list
|
|
}
|
|
|
|
// Clear current list
|
|
draw.clear = function() {
|
|
current_list.clear()
|
|
}
|
|
|
|
// Get commands from current list
|
|
draw.get_commands = function() {
|
|
return current_list.get()
|
|
}
|
|
|
|
// Helper to add a command
|
|
function add_command(type, data) {
|
|
var cmd = {cmd: type}
|
|
Object.assign(cmd, data)
|
|
current_list.push(cmd)
|
|
}
|
|
|
|
// Default geometry definitions
|
|
var ellipse_def = {
|
|
start: 0,
|
|
end: 1,
|
|
mode: 'fill',
|
|
thickness: 1,
|
|
}
|
|
|
|
var line_def = {
|
|
thickness: 1,
|
|
cap:"butt",
|
|
}
|
|
|
|
var rect_def = {
|
|
thickness:1,
|
|
radius: 0
|
|
}
|
|
|
|
var slice9_info = {
|
|
tile_top:true,
|
|
tile_bottom:true,
|
|
tile_left:true,
|
|
tile_right:true,
|
|
tile_center_x:true,
|
|
tile_center_right:true,
|
|
}
|
|
|
|
var image_info = {
|
|
tile_x: false,
|
|
tile_y: false,
|
|
flip_x: false,
|
|
flip_y: false,
|
|
mode: 'linear'
|
|
}
|
|
|
|
var circle_def = {
|
|
inner_radius:1, // percentage: 1 means filled circle
|
|
start:0,
|
|
end: 1,
|
|
}
|
|
|
|
// Drawing functions
|
|
draw.point = function(pos, size, opt = {}, material) {
|
|
add_command("draw_point", {
|
|
pos: pos,
|
|
size: size,
|
|
opt: opt,
|
|
material: material
|
|
})
|
|
}
|
|
draw.point[cell.DOC] = `
|
|
:param pos: A 2D position ([x, y]) where the point should be drawn.
|
|
:param size: The size of the point.
|
|
:param opt: Optional geometry properties.
|
|
:param material: Material/styling information (color, shaders, etc.)
|
|
:return: None
|
|
`
|
|
|
|
draw.ellipse = function(pos, radii, def, material) {
|
|
var opt = def ? {...ellipse_def, ...def} : ellipse_def
|
|
if (opt.thickness <= 0) opt.thickness = Math.max(radii[0], radii[1])
|
|
|
|
add_command("draw_ellipse", {
|
|
pos: pos,
|
|
radii: radii,
|
|
opt: opt,
|
|
material: material
|
|
})
|
|
}
|
|
|
|
draw.line = function(points, def, material)
|
|
{
|
|
var opt = def ? {...line_def, ...def} : line_def
|
|
|
|
add_command("draw_line", {
|
|
points: points,
|
|
opt: opt,
|
|
material: material
|
|
})
|
|
}
|
|
|
|
draw.cross = function render_cross(pos, size, def, material) {
|
|
var a = [pos.add([0, size]), pos.add([0, -size])]
|
|
var b = [pos.add([size, 0]), pos.add([-size, 0])]
|
|
draw.line(a, def, material)
|
|
draw.line(b, def, material)
|
|
}
|
|
|
|
draw.arrow = function render_arrow(start, end, wingspan = 4, wingangle = 10, def, material) {
|
|
var dir = math.norm(end.sub(start))
|
|
var wing1 = [math.rotate(dir, wingangle).scale(wingspan).add(end), end]
|
|
var wing2 = [math.rotate(dir, -wingangle).scale(wingspan).add(end), end]
|
|
draw.line([start, end], def, material)
|
|
draw.line(wing1, def, material)
|
|
draw.line(wing2, def, material)
|
|
}
|
|
|
|
draw.rectangle = function render_rectangle(rect, def, material) {
|
|
var opt = def ? {...rect_def, ...def} : rect_def
|
|
|
|
add_command("draw_rect", {
|
|
rect: rect,
|
|
opt: opt,
|
|
material: material
|
|
})
|
|
}
|
|
|
|
draw.slice9 = function slice9(image, rect = [0,0], slice = 0, info = slice9_info, material) {
|
|
if (!image) throw Error('Need an image to render.')
|
|
|
|
add_command("draw_slice9", {
|
|
image: image,
|
|
rect: rect,
|
|
slice: slice,
|
|
info: info,
|
|
material: material
|
|
})
|
|
}
|
|
|
|
draw.image = function image(image, rect, rotation = 0, anchor = [0,0], shear = [0,0], info = {}, material) {
|
|
if (!rect) throw Error('Need rectangle to render image.')
|
|
if (!image) throw Error('Need an image to render.')
|
|
|
|
if (!('x' in rect && 'y' in rect)) throw Error('Must provide X and Y for image.')
|
|
|
|
info = Object.assign({}, image_info, info);
|
|
|
|
add_command("draw_image", {
|
|
image: image,
|
|
rect: rect,
|
|
rotation: rotation,
|
|
anchor: anchor,
|
|
shear: shear,
|
|
info: info,
|
|
material: material
|
|
})
|
|
}
|
|
|
|
draw.circle = function render_circle(pos, radius, def, material) {
|
|
draw.ellipse(pos, [radius,radius], def, material)
|
|
}
|
|
|
|
draw.text = function text(text, pos, font = 'fonts/c64.ttf', size = 8, color = color.white, wrap = 0) {
|
|
add_command("draw_text", {
|
|
text,
|
|
pos,
|
|
font,
|
|
size,
|
|
wrap,
|
|
material: {color}
|
|
})
|
|
}
|
|
|
|
return draw |