2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

Module:高级3D模型预览

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳转到导航 跳转到搜索
Template-info.svg 模块文档  [创建] [刷新]
local p = {}

local utils = {
    get_args = function(frame)
        local origArgs
        if frame == mw.getCurrentFrame() then
            -- We're being called via #invoke. If the invoking template passed any args, use
            -- them. Otherwise, use the args that were passed into the template.
            origArgs = frame:getParent().args
            for k, v in pairs(frame.args) do
                origArgs = frame.args
                break
            end
        else
            -- We're being called from another module or from the debug console, so assume
            -- the args are passed in directly.
            origArgs = frame
        end
     
        -- ParserFunctions considers the empty string to be false, so to preserve the previous 
        -- behavior of the template, change any empty arguments to nil, so Lua will consider
        -- them false too.
        local args = {}
        for k, v in pairs(origArgs) do
            if v ~= '' then
                -- parameter names should be case-insensitive
                if type(k) == 'string' then
                    k = string.lower(k)
                end
                args[k] = v
            end
        end
        return args
    end,
    expandWikitext = function(wikitext)
        -- function to process wikitext, expanding templates, and return result
        return mw.getCurrentFrame():preprocess(wikitext)
    end,
    processArg = function(arg, default)
        -- function that replicates wiki template behaviour where nil and blank arguments are equivalent here
        if arg and arg ~= '' then
            return arg
        end
        return default or ''
    end,
    processArgLowered = function(arg, default)
        -- similar to processArg but returns lowered string
        local processed_arg = util.processArg(arg, default)
        if processed_arg then
            return string.lower(processed_arg)
        end
        return ''
    end
}
local frame = nil

-- Expands the template Common string for a given value. Note that some common string values include an additional parameter, here called opt_arg.
function common_string(arg, opt_arg)
    return frame:expandTemplate{title='Common string', args={arg, opt_arg}}
end

-- Returns ' (text)', with correct parenthesis characters in Chinese.
function paren(text)
    if if_lang == '/zh_hans' or if_lang == '/zh-hant' then
        return ' (' .. text .. ')'
    else
        return ' (' .. text .. ')'
    end
end

function p.viewer(f)
    local args = utils.get_args(f)
    local startframe = utils.processArg(args['startframe'])
    local image = utils.processArg(args['image'])
    local image_0 = utils.processArg(args['image-0'])
    local fallback = utils.processArg(args['fallback'])
    local startframe_class
    if startframe ~= '' then
        startframe_class = mw.text.trim(startframe)
    else
        startframe_class = utils.expandWikitext('[[File:' .. (image_0 or image) .. '|startframe]]')
    end
    local output_view = mw.html.create('div')
        :addClass('viewer-3d')
        :addClass('startframe-' .. startframe_class)
        :wikitext(fallback)

    for i = 0,10 do
        local image_n = utils.processArg(args['image-' .. i], '')
        if image_n ~= '' then
            span_image_url_n = output_view
                :tag('span')
                :addClass('viewer-3d-url-' .. i)
                :wikitext(utils.expandWikitext('[[File:' .. image_n .. '|url]]'))

            span_image_map_n = output_view
                :tag('span')
                :addClass('viewer-3d-map-' .. i)
                :wikitext(utils.expandWikitext('[[File:' .. image_n .. '|map]]'))
        end
    end

    local viewer_3d_frame = output_view
        :tag('div')
        :addClass('viewer-3d-frame')

    local switch_to_2d = output_view
        :tag('div')
        :attr('id', 'switch-to-2d')

    return tostring(output_view)
end

function p.viewer_new(f)
    frame = f
    local args = utils.get_args(f)
    
    -- button classes mapping
    local button_classes = {
        red = 'view-selector-red',
        blu = 'view-selector-blu',
        australium_half = 'view-selector-australium-',
        australium_full = 'view-selector-australium-full',
        australium = 'view-selector-australium-full',
        default_half = 'view-selector-default-',
        default_full = 'view-selector-default-full',
        default = 'view-selector-default-full'
    }

    -- create output container
    local output_view = mw.html.create('div')
        :addClass('viewer-3d-container')
    
    -- create container for viewer
    local startimage = utils.processArg(args['3d-image-1'])
    -- if first button is colored then add RED to filename
    if utils.processArg(args['3d-button-1']) == 'colored_pair' then
        startimage = startimage .. ' RED'
    end
    local startframe = args['3d-startframe'] or utils.expandWikitext('[[File:' .. startimage .. ' 3D.jpg|startframe]]')
    local viewer_container = output_view
        :tag('div')
        :addClass('viewer-3d')
        :addClass('startframe-' .. startframe)

    -- add 3D and 2D selectors
    local viewer_3d_frame = viewer_container
        :tag('div')
        :addClass('viewer-3d-frame')

    local switch_to_2d = viewer_container
        :tag('div')
        :attr('id', 'switch-to-2d')

    -- create container for model selector buttons
    local buttons_container = output_view
        :tag('ul')
        :addClass('buttons-container-3d')

    -- create container for 2D image
    local image_2d
    if args['image'] then
        image_2d = args['image']
    elseif args['team-colors'] == 'yes' then
        image_2d = args['skin-image-red'] or mw.title.getCurrentTitle().baseText .. ' RED.png'
    else
        image_2d = mw.title.getCurrentTitle().baseText .. '.png'
    end
    local viewer_2d_frame = output_view
        :tag('div')
        :wikitext(utils.expandWikitext('{{2D viewer|' .. image_2d .. '|' .. (args['imagewidth'] or '250px') .. '}}'))

    -- row button counter for half width buttons
    local current_row_count = 0
    local colored = false
    local i = 1
    while utils.processArg(args['3d-image-' .. i]) ~= '' or colored do
    -- the "or colored" ensures that if the last image pair is team-colored, it will still be processed.
        local image_postfix = ' 3D.jpg'
        local viewname_postfix = ''
        if colored then
            -- if we are the second half of a team-colored image, use the details from the first half.
            i = i - 1
        end
        local image_n = utils.processArg(args['3d-image-' .. i])
        local button_n = utils.processArg(args['3d-button-' .. i])
        local button_class = button_classes[button_n]
        local viewname_n = utils.processArg(args['3d-viewname-' .. i])
        if colored then
            i = i + 1
            image_postfix = ' BLU 3D.jpg'
            viewname_postfix = paren(common_string('BLU'))
            button_class = 'view-selector-blu'
            colored = false
        elseif not colored and button_n == 'colored_pair' then
            image_postfix = ' RED 3D.jpg'
            viewname_postfix = paren(common_string('RED'))
            button_class = 'view-selector-red'
            colored = true
        end
        if image_n ~= '' then
            span_image_url_n = viewer_container
                :tag('span')
                :addClass('viewer-3d-url-' .. (i-1))
                :wikitext(utils.expandWikitext('[[File:' .. image_n .. image_postfix .. '|url]]'))

            span_image_map_n = viewer_container
                :tag('span')
                :addClass('viewer-3d-map-' .. (i-1))
                :wikitext(utils.expandWikitext('[[File:' .. image_n .. image_postfix .. '|map]]'))

            -- if there is only one 3d image then don't attach selector
            if i == 1 and args['3d-image-2'] == nil and args['3d-image-3'] == nil then
                break
            end
            -- add selector button for this model
            if button_n == 'default_half' or button_n == 'australium_half' then
                if current_row_count == 0 then
                    button_class = button_class .. 'left'
                    current_row_count = 1
                else
                    button_class = button_class .. 'right'
                    current_row_count = 0
                end
            end
            -- selector is 0-indexed
            button_class = button_class .. ' selector-' .. (i-1)
            
            li_button_n = buttons_container
                :tag('li')
                :addClass(button_class)
                :wikitext(utils.expandWikitext('[[:File:' .. image_n .. image_postfix .. '|' .. viewname_n .. viewname_postfix .. ']]'))
        end

        i = i + 1
    end

    return tostring(output_view)
end

return p