local module = {} local getArgs = require('Module:Arguments').getArgs local shadow={} shadow.__index=shadow function shadow.create() return setmetatable({},shadow) end function shadow:moveStep(value) local stringBuilder={} local d=value*self.spread*20*5 if self.rad then self.y=d*self.y_step self.x=d*self.x_step stringBuilder[#stringBuilder+1]=self.vertical and ("calc("..self.y.."px + "..self.vertical..")") or self.y.."px" stringBuilder[#stringBuilder+1]=self.horizontal and ("calc("..self.x.."px + "..self.horizontal..")") or self.x.."px" else stringBuilder[#stringBuilder+1]="0" stringBuilder[#stringBuilder+1]="0" end stringBuilder[#stringBuilder+1]=(2+d*self.dispersity/4).."px" if self.intensity then stringBuilder[#stringBuilder+1]="calc("..((1-value)*self.spread/8).." * "..self.intensity..")" end stringBuilder[#stringBuilder+1]=self.color if self.inset then stringBuilder[#stringBuilder+1]=self.inset end return table.concat(stringBuilder," ") end function shadow:done() if tonumber(self.direct) then self.rad=math.rad(self.direct) self.x_step=math.floor(100*math.cos(self.rad))/100 self.y_step=math.floor(100*math.sin(self.rad))/100 end local stringBuilder={} for i=0,self.count do stringBuilder[#stringBuilder+1]=self:moveStep(i/self.count) end return table.concat(stringBuilder,",") end function module._main(args,isBlock)--主函数 local stepNum=1 local function step(func) local n=stepNum while true do local arg=args[n] if not arg then return nil end local v if func then v=func(arg) else v=arg end if v then stepNum=n+1 return v end n=n+1 end end local function directFilter(str) if str=="none" then return "none" end if str=="left" then return 270 end if str=="right" then return 90 end if str=="up" then return 0 end if str=="down" then return 180 end return tonumber(str) end local function valueFilter(str) if string.match(str, "^%-?%d+%.*%d*%l*$") then return str end end local function numberFilter(str) if string.match(str, "^%-?%d+%.*%d*$") then return str end end local function sizeFilter(str) if string.match(str, "^%-?%d+%.*%d*%l*$") then return str end if string.match(str, "^%-?%d+%.*%d*%%$") then return str end end local function tagFilter(str) if string.match(str, "^%l*$") then return str end end local function insetFilter(str) if str=="内部" or str=="inset" then return true end end local text =args["内容"] or args.content or step() local shadow=shadow.create() shadow.direct =directFilter(args["方向"] or args.direct) or step(directFilter) or "none"--none/left right up down/number shadow.spread =tonumber(args["范围"] or args.spread or step(valueFilter)) or 1 shadow.dispersity =tonumber(args["分散"] or args.dispersity or step(numberFilter)) or 1 if isBlock then shadow.intensity =args["强度"] or args.intensity or step(valueFilter) or "4px" end shadow.horizontal =args["横向偏移"] or args.horizontal or step(valueFilter) shadow.vertical =args["纵向偏移"] or args.vertical or step(valueFilter) shadow.inset =args["内部"] or args.inset or step(insetFilter) shadow.color =args["颜色"] or args.color or step() shadow.count =tonumber(args["细致值"] or args.count or step(valueFilter)) or 20 local tag if isBlock then tag = args["标签"] or args.tag or step(tagFilter) or "span" else tag = "span" end local node =mw.html.create(tag) :css(isBlock and "box-shadow" or "text-shadow",shadow:done()) :wikitext(text) if isBlock then node :css("width",args["宽"] or args.width or step(sizeFilter)) :css("height",args["高"] or args.height or step(sizeFilter)) :cssText(args.css) end return node:done() end function module.text(frame)--文本 local args = getArgs(frame)--test ABC|red|right|1 return module._main(args,false)--test {"ABC","right","1","red"} end function module.block(frame)--块 local args = getArgs(frame)--test "<div style="height:20px;width:20px"></div>"|"right"|"1"|"red" return module._main(args,true)--test {'<div style="height:20px;width:20px"></div>',"right","1","red"} end return module