#--------------------------------------------------------------------------- # # Title : Generic Canvas Instrument # # File Type : Implementation File # # Description : Provides the standard wiring to connect a surface to an SVG and allow animation # : This class should be subclassed for use; see canvas_altimeter.nas # # Author : Richard Harrison (richard@zaretto.com) # # Creation Date : 10 April 2016 # # Version : 1.0 # # Copyright (C) 2016 Richard Harrison Released under GPL V2 # #---------------------------------------------------------------------------*/ # # This is your bog standard don't do anything unless the value has changed more than a predetermined amount class. # - use to update animations on canvas elements # var PropertyUpdateManager = { new : func(_propname, _delta, _changed_method) { var obj = {parents : [PropertyUpdateManager] }; obj.propname = _propname; obj.delta = _delta; obj.curval = getprop(obj.propname); obj.lastval = obj.curval; obj.changed = _changed_method; obj.update = func { me.curval = getprop(me.propname); if (me.curval != nil) { if(me.lastval == nil or math.abs(me.lastval - me.curval) > me.delta) { me.lastval = me.curval; me.changed(me.curval); } } }; obj.update(); return obj; }, }; # # # Base class for canvas instruments; generally don't change this # var CanvasInstrument = { new : func (svgname, _item_name,tran_x,tran_y){ var canvas_item = "Canvas"~_item_name~"Face"; var obj = {parents : [CanvasInstrument] }; obj.canvas= canvas.new({ "name": _item_name, "size": [1024,1024], "view": [660,560], "mipmapping": 1 }); obj.canvas_name = canvas_item; obj.name = _item_name; obj.canvas.addPlacement({"node": canvas_item}); obj.update_rate_seconds = 0.001; # Create a group for the parsed elements obj.svg = obj.canvas.createGroup(); obj.svg.setTranslation (tran_x,tran_y); # Parse an SVG file and add the parsed elements to the given group var parse_result = canvas.parsesvg(obj.svg, svgname); # printf("%s: Parse SVG %d for surface %s",obj.name, parse_result, obj.canvas_name); obj.update_items = []; obj.UpdateTimer = maketimer(1, func { obj.update(); obj.UpdateTimer.restart(obj.update_rate_seconds); }); obj.UpdateTimer.restart(0); return obj; }, # # # get a text element from the SVG and set the font / sizing get_text : func(id, font, size, ratio) { var el = me.svg.getElementById(id); el.setFont(font).setFontSize(size,ratio); return el; }, # # # Get an element from the SVG; handle errors; and apply clip rectangle # if found (by naming convention : addition of _clip to object name). get_element : func(id) { var el = me.svg.getElementById(id); if (el == nil) { print("Failed to locate ",id," in SVG"); return el; } # # if an element has a matching "element_clip" (i.e. with _clip appened) # then use this as the clipping rectangle for this item. # NOTE: clipping rectangles are to be used sparingly as they place extra workload on the scene transformations var clip_el = me.svg.getElementById(id ~ "_clip"); if (clip_el != nil) { clip_el.setVisible(0); var tran_rect = clip_el.getTransformedBounds(); var clip_rect = sprintf("rect(%d,%d, %d,%d)", tran_rect[1], # 0 ys tran_rect[2], # 1 xe tran_rect[3], # 2 ye tran_rect[0]); #3 xs el.set("clip", clip_rect); el.set("clip-frame", canvas.Element.PARENT); } return el; }, update : func { foreach(var update_item; me.update_items) { update_item.update(); } }, };