SvgCreate: 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|}}
{{Added feature/item|1.5.9|1.5.8|20979|}}
Creates an [[svg]] from size (blank document), filepath or raw data.
Creates an [[svg]] from size (blank document), filepath or raw data.
{{Important Note|Before r21155 ([https://github.com/multitheftauto/mtasa-blue/commit/31579051cc046bc5cb55c59fc4e9e70ec1bdce34 3157905]) the provided callback wasn't stored on the SVG and was only fired '''once''' after the function had performed its task. This is no longer the case - each SVG can now store a single callback function (optional) which is fired '''every time''' the SVG texture has been changed/updated. }}
==Syntax==  
==Syntax==  
<syntaxhighlight lang="lua">svg svgCreate ( int width, int height [, string pathOrRawData, function callback ( bool didLoad ) ] )</syntaxhighlight>
<syntaxhighlight lang="lua">svg svgCreate ( int width, int height [, string pathOrRawData, function callback ( element svg ) ] )</syntaxhighlight>


===Required Arguments===
===Required Arguments===
Line 13: Line 16:
{{OptionalArg}}
{{OptionalArg}}
*'''pathOrRawData:''' A string representing the path to your SVG file, or the raw SVG data
*'''pathOrRawData:''' A string representing the path to your SVG file, or the raw SVG data
*'''callback:''' A callback function which is invoked upon SVG document and texture creation, useful for knowing when the [[svg]] is ready
*'''callback:''' A callback function which is stored on the SVG and fired every time the SVG texture is updated (for example, via [[svgSetDocumentXML]])


===Returns===
===Returns===
Line 19: Line 22:


==Example==
==Example==
The example below shows how you can load an SVG from raw data (or path) and draw it with [[dxDrawImage]] via [[onClientRender]].
The example below shows a basic example of how you can load an SVG from raw data (or path) and draw it with [[dxDrawImage]] via [[onClientRender]].
 
<syntaxhighlight lang="lua">
-- 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 myCircleSvg
 
local function drawCircleSvg()
    dxDrawImage(0, 0, 500, 500, myCircleSvg, 0, 0, 0, tocolor(255, 255, 255), false)
end
 
local function init()
    -- Create an SVG containing a circle, using the raw XML data above
    myCircleSvg = svgCreate(500, 500, rawSvgData)
    addEventHandler("onClientRender", root, drawCircleSvg)
end
addEventHandler("onClientResourceStart", resourceRoot, init)
</syntaxhighlight>


'''IMPORTANT''': Depending on your implementation, callback usage may be necessary to ensure the SVG texture and XML document are ready.
Here's another, more in-depth example which utilizes the callback argument. You can use the F2 key to set the SVG to a random size and see the update callback output a message to debugscript.


<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 31: Line 56:
]]
]]


local svg
local svgs = {}


function init()
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
     -- 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


        addEventHandler("onClientRender", root, render)
    -- Bind a key to set SVG to a random size, which will trigger the onUpdate callback
    bindKey("F2", "down", function()
        setRandomSVGSize(mySvg)
     end)
     end)
end
end
addEventHandler("onClientResourceStart", resourceRoot, init)
addEventHandler("onClientResourceStart", resourceRoot, init)


function render()
function setRandomSVGSize(svg)
     dxDrawImage(0, 0, 500, 500, svg, 0, 0, 0, tocolor(255, 255, 255), false)
    local width, height = svgGetSize(svg)
     local diff = math.min(width, height) /  math.max(width, height)
    local size = math.random(100, 500)
 
    svgSetSize(svg, size, size * diff)
end
end
</syntaxhighlight>
</syntaxhighlight>


==Requirements==
==Requirements==

Revision as of 23:01, 8 April 2022


Creates an svg from size (blank document), filepath or raw data.


[[{{{image}}}|link=|]] Important Note: Before r21155 (3157905) the provided callback wasn't stored on the SVG and was only fired once after the function had performed its task. This is no longer the case - each SVG can now store a single callback function (optional) which is fired every time the SVG texture has been changed/updated.

Syntax

svg svgCreate ( int width, int height [, string pathOrRawData, function callback ( element svg ) ] )

Required Arguments

  • width: Desired width, preferably power of two (16, 32, 64 etc.), maximum is 4096
  • height : Desired height, preferably power of two (16, 32, 64 etc.), maximum is 4096

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.

  • pathOrRawData: A string representing the path to your SVG file, or the raw SVG data
  • callback: A callback function which is stored on the SVG and fired every time the SVG texture is updated (for example, via svgSetDocumentXML)

Returns

  • Returns an svg if created successfully, false otherwise.

Example

The example below shows a basic example of how you can load an SVG from raw data (or path) and draw it with dxDrawImage via onClientRender.

-- 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 myCircleSvg

local function drawCircleSvg()
    dxDrawImage(0, 0, 500, 500, myCircleSvg, 0, 0, 0, tocolor(255, 255, 255), false)
end

local function init()
    -- Create an SVG containing a circle, using the raw XML data above
    myCircleSvg = svgCreate(500, 500, rawSvgData)
    addEventHandler("onClientRender", root, drawCircleSvg)
end
addEventHandler("onClientResourceStart", resourceRoot, init)

Here's another, more in-depth example which utilizes the callback argument. You can use the F2 key to set the SVG to a random size and see the update callback output a message to debugscript.

-- 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 set SVG to a random size, which will trigger the onUpdate callback
    bindKey("F2", "down", function()
        setRandomSVGSize(mySvg)
    end)
end
addEventHandler("onClientResourceStart", resourceRoot, init)

function setRandomSVGSize(svg)
    local width, height = svgGetSize(svg)
    local diff = math.min(width, height) /  math.max(width, height)
    local size = math.random(100, 500)

    svgSetSize(svg, size, size * diff)
end


Requirements

This template will be deleted.

See Also