name:
The Perfect NFT - NFT Renderer
project description:
The Perfect NFT is blockchain art performance by and for you. You’re invited to leave your mark. Every composition is derived from a number between 0
and 511
, represented as a binary value.
storage type:
on-chain (modular)
asset name:
renderer
policy id:
51211110add284b78cff66364ea4997f8612b91ee07d8a2339d7cb0b
fingerprint:
asset147hpzhrjcjgk7tsuu9q45h5ctcc5eusgn7qejm
transaction hash:
35ceb9fbb8773b853e433fd0811dd03e90a3e1d00a882b005a5904553bd52c2e
block hash:
d0b8296ec3a8bcf1ed386c28a6f294898f42d24db38b2dd7d6b4da7258837fe4
minted at:
2023-03-05 19:07:07 (3 months ago)
minted in epoch/slot:
397/337876
minted in block number:
8479377
block size:
81385 bytes
dependencies[000].fingerprint:
asset1puem2t253x27nu3tuqvah8h377fv2xcu04xa4n
dependencies[000].type:
internal
dependencies[001].fingerprint:
asset1cqshmlqnh8ghzv20qm453qyf46vn6ur5ef03zs
dependencies[001].type:
internal
files[000].mediaType:
text/html
files[000].name:
renderer.html
files[000].src:
<main><div id='nft'></div></main>
files[001].mediaType:
text/css
files[001].name:
renderer.css
files[001].src:
body {user-select:none;display:flex;flex-direction:column;}main {display:flex;align-items:center;justify-content:center;flex-gro w:100;}#nft {max-width:94%;max-height:100vh;}#nft svg {display:b lock;width:auto;height:94vh;max-width:100%;}
files[002].license:
CC BY-NC-SA 4.0
files[002].mediaType:
application/javascript
files[002].name:
renderer.js
files[002].src:
/* The Perfect NFT - License: CC BY-NC-SA 4.0 - Author: Wout Fie rens */ function NFT(e,t,n,r){const o=Random.prng(t+512*n),i='#404040',s =1024,g=[-25,25],a=[-.07,.07],c=1024,l=[-100,-100,1224,1224],d=( e,t,n,r)=>{Svg.circle(e,{r:.75*r,cx:t+r,cy:n-r})},f=(e,t,n,i,s)= >{const c=s/2,l=Svg.g(e,{transform:SvgTransform({rotate:[Random. between(...g,o),n+c,i-c],translate:[Random.between(...a,o)*s+(n+ c),Random.between(...a,o)*s+(i-c)]})}),d=fingerprint(l,r[t],'#9d 192e');Svg.at(d,{width:s,height:s,x:-c,y:-c})},v=Svg.doc(c,s,e,{ viewBox:l.join(' ')});return Svg.desc(v).textContent=`number: ${ t}; round: ${n};`,(e=>{Svg.rect(e,{fill:'#f4f0e8',stroke:'none', x:l[0],y:l[1],width:l[2],height:l[3]},!0)})(v),(e=>{Svg.text(e,{ fontSize:36,fontFamily:`cutivemonoregular, 'Cutive Mono', monosp ace`,textAnchor:'middle',fill:i,x:512,y:1070.08}).textContent=t. toString(2)})(v),(e=>{const n=Svg.g(e,{id:'placeholders',fill:'n one',stroke:i,strokeDasharray:'0 9.81px',strokeWidth:5,strokeLin ecap:'round',strokeOpacity:.33}),o=Svg.g(e,{id:'fingerprints'}), g=t.toString(2).split('').reverse(),a=t<2?1:t<16?2:3,c=s/a,l=g.f ilter((e=>0!=e)).length;let v=0;r=[...r].reverse().slice(0,l).re verse(),g.forEach(((e,t)=>{if('1'!=e)return;const[i,g]=[c*(t%a), -c*Math.floor(t/a)+s];d(n,i,g,c/2),r[v]&&f(o,v++,i,g,c)}))})(v), v} function fingerprint(r,e,o){const a=Random.sfc32FromHash(e.repla ce(/^addr(_test)?/,'')),t=Random.fromRange(15,19,a),n=[350,750], s=[3,21],l=Matrix.build(2,2,(()=>5*a())),c=640,i=Math.round(1e4* a()),h=Random.fromWeightedList([['plain arch',5],['tented arch', 3],['ulnar loop',60],['radial loop',5],['plain whorl',27]],a),u= 640,p=r=>{const[e,o,a,t]=v('plain arch');m(r,C(e)),g(r,e,o),m(r, C(o)),g(r,o,a),m(r,C(a)),g(r,a,t),m(r,C(t))},d=r=>{const e=a()>. 5,o=v('tented arch').map((r=>e?F(r):r)),[t,n,s,l,c]=o;m(r,C(t)), g(r,t,n),m(r,C(n)),s.forEach((e=>m(r,C(e)))),m(r,C(l)),g(r,l,c), m(r,C(c))},f=(r,e)=>{const o=v((e?'radial':'ulnar')+' loop'),[a, t,n,s,l,c,i,h,u]=o;m(r,C(a)),g(r,a,t,!1),m(r,C(t)),m(r,C(n)),g(r ,n,s),m(r,C(s)),m(r,C(l)),m(r,C(c)),m(r,C(i)),g(r,i,h,!1),m(r,C( h)),u.forEach((e=>m(r,C(e))))},S=r=>{const e=v('plain whorl'),[o ,a,t,n,s,l,c,i]=e;m(r,C(o)),g(r,o,a,!1),m(r,C(a)),m(r,C(t,!0)),g (r,t,n,!0),m(r,C(n,!0)),m(r,C(s)),g(r,s,l,!1),m(r,C(l)),c.forEac h((e=>m(r,C(e)))),i.forEach((e=>m(r,C(e))))},g=(r,e,o,a)=>{const t=k(e,o);Utils.times(t-1,(n=>Svg.el('path',r,{d:C(Points.blend( e,o,(n+1)/t),a),strokeDashoffset:B()})))},m=(r,e)=>Svg.el('path' ,r,{d:e,strokeDashoffset:B()}),w=(r,e,o)=>{const a=Svg.filter(L, {id:b(`${r}Filter`)});return Svg.el('feTurbulence',a,{type:'turb ulence',baseFrequency:e,numOctaves:2,result:'turbulence',seed:i} ),Svg.el('feDisplacementMap',a,{in2:'turbulence',in:'SourceGraph ic',scale:o,xChannelSelector:'R',yChannelSelector:'G'}),a},v=r=> {switch(r){case'plain arch':return[$('archRoof'),$('archShape'), $('archBase'),$('archFloor')];case'tented arch':return[A('tentAr chRoof'),A('tentArchShape'),A('tentArchFill'),$('tentArchBase'), A('tentArchFloor')];case'plain whorl':return[A('whorlRoof'),A('w horlShape'),A('whorlCoreOut'),A('whorlCoreIn'),A('whorlBase'),A( 'whorlFloor'),A('whorlTriL'),A('whorlTriR')];case'ulnar loop':re turn[A('loopRoof'),A('loopShape'),A('loopOuter'),A('loopIn'),A(' loopCore'),A('loopFill'),A('loopBase'),A('loopFloor'),A('loopTri L')];case'radial loop':return v('ulnar loop').map((r=>F(r)))}},R =r=>{const e=y(r);return Array.isArray(e[0][0])?e.map((r=>Matrix .mpy(r,[u,c]))):Matrix.mpy(e,[u,c])},y=r=>{switch(r){case'archRo of':return[[-.1,.25],[.15,.2],[.5,.025],[.9,.2],[1.1,.25]];case' archShape':return[[0,.45],[.25,.4],[.5,.3],[.75,.4],[1,.45]];cas e'archBase':return[[.05,.67],[.33,.73],[.67,.73],[.95,.67]];case 'archFloor':return[[.1,.8],[.5,.975],[.9,.8]];case'tentArchRoof' :return[[-.2,.57],[0,.43],[.5,0],[1,.43],[1.2,.57]];case'tentArc hShape':return[[.056,.86],[.415,.63],[.5,.4],[.61,.65],[.96,.87] ];case'tentArchFill':return[[[.513,.46],[.59,.665],[.96,.895]],[ [.518,.49],[.527,.652],[.64,.725]],[[.535,.585],[.545,.64],[.57, .67]],[[.501,.42],[.507,.66],[.68,.765],[.96,.92]],[[.05,.89],[. 4,.68],[.475,.57]],[[.38,.715],[.45,.666],[.475,.63]],[[.445,.69 5],[.467,.68],[.485,.655]],[[.484,.69],[.495,.675]],[[.05,.915], [.36,.745],[.515,.705]]];case'tentArchBase':return[[.05,.945],[. 407,.757],[.6,.76],[.95,.94]];case'tentArchFloor':return[[.1,1.1 ],[.3,1],[.5,.96],[.7,1],[.9,1.1]];case'whorlRoof':return[[0,.5] ,[.1,.4],[.3,.07],[.7,.07],[.9,.4],[1,.5]];case'whorlShape':retu rn[[.1,.75],[.28,.64],[.4,.33],[.6,.33],[.72,.64],[.9,.75]];case 'whorlBase':return[[.1,.76],[.28,.7],[.45,.73],[.55,.73],[.72,.7 ],[.9,.76]];case'whorlFloor':return[[.2,.97],[.3,1],[.45,1.06],[ .55,1.06],[.7,1],[.8,.97]];case'whorlCoreOut':return[[.5,.71],[. 35,.63],[.41,.35],[.585,.35],[.655,.63]];case'whorlCoreIn':retur n[[.5,.52],[.49,.51],[.49,.49],[.51,.49],[.51,.51]];case'whorlTr iR':switch(Random.fromRange(0,2,a)){case 0:return[[[.675,.59],[. 673,.642],[.655,.68],[.7,.677],[.725,.678],[.715,.666],[.694,.63 5],[.687,.66]]];case 1:return[[[.676,.59],[.673,.65],[.65,.685]] ,[[.695,.635],[.69,.665],[.677,.685]],[[.712,.66],[.71,.67],[.70 3,.683]],[[.73,.68],[.728,.683]]];case 2:return[[[.735,.686],[.6 95,.64],[.676,.59]],[[.705,.682],[.689,.665],[.672,.635]],[[.678 ,.682],[.661,.662]],[[.653,.685],[.65,.681]]]}case'whorlTriL':sw itch(Random.fromRange(0,2,a)){case 0:return[[[.327,.58],[.332,.6 4],[.346,.68],[.3,.677],[.275,.678],[.288,.666],[.31,.635],[.32, .66]]];case 1:return[[[.327,.58],[.33,.64],[.355,.688]],[[.308,. 627],[.313,.66],[.327,.685]],[[.29,.66],[.291,.67],[.297,.683]], [[.27,.68],[.272,.685]]];case 2:return[[[.266,.684],[.3,.65],[.3 25,.59]],[[.3,.682],[.319,.66],[.33,.63]],[[.33,.68],[.34,.662]] ,[[.352,.682],[.356,.685]]]}case'loopRoof':return[[0,.5],[.1,.4] ,[.27,0],[.7,0],[.9,.4],[1,.5]];case'loopShape':return[[.05,.75] ,[.31,.59],[.395,.28],[.605,.28],[.72,.58],[1,.74]];case'loopOut er':return[[.9,.88],[.72,.79],[.52,.725],[.385,.61],[.41,.3],[.5 9,.3],[.7,.59],[1,.76]];case'loopIn':return[[.95,.845],[.76,.74] ,[.56,.65],[.445,.58],[.455,.36],[.545,.36],[.61,.62],[1,.83]];c ase'loopCore':return[[.575,.605],[.56,.63],[.465,.57],[.47,.38], [.53,.38],[.535,.5],[.555,.6],[.48,.55],[.48,.4],[.515,.4],[.515 ,.48],[.53,.57],[.5,.53],[.495,.4]];case'loopFill':return[[.645, .67],[.59,.636]];case'loopBase':return[[.1,.76],[.31,.66],[.44,. 712],[.55,.76],[.72,.81],[.9,.9]];case'loopFloor':return[[.2,.87 ],[.3,.92],[.45,.98],[.575,.98],[.7,.97],[.85,1.1]];case'loopTri L':switch(Random.fromRange(0,2,a)){case 0:return[[[.275,.65],[.3 3,.6],[.353,.55],[.365,.613],[.38,.643],[.344,.64],[.322,.641],[ .329,.629],[.344,.609],[.351,.623]]];case 1:return[[[.275,.65],[ .33,.6],[.356,.54]],[[.315,.645],[.352,.605],[.36,.58]],[[.35,.6 4],[.37,.615],[.37,.6]],[[.38,.65],[.38,.64]]];case 2:return[[[. 385,.652],[.33,.635],[.275,.649]],[[.37,.62],[.335,.613],[.31,.6 18]],[[.36,.595],[.345,.59],[.33,.59]],[[.36,.57],[.34,.57]],[[. 36,.55],[.35,.55]],[[.357,.53],[.355,.53]]]}}},k=(r,e)=>~~(Math. max(...r.map(((o,a)=>Point.dist(r[a],e[a]))))/t),A=r=>{const e=R (r);return Array.isArray(e[0][0])?e.map((r=>x(r))):x(e)},F=r=>Ar ray.isArray(r[0][0])?r.map((r=>F(r))):Matrix.add(Matrix.mpy(r,[- 1,1]),[u,0]),$=r=>x(SvgPath.toPoly(C(R(r)),5)),x=r=>r.map((r=>{c onst[e,o]=[1/u*r[0]*1.2,1/c*r[1]*1.2];return r[0]+=75*(2*Perlin. noise2d(l[0][0]+e,l[0][1]+o)-1),r[1]+=75*(2*Perlin.noise2d(l[1][ 0]+e,l[1][1]+o)-1),r})),M=(r,e,o)=>SvgStroke.randomDashArray(r,e ,o,a,0),B=()=>Math.round(-n[1]*a()),b=r=>`${r}-${e}`,C=SvgBezier .cubic,P=Svg.doc(u,c,r,{viewBox:`0 0 ${u} ${c}`}),L=Svg.defs(P); Svg.desc(P).textContent=`type: ${h}; address: ${e};`;const T=Svg .symbol(L,{id:b('fingerprint')}),D=(()=>{const[r,e]=[[u,c].map(( r=>r/2)),4],[o,t]=[.41*u,2*Math.PI/e],n=Utils.range(0,e-1).reduc e(((e,a)=>[...e,Point.atAngle(r,[.8*o,o],t*a)]),[]),s=Svg.el('ma sk',L,{id:b('fpMask')});return Svg.path(s,{d:C(Points.randomize( n,[.02*u,.12*c],a),!0,.28),filter:`url('#${w('mask',.06,25).id}' )`,fill:'#fff'}),s})(),O=w('erosion',.09,5),I=Svg.g(P,{mask:`url (#${D.id})`}),E=Svg.g(I,{filter:`url(#${O.id})`});return((r,e)=> {switch(r){case'plain arch':return p(e);case'tented arch':return d(e);case'plain whorl':return S(e);case'ulnar loop':return f(e) ;case'radial loop':f(e,!0)}})(h,T),((r,e)=>{const a=Svg.use(r,{f ill:'none',stroke:o,strokeDasharray:M(100,n,s),strokeLinecap:'ro und',strokeOpacity:.9,strokeWidth:8});Svg.at(a,{href:`#${e.id}`} ,Svg.xlink)})(E,T),((r,e,o)=>{const a=Svg.use(r,{fill:'none',fil ter:`url('#${o.id}')`,stroke:'#000',strokeDasharray:M(20,[1,2],[ 10,50]),strokeLinecap:'round',strokeWidth:2});Svg.at(a,{href:`#$ {e.id}`},Svg.xlink)})(D,T,O),P} function main(number, round, addresses){NFT(document.getElementB yId('nft'),number,round,addresses.map(a => a.join('')))}
image:
ipfs://QmUx21Bqoid1oLKRE33xPsohFiQmGd3yCsNcFuT2fGdzFD
mediaType:
image/png
name:
The Perfect NFT - NFT Renderer
outputType:
text/html