SvgCreate: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
mNo edit summary
(Remove obsolete Requirements section)
 
(22 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Client function}}
{{Client function}}
{{Added feature/item|1.5.9|1.5.8|20979|Creates an [[svg]] from size (blank document), filepath or raw data.}}
__NOTOC__
{{Added feature/item|1.5.9|1.5.8|20979|
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 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.}}
 
{{Note|SVG in MTA is handled by the '''lunasvg''' rendering engine - Some features in MTA may not work properly, compared to the browser.}}
''Check the list of supported [https://github.com/sammycage/lunasvg?tab=readme-ov-file#features features].'''
 
{{Tip|If you are experiencing poor texture quality or artifacts in the form of black outlines, setting the blend mode to '''add''' might help}}
 
==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 10: Line 21:
===Optional Arguments===
===Optional Arguments===
{{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]]).


'''Note:''' See [[svgSetUpdateCallback]] for setting an svg's callback function after it has been created.
===Returns===
===Returns===
* Returns an [[svg]] if created successfully, ''false'' otherwise.
* Returns an [[svg]] if created successfully, ''false'' otherwise.


==Example==
==Example==
The example below shows how you can load an SVG from raw data (or path) and manipulate the underlying XML document.
This is a basic example of how you can create 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 29: Line 64:
]]
]]


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
        }


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


         onSvgLoad(svg)
    -- 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 setRandomSVGSize(svg)
    local width, height = svgGetSize(svg)
    local diff = math.min(width, height) /  math.max(width, height)
    local size = math.random(100, 500)


-- Implement a callback for SVG load
     svgSetSize(svg, size, size * diff)
function onSvgLoad(svg)
     addEventHandler("onClientRender", root, render)
end
 
function render()
    dxDrawImage(0, 0, 500, 500, svg, 0, 0, 0, tocolor(255, 255, 255), false)
end
end
</syntaxhighlight>
</syntaxhighlight>
==Requirements==
{{Requirements|n/a|1.5.8-9.20979|}}


==See Also==
==See Also==
{{SVG_functions}}
{{SVG_functions}}
[[pt-br:svgCreate]]

Latest revision as of 17:29, 7 November 2024

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


[[{{{image}}}|link=|]] Important Note: Before r21155 (3157905) the provided callback 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.
[[{{{image}}}|link=|]] Note: SVG in MTA is handled by the lunasvg rendering engine - Some features in MTA may not work properly, compared to the browser.

Check the list of supported features.'


[[{{{image}}}|link=|]] Tip: If you are experiencing poor texture quality or artifacts in the form of black outlines, setting the blend mode to add might help

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).

Note: See svgSetUpdateCallback for setting an svg's callback function after it has been created.

Returns

  • Returns an svg if created successfully, false otherwise.

Example

This is a basic example of how you can create 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

See Also