SvgSetDocumentXML: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
No edit summary
(Update usage & examples as per GitHub PR #2589)
Line 3: Line 3:
{{Added feature/item|1.5.9|1.5.8|20979|Sets the underlying XML document of an SVG element.}}
{{Added feature/item|1.5.9|1.5.8|20979|Sets the underlying XML document of an SVG element.}}
==Syntax==  
==Syntax==  
<syntaxhighlight lang="lua">bool svgSetDocumentXML ( svg svgElement, xmlnode xmlDocument [, function callback ( bool didLoad ) ] )</syntaxhighlight>
<syntaxhighlight lang="lua">bool svgSetDocumentXML ( svg svgElement, xmlnode xmlDocument [, function callback ( element svg ) ] )</syntaxhighlight>


===Required Arguments===
===Required Arguments===
Line 11: Line 11:
===Optional Arguments===
===Optional Arguments===
{{OptionalArg}}
{{OptionalArg}}
*'''callback:''' A callback function which is invoked upon SVG document and texture creation, useful for knowing when the SVG element is ready
*'''callback:''' A callback function which is stored on the SVG and fired every time the SVG texture is updated (for example, via [[svgSetSize]]). '''Note:''' if present, this will overwrite the current callback stored on the svg


===Returns===
===Returns===
Line 17: Line 17:


==Example==
==Example==
The example below shows how you can load an SVG from raw data (or path), manipulate the underlying XML document and then draw it with [[dxDrawImage]] via [[onClientRender]].
This example creates an [[svg]] element including a keybind (F2) to add a child rect node, with the use of callbacks to notify in debugscript when the SVG was updated.
 
'''IMPORTANT''': Depending on your implementation, callback usage may be necessary to ensure the SVG texture and XML document are ready.


<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
-- This could also be a file, with the path provided to svgCreate
-- This could also be a file, with the path provided to svgCreate instead
local rawSvgData = [[
local rawSvgData = [[
     <svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
     <svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
Line 29: Line 27:
]]
]]


local svg
local svgs = {}
 
local function render(svg)
    if (not isElement(svg)) or (getElementType(svg) ~= "svg") then
        removeEventHandler("onClientRender", root, svgs[svg].handler)
        svgs[svg] = nil
    end
 
    local width, height = svgGetSize(svg)
    dxDrawImage(0, 0, width, height, svg, 0, 0, 0, tocolor(255, 255, 255), false)
end
 
local function onUpdate(svg)
    -- If this is the first update, add svg to our table and start drawing it
    if (not svgs[svg]) then
        svgs[svg] = {
            state = true,
            handler = function()
                render(svg)
            end
        }
 
        addEventHandler("onClientRender", root, svgs[svg].handler)
    end
 
    iprint("SVG texture updated", svg, getTickCount())
end


function init()
local function init()
     -- Create an SVG containing a circle, using the raw XML data above
     -- Create an SVG containing a circle, using the raw XML data above
     svg = svgCreate(500, 500, rawSvgData, function(didLoad)
     local mySvg = svgCreate(500, 500, rawSvgData, onUpdate)
        if (not didLoad) then -- SVG failed to load, so don't continue
            return
        end


         onSvgLoad(svg)
    -- Bind a key to create an SVG rect child node, which will trigger the onUpdate callback
    bindKey("F2", "down", function()
         addSVGRectNode(mySvg)
     end)
     end)
end
end
addEventHandler("onClientResourceStart", resourceRoot, init)
addEventHandler("onClientResourceStart", resourceRoot, init)


 
-- Adds a rect node to the SVG with a random color, size and position
-- Implement a callback for SVG load, to manipulate the underlying XML document
function addSVGRectNode(svg)
function onSvgLoad(svg)
     -- Get the XML document from our SVG
     -- Get the XML document from our SVG
     local svgXML = svgGetDocumentXML(svg)
     local svgXML = svgGetDocumentXML(svg)
Line 51: Line 73:
     -- Add a rect SVG node, positioned center of the document
     -- Add a rect SVG node, positioned center of the document
     local rect = xmlCreateChild(svgXML, "rect")
     local rect = xmlCreateChild(svgXML, "rect")
     xmlNodeSetAttribute(rect, "x", "25%")
 
     xmlNodeSetAttribute(rect, "y", "25%")
    local size = math.random(0, 50)
     xmlNodeSetAttribute(rect, "width", "50%")
    local r, g, b = math.random(10, 99), math.random(10, 99), math.random(10, 99)
     xmlNodeSetAttribute(rect, "height", "50%")
 
     xmlNodeSetAttribute(rect, "fill", "#00749b")
     xmlNodeSetAttribute(rect, "x", (size / 2) .. "%")
     xmlNodeSetAttribute(rect, "y", (size / 2) .. "%")
     xmlNodeSetAttribute(rect, "width", size .. "%")
     xmlNodeSetAttribute(rect, "height", size .. "%")
     xmlNodeSetAttribute(rect, "fill", "#" .. r .. g .. b)
      
      
     -- Apply our XML to the SVG, and start drawing via callback
     -- Apply our XML to the SVG, and start drawing via callback
     return svgSetDocumentXML(svg, svgXML, function()
     svgSetDocumentXML(svg, svgXML)
        addEventHandler("onClientRender", root, render)
    end)
end
 
function render()
    local width, height = svgGetSize(svg)
    dxDrawImage(0, 0, width, height, svg, 0, 0, 0, tocolor(255, 255, 255), false)
end
end
</syntaxhighlight>
</syntaxhighlight>

Revision as of 23:15, 8 April 2022

Sets the underlying XML document of an SVG element.

Syntax

bool svgSetDocumentXML ( svg svgElement, xmlnode xmlDocument [, function callback ( element svg ) ] )

Required Arguments

  • svgElement: The svg element you want to set the XML document of
  • xmlDocument: An xmlnode containing the data to be set on the SVG document

Optional Arguments

NOTE: When using optional arguments, you might need to supply all arguments before the one you wish to use. For more information on optional arguments, see optional arguments.

  • callback: A callback function which is stored on the SVG and fired every time the SVG texture is updated (for example, via svgSetSize). Note: if present, this will overwrite the current callback stored on the svg

Returns

  • Returns true if successful, false otherwise

Example

This example creates an svg element including a keybind (F2) to add a child rect node, with the use of callbacks to notify in debugscript when the SVG was updated.

-- This could also be a file, with the path provided to svgCreate instead
local rawSvgData = [[
    <svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
        <circle cx="250" cy="250" r="250" fill="#0fc0fc" />
    </svg>
]]

local svgs = {}

local function render(svg)
    if (not isElement(svg)) or (getElementType(svg) ~= "svg") then
        removeEventHandler("onClientRender", root, svgs[svg].handler)
        svgs[svg] = nil
    end

    local width, height = svgGetSize(svg)
    dxDrawImage(0, 0, width, height, svg, 0, 0, 0, tocolor(255, 255, 255), false)
end

local function onUpdate(svg)
    -- If this is the first update, add svg to our table and start drawing it
    if (not svgs[svg]) then
        svgs[svg] = {
            state = true,
            handler = function()
                render(svg)
            end
        }

        addEventHandler("onClientRender", root, svgs[svg].handler)
    end

    iprint("SVG texture updated", svg, getTickCount())
end

local function init()
    -- Create an SVG containing a circle, using the raw XML data above
    local mySvg = svgCreate(500, 500, rawSvgData, onUpdate)

    -- Bind a key to create an SVG rect child node, which will trigger the onUpdate callback
    bindKey("F2", "down", function()
        addSVGRectNode(mySvg)
    end)
end
addEventHandler("onClientResourceStart", resourceRoot, init)

-- Adds a rect node to the SVG with a random color, size and position
function addSVGRectNode(svg)
    -- Get the XML document from our SVG
    local svgXML = svgGetDocumentXML(svg)
    
    -- Add a rect SVG node, positioned center of the document
    local rect = xmlCreateChild(svgXML, "rect")

    local size = math.random(0, 50)
    local r, g, b = math.random(10, 99), math.random(10, 99), math.random(10, 99)

    xmlNodeSetAttribute(rect, "x", (size / 2) .. "%")
    xmlNodeSetAttribute(rect, "y", (size / 2) .. "%")
    xmlNodeSetAttribute(rect, "width", size .. "%")
    xmlNodeSetAttribute(rect, "height", size .. "%")
    xmlNodeSetAttribute(rect, "fill", "#" .. r .. g .. b)
    
    -- Apply our XML to the SVG, and start drawing via callback
    svgSetDocumentXML(svg, svgXML)
end

Requirements

This template will be deleted.

See Also