Bước tới nội dung

Mô đun:Màu sắc

Từ điển mở Wiktionary
local p = {}
local m = require "Mô đun:Math"

-- Từ mã nguồn [[:Tập tin:Linear visible spectrum.svg]].
p.visibleSpectrum = {
  [380] = {offset = 0.000000, red = 0x02, green = 0x00, blue = 0x05},
  [385] = {offset = 0.013514, red = 0x02, green = 0x00, blue = 0x06},
  [390] = {offset = 0.027027, red = 0x03, green = 0x00, blue = 0x08},
  [395] = {offset = 0.040541, red = 0x04, green = 0x00, blue = 0x0A},
  [400] = {offset = 0.054054, red = 0x06, green = 0x00, blue = 0x0D},
  [405] = {offset = 0.067568, red = 0x08, green = 0x01, blue = 0x10},
  [410] = {offset = 0.081081, red = 0x0C, green = 0x01, blue = 0x17},
  [415] = {offset = 0.094595, red = 0x11, green = 0x02, blue = 0x1F},
  [420] = {offset = 0.108108, red = 0x17, green = 0x03, blue = 0x2A},
  [425] = {offset = 0.121622, red = 0x1F, green = 0x05, blue = 0x3A},
  [430] = {offset = 0.135135, red = 0x25, green = 0x08, blue = 0x4B},
  [435] = {offset = 0.148649, red = 0x29, green = 0x0A, blue = 0x5C},
  [440] = {offset = 0.162162, red = 0x2B, green = 0x0E, blue = 0x6F},
  [445] = {offset = 0.175676, red = 0x29, green = 0x13, blue = 0x80},
  [450] = {offset = 0.189189, red = 0x1F, green = 0x23, blue = 0x7B},
  [455] = {offset = 0.202703, red = 0x13, green = 0x2E, blue = 0x74},
  [460] = {offset = 0.216216, red = 0x09, green = 0x37, blue = 0x6C},
  [465] = {offset = 0.229730, red = 0x0A, green = 0x3E, blue = 0x66},
  [470] = {offset = 0.243243, red = 0x0C, green = 0x46, blue = 0x67},
  [475] = {offset = 0.256757, red = 0x0E, green = 0x4F, blue = 0x6A},
  [480] = {offset = 0.270270, red = 0x10, green = 0x59, blue = 0x6C},
  [485] = {offset = 0.283784, red = 0x11, green = 0x63, blue = 0x6D},
  [490] = {offset = 0.297297, red = 0x14, green = 0x6E, blue = 0x6F},
  [495] = {offset = 0.310811, red = 0x17, green = 0x79, blue = 0x70},
  [500] = {offset = 0.324324, red = 0x17, green = 0x86, blue = 0x72},
  [505] = {offset = 0.337838, red = 0x1A, green = 0x95, blue = 0x74},
  [510] = {offset = 0.351351, red = 0x1D, green = 0xA3, blue = 0x75},
  [515] = {offset = 0.364865, red = 0x1D, green = 0xB2, blue = 0x73},
  [520] = {offset = 0.378378, red = 0x20, green = 0xC0, blue = 0x70},
  [525] = {offset = 0.391892, red = 0x22, green = 0xCB, blue = 0x6B},
  [530] = {offset = 0.405405, red = 0x21, green = 0xD6, blue = 0x62},
  [535] = {offset = 0.418919, red = 0x23, green = 0xE0, blue = 0x54},
  [540] = {offset = 0.432432, red = 0x36, green = 0xE8, blue = 0x42},
  [545] = {offset = 0.445946, red = 0x50, green = 0xED, blue = 0x28},
  [550] = {offset = 0.459459, red = 0x73, green = 0xEB, blue = 0x22},
  [555] = {offset = 0.472973, red = 0x8F, green = 0xE7, blue = 0x22},
  [560] = {offset = 0.486486, red = 0xA5, green = 0xE2, blue = 0x21},
  [565] = {offset = 0.500000, red = 0xB9, green = 0xDC, blue = 0x22},
  [570] = {offset = 0.513514, red = 0xCB, green = 0xD6, blue = 0x21},
  [575] = {offset = 0.527027, red = 0xDC, green = 0xCE, blue = 0x20},
  [580] = {offset = 0.540541, red = 0xEC, green = 0xC4, blue = 0x20},
  [585] = {offset = 0.554054, red = 0xF2, green = 0xB7, blue = 0x35},
  [590] = {offset = 0.567568, red = 0xF5, green = 0xAB, blue = 0x42},
  [595] = {offset = 0.581081, red = 0xF6, green = 0x9F, blue = 0x49},
  [600] = {offset = 0.594595, red = 0xF7, green = 0x94, blue = 0x4B},
  [605] = {offset = 0.608108, red = 0xF9, green = 0x88, blue = 0x48},
  [610] = {offset = 0.621622, red = 0xFA, green = 0x7B, blue = 0x42},
  [615] = {offset = 0.635135, red = 0xFB, green = 0x6C, blue = 0x39},
  [620] = {offset = 0.648649, red = 0xFD, green = 0x5B, blue = 0x2E},
  [625] = {offset = 0.662162, red = 0xFC, green = 0x47, blue = 0x1F},
  [630] = {offset = 0.675676, red = 0xF7, green = 0x30, blue = 0x0F},
  [635] = {offset = 0.689189, red = 0xEA, green = 0x22, blue = 0x0D},
  [640] = {offset = 0.702703, red = 0xD4, green = 0x22, blue = 0x15},
  [645] = {offset = 0.716216, red = 0xBF, green = 0x23, blue = 0x18},
  [650] = {offset = 0.729730, red = 0xA9, green = 0x23, blue = 0x09},
  [655] = {offset = 0.743243, red = 0x98, green = 0x1F, blue = 0x07},
  [660] = {offset = 0.756757, red = 0x87, green = 0x1B, blue = 0x06},
  [665] = {offset = 0.770270, red = 0x77, green = 0x18, blue = 0x05},
  [670] = {offset = 0.783784, red = 0x67, green = 0x15, blue = 0x04},
  [675] = {offset = 0.797297, red = 0x59, green = 0x13, blue = 0x03},
  [680] = {offset = 0.810811, red = 0x4D, green = 0x11, blue = 0x03},
  [685] = {offset = 0.824324, red = 0x42, green = 0x0E, blue = 0x02},
  [690] = {offset = 0.837838, red = 0x37, green = 0x0C, blue = 0x01},
  [695] = {offset = 0.851351, red = 0x2E, green = 0x0A, blue = 0x01},
  [700] = {offset = 0.864865, red = 0x27, green = 0x08, blue = 0x01},
  [705] = {offset = 0.878378, red = 0x21, green = 0x06, blue = 0x00},
  [710] = {offset = 0.891892, red = 0x1E, green = 0x04, blue = 0x00},
  [715] = {offset = 0.905405, red = 0x1A, green = 0x03, blue = 0x00},
  [720] = {offset = 0.918919, red = 0x17, green = 0x02, blue = 0x00},
  [725] = {offset = 0.932432, red = 0x13, green = 0x01, blue = 0x00},
  [730] = {offset = 0.945946, red = 0x10, green = 0x01, blue = 0x00},
  [735] = {offset = 0.959459, red = 0x0C, green = 0x01, blue = 0x00},
  [740] = {offset = 0.972973, red = 0x08, green = 0x01, blue = 0x00},
  [745] = {offset = 0.986486, red = 0x06, green = 0x01, blue = 0x00},
  [750] = {offset = 1.000000, red = 0x04, green = 0x01, blue = 0x00},
}

p.cssGradientFormats = {
    {"background: -moz-linear-gradient(left, %s);", "%s %i%%"}, -- Gecko 1.9.2+
    {"background: -webkit-gradient(linear, left top, right top, %s);", stop = "color-stop(%i%%, %s)"}, -- Chrome, Safari 4+
    {"background: -webkit-linear-gradient(left, %s);", "%s %i%%"}, -- Chrome 10+, Safari 5.1+
    {"background: -o-linear-gradient(left, %s);", "%s %i%%"}, -- Presto 2.8+
    {"background: -icab-linear-gradient(left, %s);", "%s %i%%"}, -- iCab?
    {"background: -khtml-gradient(linear, left top, right top, %s);", stop = "color-stop(%i%%, %s)"}, -- KHTML?
    {"background: -ms-linear-gradient(left, %s);", "%s %i%%"}, -- Trident 6.0+
    {"background: linear-gradient(to right, %s);", "%s %i%%"}, -- CSS 3
}

function p.visibleSpectrumCSSGradient(frame)
    local nmMin = m._roundNearest(frame.args[1] or 0, 5)
    local nmMax = m._roundNearest(frame.args[2] or 0, 5)
    
    local offsetMin = 0
    for i = nmMin, nmMax, 5 do
        local stop = p.visibleSpectrum[i]
        if stop then
            offsetMin = stop.offset
            break
        end
    end
    
    local offsetMax = 0
    for i = nmMax, nmMin, -5 do
        local stop = p.visibleSpectrum[i]
        if stop then
            offsetMax = stop.offset
            break
        end
    end
    
    local stops = {}
    for i = nmMin, nmMax, 5 do
        local stop = p.visibleSpectrum[i]
        if stop then
            table.insert(stops, {
                offset = (stop.offset - offsetMin) * 100 / (offsetMax - offsetMin),
                color = string.format("rgb(%i, %i, %i)",
                    stop.red, stop.green, stop.blue),
            })
        end
    end
    
    local props = {}
    for i, format in ipairs(p.cssGradientFormats) do
        local cssStops = {}
        for j, stop in ipairs(stops) do
            local cssStop
            if format.stop then
                cssStop = mw.ustring.format(format.stop, stop.offset, stop.color)
            else
                cssStop = mw.ustring.format(format[2], stop.color, stop.offset)
            end
            table.insert(cssStops, cssStop)
        end
        
        table.insert(props, mw.ustring.format(format[1], table.concat(cssStops, ", ")))
    end
    
    return table.concat(props, " ")
end

return p