匿名
未登录
中文(中国大陆)
创建账号
登录
Limbo Wiki
搜索
这是测试站点!!!!
不要保存重要内容!不要保存重要内容!不要保存重要内容!不要保存重要内容!不要保存重要内容!
查看“︁模块:纸张”︁的源代码
来自Limbo Wiki
命名空间
模块
讨论
更多
更多
页面操作
中文(中国大陆)
阅读
查看源代码
历史
←
模块:纸张
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于这些用户组的用户执行:
管理员
、
邮箱已验证用户
、FullUser
您可以查看和复制此页面的源代码。
local p = {} local TYPES = { ['咖啡']='st1',['墨']='st2',['水']='st3',['茶']='st4',['霉']='st5',['血迹']='st6' } local RING = { st1=true, st3=true, st4=true } local OFF = { {5,-6,0.66}, {-6,7,0.58}, {9,6,0.50}, {-5,-8,0.44} } local WEARPTS = { {10,14,1.30,1.00},{72,30,1.70,1.20},{38,66,1.55,1.10},{84,72,1.20,0.95}, {20,86,1.85,1.30},{56,8,1.10,0.85},{90,44,1.00,0.80},{6,52,1.40,1.05}, } local CORNERCLS = { ['左上']='tl',['右上']='tr',['左下']='bl',['右下']='br' } local CORNERPOS = { tl='0% 0%', tr='100% 0%', bl='0% 100%', br='100% 100%' } local function trim(s) if not s then return '' end s=s:gsub('^%s+','') s=s:gsub('%s+$','') return s end local function clamp(v,lo,hi) if v<lo then return lo end if v>hi then return hi end return v end local function lcg(n) return (n*1103515245+12345) % 2147483648 end local function pageSeed() local t = mw.title.getCurrentTitle().text or '' local h = 5381 for i = 1, #t do h = (h*33 + t:byte(i)) % 100003 end return h end local function normOpacity(s) local o=tonumber(s) if not o then return nil end if o>1 then o=o/100 end if o<0 then o=0 end if o>1 then o=1 end return o end local function opStr(o) if not o then return '' end return 'opacity:'..string.format('%.2f',o)..';' end local function mix(n, salt) local v = (n + salt*7919) % 2147483647 v = (v * 1103515245 + 12345) % 2147483647 v = (v * 1103515245 + 12345) % 2147483647 return v end local function jitterR(h,i) local a = mix(h+i, 1) % 33 - 16 local b = mix(h+i, 2) % 33 - 16 local c = mix(h+i, 3) % 33 - 16 local d = mix(h+i, 4) % 33 - 16 return string.format('%d%% %d%% %d%% %d%%',50+a,50+b,50+c,50+d) end local function strhash(s) if not s or s == '' then return 0 end local n = #s local step = 1 if n > 400 then step = math.floor(n / 400) end local h = 5381 for i = 1, n, step do h = (h*31 + s:byte(i)) % 1000033 end return h end local function contentSeed(content, seed, typ) return (pageSeed() + strhash(content or '')*389 + strhash(seed or '')*701 + strhash(typ or '')*47 + 17) % 1000003 end local function instSeed(frame) return contentSeed(frame.args[1], frame.args[2], frame.args[3]) end function p.stain(frame) local src = trim(frame.args[1] or '') local qtyG = clamp(math.floor(tonumber(trim(frame.args[2] or '')) or 1),1,5) local opaG = normOpacity(trim(frame.args[3] or '')) local spread = clamp(math.floor(tonumber(trim(frame.args[4] or '')) or 0),0,5) src = src:gsub(',',','):gsub(';',';'):gsub('@','@'):gsub(' ',' ') src = trim(src) local srch = 7 for i = 1, #src do srch = (srch*31 + src:byte(i)) % 100003 end local h = (contentSeed(frame.args[5], frame.args[6], frame.args[7]) + srch * 131) % 1000003 local list = {} for entry in mw.text.gsplit(src,';') do entry = trim(entry) if entry ~= '' and entry ~= '无' then local at = entry:find('@',1,true) local tname, rest if at then tname=trim(entry:sub(1,at-1)) rest=entry:sub(at+1) else tname=entry rest='' end local cls = TYPES[tname] if cls then local x,y,color,splash = nil,nil,'','' local opa,qty = opaG,qtyG if rest ~= '' then local segs = mw.text.split(rest,',',true) local px = tonumber(trim(segs[1] or '') or '') local py = tonumber(trim(segs[2] or '') or '') if px then x = clamp(px,0,95) end if py then y = clamp(py,0,95) end color = trim(segs[3] or '') local sp = trim(segs[4] or '') if sp=='飞溅' or sp=='splash' then splash=' limbo-paper-splash' end local o5 = normOpacity(trim(segs[5] or '')) if o5 then opa=o5 end local q6 = tonumber(trim(segs[6] or '') or '') if q6 then qty=clamp(math.floor(q6),1,5) end end list[#list+1] = { cls=cls, x=x, y=y, color=color, splash=splash, opa=opa, qty=qty } end end end local out, idx = {}, 0 for _, it in ipairs(list) do idx = idx + 1 local x = it.x local y = it.y if not x then x = 6 + (mix(h, idx*37+1) % 87) end if not y then y = 6 + (mix(h, idx*37+2) % 80) end local colStyle = it.color ~= '' and ('--limbo-paper-stain:'..it.color..';') or '' local shape = 'border-radius:'..jitterR(h,idx)..';' local spin = string.format('transform:rotate(%.1fdeg) scale(%.2f);', ((mix(h, idx*9+1) % 4000)/100.0) - 20, 0.68 + (mix(h, idx*9+2) % 78)/100.0) local bwid = '' if RING[it.cls] then local bbase = (it.cls == 'st3') and 0.18 or 0.24 bwid = string.format('border-width:%.2fem;', bbase * (0.60 + (mix(h, idx*29+3) % 91)/100.0)) end out[#out+1] = string.format('<span class="limbo-paper-stain limbo-paper-%s%s" style="left:%d%%;top:%d%%;%s%s%s%s%s"></span>', it.cls, it.splash, math.floor(x), math.floor(y), colStyle, shape, bwid, spin, opStr(it.opa)) for i = 1, it.qty-1 do local d = OFF[i] if d then local ring = RING[it.cls] local k = ring and (2.2 + (mix(h, idx*13+i) % 141)/100.0) or (0.60 + (mix(h, idx*13+i) % 86)/100.0) local rot = ((mix(h, idx*17+i) % 4800)/100.0) - 24 local fs = d[3] * (0.70 + (mix(h, idx*31+i) % 61)/100.0) local dx, dy = d[1]*k, d[2]*k if ring then local ang = math.rad(((mix(h, idx*43+i) % 4400)/100.0) - 22) local ca, sa = math.cos(ang), math.sin(ang) dx, dy = dx*ca - dy*sa, dx*sa + dy*ca end out[#out+1] = string.format('<span class="limbo-paper-stain limbo-paper-%s" style="left:%d%%;top:%d%%;font-size:%.2fem;transform:rotate(%.1fdeg);%s%s%s"></span>', it.cls, math.floor(clamp(x+dx,0,94)), math.floor(clamp(y+dy,0,94)), fs, rot, colStyle, 'border-radius:'..jitterR(h,idx*7+i)..';', opStr(it.opa)) end end end if spread > 0 and #list > 0 then local total = spread * 6 local cols = math.ceil(math.sqrt(total*1.4)) local rows = math.ceil(total/cols) local cw = 90.0/cols local ch = 86.0/rows for i = 1, total do local it = list[(i-1) % #list + 1] local col = (i-1) % cols local row = math.floor((i-1)/cols) local jx = lcg(i*7919) % math.max(1, math.floor(cw*0.55)) local jy = lcg(i*104729+17) % math.max(1, math.floor(ch*0.55)) local x = math.floor(4 + col*cw + jx) local y = math.floor(4 + row*ch + jy) local sc = 0.12 + (lcg(i*31337) % 84) / 100.0 local rot = (mix(h + i, 9) % 12000) / 100.0 - 60 local colStyle = it.color ~= '' and ('--limbo-paper-stain:'..it.color..';') or '' out[#out+1] = string.format( '<span class="limbo-paper-stain limbo-paper-%s" style="left:%d%%;top:%d%%;font-size:%.2fem;transform:rotate(%.1fdeg);%s%s%s"></span>', it.cls, x, y, sc, rot, colStyle, 'border-radius:'..jitterR(h,i*11+3)..';', opStr(it.opa)) end end return table.concat(out) end function p.corner(frame) local src = trim(frame.args[1] or '') src = src:gsub(',',','):gsub('、',','):gsub(';',';'):gsub(' ',' ') local out, seen = {}, {} for entry in mw.text.gsplit(src,'[,;]') do local c = CORNERCLS[trim(entry)] if c and not seen[c] then seen[c] = true out[#out+1] = '<span class="limbo-paper-deco limbo-paper-corner limbo-paper-cn-'..c..'"></span>' end end return table.concat(out) end function p.damage(frame) local n = clamp(math.floor(tonumber(trim(frame.args[1] or '')) or 0),0,8) if n < 1 then return '' end local h = contentSeed(frame.args[2], frame.args[3], frame.args[4]) local grow = 0.55 + 0.11*(n-1) local out = {} for i = 1, n do local w = WEARPTS[i] if w then local jx = ((h+i*97)%23)-11 local jy = ((h+i*131)%23)-11 local sz = 0.65 + (mix(h+i,7)%81)/100.0 out[#out+1] = string.format('<span class="limbo-paper-wear" style="left:%d%%;top:%d%%;width:%.2fem;height:%.2fem;border-radius:%s"></span>', clamp(w[1]+jx,0,92), clamp(w[2]+jy,0,90), w[3]*grow*sz, w[4]*grow*sz, jitterR(h,i*5)) end end return table.concat(out) end -- 裁切:每个图层都铺满纸张,仅在目标处留透明洞(配合 mask-composite:intersect) -- 折角:45° 线性渐变,缺口两条直角边与折痕完全贴合 -- 缺口:椭圆簇切出指定长宽/位置的不规则孔洞 local CORNERGRAD = { tl=135, tr=225, br=315, bl=45 } local CORNERLEG = 1.33 local function gapCores(src, h, base) local list = {} src = (src or ''):gsub(';',';'):gsub(',',','):gsub(' ',' ') local gi = 0 for entry in mw.text.gsplit(src,';') do entry = trim(entry) if entry ~= '' then local body, pos = entry:match('^(.-)@(.*)$') if not body then body = entry end body = body:gsub('×','x'):gsub('%*','x') local gw, gh = body:match('([%d%.]+)%s*[x,]%s*([%d%.]+)') if gw and gh then gi = gi + 1 local w2, h2 = tonumber(gw), tonumber(gh) local gx, gy = 50, 50 if pos then local px, py = pos:match('([%d%.%-]+)%s*,%s*([%d%.%-]+)') gx = tonumber(px) or 50 gy = tonumber(py) or 50 end local seed = h + base + gi * 3571 local n = 1 + (mix(seed, 51) % 3) local cores = {} for i = 1, n do local s = seed + i * 97 local rx, ry, xe, ye if n == 1 then rx = (w2 / 2) * (0.95 + (mix(s, 56) % 11) / 100.0) ry = (h2 / 2) * (0.95 + (mix(s, 57) % 11) / 100.0) xe, ye = 0, 0 else local ang = (mix(s, 54) % 6283) / 1000.0 local off = 0.14 + (mix(s, 55) % 13) / 100.0 xe = math.cos(ang) * (w2 / 2) * off ye = math.sin(ang) * (h2 / 2) * off rx = (w2 / 2) * (0.62 + (mix(s, 56) % 19) / 100.0) ry = (h2 / 2) * (0.62 + (mix(s, 57) % 19) / 100.0) end cores[#cores+1] = { rx=rx, ry=ry, xp=gx, xe=xe, yp=gy, ye=ye } end list[#list+1] = cores end end end return list end function p.cut(frame) local corners = trim(frame.args[1] or '') local dmg = clamp(math.floor(tonumber(trim(frame.args[2] or '')) or 0),0,8) local gaps = trim(frame.args[3] or '') local h = contentSeed(frame.args[4], frame.args[5], frame.args[6]) local layers = {} local function calcMix(pct, em) if em >= 0 then return string.format('calc(%.2f%% + %.2fem)', pct, em) end return string.format('calc(%.2f%% - %.2fem)', pct, -em) end corners = corners:gsub(',',','):gsub('、',','):gsub(';',';') local seen = {} for entry in mw.text.gsplit(corners,'[,;]') do local c = CORNERCLS[trim(entry)] if c and not seen[c] then seen[c] = true layers[#layers+1] = string.format('linear-gradient(%ddeg,transparent 0 %.2fem,#000 %.2fem)', CORNERGRAD[c], CORNERLEG, CORNERLEG + 0.02) end end local grow = 0.55 + 0.11*(dmg-1) for i = 1, dmg do local w = WEARPTS[i] if w then local jx = ((h+i*97)%23)-11 local jy = ((h+i*131)%23)-11 local sz = 0.65 + (mix(h+i,7)%81)/100.0 local r = w[3]*grow*sz*0.52 layers[#layers+1] = string.format('radial-gradient(circle at %d%% %d%%,transparent %.2fem,#000 %.2fem)', clamp(w[1]+jx,0,92), clamp(w[2]+jy,0,90), r, r*1.35) end end for _, cores in ipairs(gapCores(frame.args[3], h, 0)) do for _, c in ipairs(cores) do layers[#layers+1] = string.format('radial-gradient(ellipse %.2fem %.2fem at %s %s,transparent 0 96%%,#000 100%%)', c.rx, c.ry, calcMix(c.xp, c.xe), calcMix(c.yp, c.ye)) end end for _, cores in ipairs(gapCores(frame.args[7], h, 777)) do for _, c in ipairs(cores) do layers[#layers+1] = string.format('radial-gradient(ellipse %.2fem %.2fem at %s %s,transparent 0 96%%,#000 100%%)', c.rx, c.ry, calcMix(c.xp, c.xe), calcMix(c.yp, c.ye)) end end if #layers == 0 then return '' end return 'mask-image:'..table.concat(layers,',')..';' end function p.burnholes(frame) local h = contentSeed(frame.args[2], frame.args[3], frame.args[4]) local out, idx = {}, 0 local function calc(pct, em) if em >= 0 then return string.format('calc(%.2f%% + %.2fem)', pct, em) end return string.format('calc(%.2f%% - %.2fem)', pct, -em) end for _, cores in ipairs(gapCores(frame.args[1], h, 777)) do for _, c in ipairs(cores) do idx = idx + 1 local function v(k) return 48 + ((mix(h + idx, 90 + k) % 9) - 4) end local radius = string.format('%d%% %d%% %d%% %d%%', v(1), v(2), v(3), v(4)) out[#out+1] = string.format('<span class="limbo-paper-burnhole" style="left:%s;top:%s;width:%.2fem;height:%.2fem;border-radius:%s"></span>', calc(c.xp, c.xe), calc(c.yp, c.ye), (c.rx + 0.30) * 2, (c.ry + 0.30) * 2, radius) end end return table.concat(out) end function p.charb(frame) local h = instSeed(frame) local out = {} local function rad(seed, base) local function v(k) return 50 + ((mix(h, seed*7+k) % 33) - 16) end return string.format('%d%% %d%% %d%% %d%%', v(1), v(2), v(3), v(4)) end local function pos(basePct, em) if em >= 0 then return string.format('calc(%.1f%% + %.2fem)', basePct, em) end return string.format('calc(%.1f%% - %.2fem)', basePct, -em) end local function push(x, y, wem, hhem, seed, a) out[#out+1] = string.format( '<span class="limbo-paper-charb" style="left:%.1f%%;top:%.1f%%;width:%.2fem;height:%.2fem;border-radius:%s;background-color:rgba(28,15,4,%.2f);transform:translate(-50%%,-50%%)"></span>', clamp(x,-4,104), clamp(y,-4,104), wem, hhem, rad(seed, math.max(0.18, hhem)), a) end local function pushAt(xstr, ystr, wem, hem, seed, a) out[#out+1] = string.format( '<span class="limbo-paper-charb" style="left:%s;top:%s;width:%.2fem;height:%.2fem;border-radius:%s;background-color:rgba(28,15,4,%.2f);transform:translate(-50%%,-50%%)"></span>', xstr, ystr, wem, hem, rad(seed, math.max(0.20, math.min(wem, hem))), a) end local function pushW(x, ystr, wpct, hhem, seed, a) out[#out+1] = string.format( '<span class="limbo-paper-charb" style="left:%.1f%%;top:%s;width:%.1f%%;height:%.2fem;border-radius:%s;background-color:rgba(28,15,4,%.2f);transform:translate(-50%%,-50%%)"></span>', clamp(x,-4,104), ystr, wpct, hhem, rad(seed, math.max(0.20, hhem)), a) end local function pushH(xstr, y, wem, hpct, seed, a) out[#out+1] = string.format( '<span class="limbo-paper-charb" style="left:%s;top:%.1f%%;width:%.2fem;height:%.1f%%;border-radius:%s;background-color:rgba(28,15,4,%.2f);transform:translate(-50%%,-50%%)"></span>', xstr, clamp(y,-4,104), wem, hpct, rad(seed, math.max(0.20, wem)), a) end local function edgeH(y, salt) local per = 26 + (mix(h+salt, 5) % 14) local step = 100.0/(per-1) for i = 0, per-1 do local t = i/(per-1) local x = t*100 + (((mix(h+i, 30+salt) % 100)/100.0) - 0.5) * step * 0.9 local off = ((mix(h+i, 40+salt) % 350)/1000.0) - 0.10 local ystr if y == 0 then ystr = pos(0, off) else ystr = pos(100, -off) end local pick = mix(h+i, 55+salt) % 10 local w = step * (1.7 + (mix(h+i, 50+salt) % 90)/100.0) local hh if pick < 8 then hh = 0.30 + (mix(h+i, 60+salt) % 55)/100.0 else hh = 0.35 + (mix(h+i, 60+salt) % 85)/100.0 end pushW(x, ystr, w, hh, i*4+salt, 1) end end local function edgeV(x0, salt) local per = 26 + (mix(h+salt, 6) % 14) local step = 100.0/(per-1) for i = 0, per-1 do local t = i/(per-1) local y = t*100 + (((mix(h+i, 31+salt) % 100)/100.0) - 0.5) * step * 0.9 local off = ((mix(h+i, 41+salt) % 350)/1000.0) - 0.10 local xstr if x0 == 0 then xstr = pos(0, off) else xstr = pos(100, -off) end local pick = mix(h+i, 56+salt) % 10 local hh = step * (1.7 + (mix(h+i, 61+salt) % 90)/100.0) local w if pick < 8 then w = 0.30 + (mix(h+i, 51+salt) % 55)/100.0 else w = 0.35 + (mix(h+i, 51+salt) % 85)/100.0 end pushH(xstr, y, w, hh, i*4+salt, 1) end end edgeH(0, 10) edgeH(100, 20) edgeV(0, 30) edgeV(100, 40) for i = 1, 14 do local side = i % 4 local t = (mix(h+i, 81) % 92) + 4 local inset = 0.12 + (mix(h+i, 82) % 45)/100.0 local sz = 0.10 + (mix(h+i, 83) % 30)/100.0 local xstr, ystr if side == 0 then xstr = string.format('%.1f%%', t) ystr = pos(0, inset) elseif side == 1 then xstr = string.format('%.1f%%', t) ystr = pos(100, -inset) elseif side == 2 then xstr = pos(0, inset) ystr = string.format('%.1f%%', t) else xstr = pos(100, -inset) ystr = string.format('%.1f%%', t) end pushAt(xstr, ystr, sz*2.2, sz, i*7+3, 0.88) end return table.concat(out) end function p.charring(frame) local h = instSeed(frame) local n = 96 local function walk(seed) local t = 0.33 local out = {} for i = 1, n do local r = (mix(h + i, seed) % 1000) / 1000.0 t = t + (r * 2 - 1) * 0.055 if t < 0.18 then t = 0.18 end if t > 0.48 then t = 0.48 end if (mix(h + i, seed + 7) % 100) < 8 then t = t + 0.09 end if t > 0.58 then t = 0.58 end out[i] = t end for pass = 1, 3 do local sm = {} for i = 1, n do local a = out[math.max(1, i-1)] local b = out[i] local c = out[math.min(n, i+1)] sm[i] = a*0.25 + b*0.5 + c*0.25 end out = sm end return out end local T, R, B, L = walk(101), walk(211), walk(307), walk(401) local pts = {} local function pct(v) return string.format('%.1f%%', v) end local function em(v) return string.format('%.2fem', v) end local function right(v) return string.format('calc(100%% - %.2fem)', v) end local function bottom(v) return string.format('calc(100%% - %.2fem)', v) end pts[#pts+1] = '0% 0%' pts[#pts+1] = '100% 0%' pts[#pts+1] = '100% 100%' pts[#pts+1] = '0% 100%' pts[#pts+1] = '0% 0%' pts[#pts+1] = em(L[1]) .. ' ' .. em(T[1]) for i = 2, n do pts[#pts+1] = em(L[i]) .. ' ' .. pct((i-1)*100/(n-1)) end for i = 1, n do pts[#pts+1] = pct((i-1)*100/(n-1)) .. ' ' .. bottom(B[i]) end for i = n, 1, -1 do pts[#pts+1] = right(R[i]) .. ' ' .. pct((i-1)*100/(n-1)) end for i = n, 1, -1 do pts[#pts+1] = pct((i-1)*100/(n-1)) .. ' ' .. em(T[i]) end pts[#pts+1] = em(L[1]) .. ' ' .. em(T[1]) return '<span class="limbo-paper-charring" style="clip-path:polygon(' .. table.concat(pts, ',') .. ')"></span>' end function p.charstyle(frame) local h = instSeed(frame) local function v(seed, lo, hi) return lo + (mix(h, seed) % (hi-lo+1)) end return string.format('style="background-position:%d%% %d%%,%d%% %d%%;background-size:%d%% %d%%,%d%% %d%%"', v(1,8,62), v(2,8,62), v(3,42,82), v(4,48,86), v(5,48,70), v(6,26,42), v(7,28,46), v(8,16,28)) end function p.edge(frame) local kind = trim(frame.args[1] or '') local h = instSeed(frame) local ampT, ampS if kind == '撕边' then ampT, ampS = 0.16, 0.06 else ampT, ampS = 0.14, 0.07 end local per = 26 local pts = {} local function rnd(salt, amp) return amp * ((mix(h+salt, 11) % 1000)/1000.0) end local function p(v) return string.format('%.1f%%', v) end local function e(v) return string.format('%.2fem', v) end local function topEdge(salt) return e(0.01 + rnd(salt, ampT)) end local function bottomEdge(salt) return 'calc(100% - '..e(0.01 + rnd(salt, ampT))..')' end local function leftEdge(salt) return e(0.01 + rnd(salt, ampS)) end local function rightEdge(salt) return 'calc(100% - '..e(0.01 + rnd(salt, ampS))..')' end for i = 0, per do pts[#pts+1] = p(i*100/per)..' '..topEdge(i*3+1) end for i = 1, per do pts[#pts+1] = rightEdge(i*3+2)..' '..p(i*100/per) end for i = 1, per do pts[#pts+1] = p(100 - i*100/per)..' '..bottomEdge(i*3+3) end for i = 1, per do pts[#pts+1] = leftEdge(i*3+4)..' '..p(100 - i*100/per) end return 'clip-path:polygon('..table.concat(pts,',')..');' end return p
此页面嵌入的页面:
模块:纸张/doc
(
查看源代码
)
返回
模块:纸张
。
导航
导航
首页
最近更改
随机页面
操作申请
帮助
入门指南
编辑指南
写作指南
随机
官方
碎数研
谜题保管所
wiki工具
wiki工具
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志