version = 1 title = 'icicle fall (9/9)' [[modules]] plugin = 'source.svelte' data.contents = ''' use your mouse to dodge(?) the bullets! (click to play!)
Ice Sign "Icicle Fall"
{#each {length: 4} as _, i}
{/each}
{#each "lr" as dir} {#each {length: 22} as _, i}
{#each {length: 3} as _, j}
{/each}
{/each} {/each}
uh-oh! your browser doesn't support (piecewise) linear easing functions yet! (or you have prefers-reduced-motion turned on)
if you're on safari, try safari technology preview 176+
''' sends = [3] graphPos = [-384, -48] [[modules]] plugin = 'source.text' data.contents = '''
misc notes and ramblings
* love too frame-advance 60fps recordings of touhou and count animation frames * the scrolling background is svg noise :3 * what even are the square things that fly around bosses * making this responsive is too much effort... you can try zooming i guess * spellcard tidbits: * on about 12 seconds left on the timer, cirno shoots lines of 4 bullets instead of 3 * the bullets on the right half are slightly faster than the ones on the left half once they turn: this makes a nice interlacing effect when the bullets meet * on the normal version, cirno shoots yellow bullets more frequently the closer you are to her * opacity effects use svg animations * i had a horrendous hack involving the `feColorMatrix` svg filter, the `filter` css property, and [this trick](https://cohost.org/oatmealine/post/310029-tutorial-cool-custo) to get smooth fading that worked over any background, but [webkit didn't like applying a filter from a data url](https://bugs.webkit.org/show_bug.cgi?id=104169) * i think uploading the svg and using that url would have worked, but i might as well add the effect directly to the svg to save you the cpu usage - it's morally the same as using an animated image anyways * also the trick only worked for all dark colors (`alpha = 1-(r+g+b)/3`, overlay with white to fade out) or all light colors (`alpha = (r+g+b)/3`, overlay with black to fade out) * i tried combining two filters to make it work with all colors (`b,alpha = 1-alpha,b`, overlay with blue to fade out, `b,alpha = alpha,1-b`), but it messed with the colors/alpha a bit
prechoster source
https://gist.github.com/ubuntor/664c617b91a6c5ce76e1acc9e797a0fa
''' data.language = 'html' sends = [3] graphPos = [-384, 48] [[modules]] plugin = 'source.lesscss' data.contents = ''' .clickthrough { position:relative; display:flex; flex-shrink:0; justify-content: center; align-items: center; width:100%; height:418px; } .clickthroughsummary { font-size:0; position:absolute; inset:0; width:100%; height:100%; cursor: pointer; } .clickthroughicon { position:absolute; height:100%; width:100%; background-position:center; background-repeat:no-repeat; background-image: url(@clickthrough); } .container { display: grid; place-items: center; height: 418px; } .game { background: linear-gradient(to right, #2a052e, #281e0c, #240034 33%, #170060, #0e0057); width: 384px; height: 418px; box-shadow: 0px 0px 0px 2px #252536; border-radius: 2px; overflow: hidden; position: absolute; cursor: url(@eggbug), auto; transform-style: preserve-3d; } .spellcard_name { color: white; position: absolute; text-align: right; right: 20px; top: 10px; background: linear-gradient(#3e32abaa, #050060aa); } .weirdsquares { transform-style: preserve-3d; perspective: 300px; background: url(@weirdsquare); } .weirdrot0 { transform-style: preserve-3d; background: inherit; transform: rotate(110deg); } .weirdrot1 { transform-style: preserve-3d; background: inherit; transform: rotate(105deg); } .weirdrot2 { transform-style: preserve-3d; background: inherit; transform: rotate(115deg); } .weirdrot3 { transform-style: preserve-3d; background: inherit; transform: rotate(170deg); } each(range(0,3), .(@i) { .weirdx@{i} { transform-style: preserve-3d; background: inherit; transform: translateX(60px); animation: 1.66s (-1.66s + 0.15s*@i) spin linear(0.0 0%, 0.19 10%, 0.69 20%, 1.31 30%, 1.81 40%, 2.0 50%, 1.81 60%, 1.31 70%, 0.69 80%, 0.19 90%, 0.0 100%) infinite; } .weirdz@{i} { transform-style: preserve-3d; background: inherit; transform: translateZ(80px); animation: 1.66s (-1.245s + 0.15s*@i) spin linear(0.0 0%, 0.19 10%, 0.69 20%, 1.31 30%, 1.81 40%, 2.0 50%, 1.81 60%, 1.31 70%, 0.69 80%, 0.19 90%, 0.0 100%) infinite; } }); .weirdrotinner { transform-style: preserve-3d; background: inherit; animation: 0.7s spin linear infinite; } .weirdsquare { transform-style: preserve-3d; position: absolute; background: inherit; width: 14px; height: 14px; transform: translate3d(-50%,-50%,0px); } .background_noise { background: url(@noise); width: 100%; height: 200%; position: absolute; animation: 12s spin linear infinite reverse; transform: translateY(-50%); } .enemy { width:34px; height:36px; perspective: 200px; position:absolute; background: url(@cirneggbug); transform: translate3d(-50%,-50%,0px); } .bullets { position: absolute; background: url(@bullet); left: 192px; top: 96px; } each(range(0,21), .(@i) { .rotl@{i} { transform: rotate((-170.15625deg - 5.625deg*mod(@i,11))); background: inherit; } .rotr@{i} { transform: rotate((-9.84375deg + 5.625deg*mod(@i,11))); background: inherit; } .rotl_inner@{i} { transform: rotate(-90deg); animation: spin 9.9s (-9.9s + 0.45s*@i) linear(1 0%, 1 12.6%, 0 12.6%, 0 100%) infinite; background: inherit; } .rotr_inner@{i} { transform: rotate(90deg); animation: spin 9.9s (-9.9s + 0.45s*@i) linear(1 0%, 1 12.6%, 0 12.6%, 0 100%) infinite; background: inherit; } each(range(0,2), .(@j) { .movelx@{i}_@{j} { transform: translateX((80px*(@j+1))); animation: spin 9.9s (-9.9s + 0.45s*@i) linear(1.0 0.0%, 0.79 1.4%, 0.605 2.8%, 0.444 4.2%, 0.309 5.6%, 0.198 7.0%, 0.111 8.4%, 0.049 9.8%, 0.012 11.2%, 0 12.6%, 0 12.6%) infinite; background: inherit; } .moverx@{i}_@{j} { transform: translateX((80px*(@j+1))); animation: spin 9.9s (-9.9s + 0.45s*@i) linear(1.0 0.0%, 0.79 1.4%, 0.605 2.8%, 0.444 4.2%, 0.309 5.6%, 0.198 7.0%, 0.111 8.4%, 0.049 9.8%, 0.012 11.2%, 0 12.6%, 0 12.6%) infinite; background: inherit; } }); .movely@{i} { transform: translateY(-726.6px); animation: spin 9.9s (-9.9s + 0.45s*@i) linear(1 0%, 1 12.6%, 0 100%) infinite; background: inherit; } .movery@{i} { transform: translateY(830.4px); animation: spin 9.9s (-9.9s + 0.45s*@i) linear(1 0%, 1 12.6%, 0 100%) infinite; background: inherit; } }); .bullet { position: absolute; background: inherit; width:16px; height:8px; transform: translate(-50%,-50%); } .linear-warning { position: absolute; transform: translateX(1px); animation: 0s linear(0,10000) 0s forwards spin; text-align: center; background: rgb(255,196,20); border-radius: 10px; border: 1px solid black; padding: 5px; color: black; } .code { font-family: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,liberation mono,courier new,monospace; font-weight: 600; font-size: .875em; } .misc { border-radius: 0.375rem; padding: 0.5em; border: 1px solid #aaa; margin-top: 1em; } .misc-inner { border-top: 1px solid #aaa; }''' sends = [3] graphPos = [-384, 96] [[modules]] plugin = 'transform.style-inliner' data.mode = 'attr' sends = ['output'] [[modules]] plugin = 'source.text' data.contents = ''' ''' data.language = 'html' sends = [5] title = 'SVG: noise' [[modules]] plugin = 'transform.svgo' data = { } sends = [6] [[modules]] plugin = 'transform.to-data-url' data.mime = 'image/svg+xml' namedSends = { '2' = ['noise'] } [[modules]] plugin = 'source.text' data.contents = '' data.language = 'html' sends = [8] title = 'SVG: bullet' [[modules]] plugin = 'transform.svgo' data = { } sends = [9] [[modules]] plugin = 'transform.to-data-url' data.mime = 'image/svg+xml' namedSends = { '2' = ['bullet'] } [[modules]] plugin = 'source.text' data.contents = ''' ''' data.language = 'html' sends = [11] title = 'SVG: cirneggbug' [[modules]] plugin = 'transform.svgo' data = { } sends = [12] [[modules]] plugin = 'transform.to-data-url' data.mime = 'image/svg+xml' namedSends = { '2' = ['cirneggbug'] } [[modules]] plugin = 'source.file-data-url' data.url = 'data:image/png;base64,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' namedSends = { '2' = ['eggbug'] } [[modules]] plugin = 'source.text' data.contents = ''' ''' data.language = 'html' sends = [15] title = 'SVG: weirdsquare' [[modules]] plugin = 'transform.svgo' data = { } sends = [16] [[modules]] plugin = 'transform.to-data-url' data.mime = 'image/svg+xml' namedSends = { '2' = ['weirdsquare'] } [[modules]] plugin = 'source.text' data.contents = '' data.language = 'html' sends = [18] title = 'SVG: clickthrough' [[modules]] plugin = 'transform.svgo' data = { } sends = [19] [[modules]] plugin = 'transform.to-data-url' data.mime = 'image/svg+xml' namedSends = { '2' = ['clickthrough'] }