Created
January 9, 2019 11:49
-
-
Save strangerintheq/8665a7e7f3e8bc824c190b372acc2e3c to your computer and use it in GitHub Desktop.
drag toys on tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<body style="margin: 0"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> | |
<style> | |
.text-effect { | |
overflow: hidden; | |
position: absolute; | |
width: 620px; | |
margin-left: calc(50vw - 310px); | |
top: calc(50vh - 300px); | |
-webkit-filter: contrast(110%) brightness(190%); | |
filter: contrast(110%) brightness(190%); | |
} | |
.neon { | |
position: relative; | |
background: black; | |
color: transparent; | |
width: 100%; | |
text-align: center; | |
} | |
.neon::before, .neon::after { | |
content: attr(data-text); | |
color: white; | |
-webkit-filter: blur(0.02em); | |
filter: blur(0.02em); | |
position: absolute; | |
top: 0; | |
left: 0; | |
pointer-events: none; | |
} | |
.neon::after { | |
mix-blend-mode: difference; | |
} | |
.gradient, .spotlight { | |
position: absolute; | |
top: 0; | |
left: 0; | |
bottom: 0; | |
right: 0; | |
pointer-events: none; | |
z-index: 10; | |
} | |
.gradient { | |
background: linear-gradient(45deg, #f9ff09, #ff00f9); | |
mix-blend-mode: multiply; | |
} | |
.spotlight { | |
-webkit-animation: light 5s infinite linear; | |
animation: light 5s infinite linear; | |
background: radial-gradient(circle, white, transparent 25%) 0 0/25% 25%, | |
radial-gradient(circle, white, black 25%) 50% 50%/12.5% 12.5%; | |
top: -100%; | |
left: -100%; | |
mix-blend-mode: color-dodge; | |
} | |
@-webkit-keyframes light { | |
100% { | |
-webkit-transform: translate3d(50%, 50%, 0); | |
transform: translate3d(50%, 50%, 0); | |
} | |
} | |
@keyframes light { | |
100% { | |
-webkit-transform: translate3d(50%, 50%, 0); | |
transform: translate3d(50%, 50%, 0); | |
} | |
} | |
.neon { | |
font: 700 220px sans-serif; | |
text-transform: uppercase; | |
text-align: center; | |
margin: 0; | |
} | |
.neon:focus { | |
outline: none; | |
} | |
</style> | |
<div class="text-effect" style="display: none; position: fixed; mix-blend-mode: lighten;"> | |
<h1 class="neon" data-text="20 19" contenteditable>20 19</h1> | |
<div class="gradient"></div> | |
<div class="spotlight"></div> | |
</div> | |
<script> | |
var w = 800, h = 600; | |
var c = [w / 2, h / 2 + 100]; | |
var svg = appendSvg(); | |
var defs = svg.append('defs'); | |
filter_smoothMin('smin'); | |
filter_3d('3d'); | |
hills(); | |
tree(); | |
toys(); | |
snow(); | |
function snow() { | |
var snowFlakes = svg.append('g') | |
.style('filter', 'url(#smin)') | |
.selectAll('.snowflake') | |
.data(d3.range(100).map(function () { | |
return Math.random() * h | |
})) | |
.enter() | |
.append('circle') | |
.classed('.snowflake', true) | |
.attr('fill', 'snow') | |
.attr('cy', function (d) { | |
return d; | |
}) | |
.each(function (d) { | |
animate(d3.select(this), (1000 + Math.random() * 2000) * (h - d) / h) | |
}); | |
setInterval(loopAnimation, 100); | |
function loopAnimation() { | |
snowFlakes.filter(function () { | |
var y = +d3.select(this).attr('cy'); | |
return y >= 600 || !y; | |
}).attr('cy', -30).each(function () { | |
animate(d3.select(this), 1000 + Math.random() * 2000); | |
}) | |
} | |
function animate(selection, t) { | |
selection | |
.attr('cx', function (d) { | |
return Math.random() * w; | |
}) | |
.attr('r', function () { | |
return 3 + Math.random() * 3; | |
}) | |
.transition() | |
.duration(t) | |
.ease(d3.easeLinear) | |
.attr('cx', function (d) { | |
return +selection.attr('cx') + | |
Math.random() * 100 * Math.sign(Math.random() - 0.5); | |
}) | |
.attr('cy', h); | |
} | |
} | |
function hills() { | |
svg.append('g') | |
.style('filter', 'url(#smin)') | |
.selectAll('circle') | |
.data(d3.range(0, 10).map(function (i) { | |
return 1500 - i * 100 + h / 2; | |
})) | |
.enter() | |
.append('circle') | |
.attr('cx', function (d) { | |
return w * 2 * Math.random() - w; | |
}) | |
.attr('cy', function (d) { | |
return d + h / 2; | |
}) | |
.attr('r', function (d) { | |
return d; | |
}) | |
.attr('fill', '#f2f2f2') | |
.attr('stroke-width', '1') | |
.attr('stroke', 'steelblue') | |
} | |
function tree() { | |
bark(); | |
level(0); | |
level(1); | |
level(2); | |
function bark() { | |
svg.append('path') | |
.attr('d', m(20, 40) + l(20, 70) + l(0, 80) + l(0, 50)) | |
.attr('fill', '#5B3413'); | |
svg.append('path') | |
.attr('d', m(-20, 40) + l(-20, 70) + l(0, 80) + l(0, 50)) | |
.attr('fill', 'brown'); | |
} | |
function level(i) { | |
var s = 100 - i * 20; | |
var g = svg.append('g') | |
.style('filter', 'url(#smin)'); | |
path(m(0, s / 2) + l(-s, 0) + l(0, -s * 2)) | |
.attr('fill', 'lightgreen'); | |
path(m(0, s / 2) + l(s, 0) + l(0, -s * 2)) | |
.attr('fill', 'green'); | |
path(m(s, 0) + l(0, s / 2) + l(-s, 0)).attr('stroke', 'white') | |
.attr("fill", "none") | |
.attr('stroke-linejoin', 'round') | |
.attr('stroke-linecap', 'round') | |
.attr('stroke-width', '12'); | |
function path(d) { | |
return g.append('path') | |
.attr('transform', 'translate(0 ' + (-i * 100) + ') ') | |
.attr('d', d); | |
} | |
} | |
} | |
function toys() { | |
var color = d3.scaleOrdinal(d3.schemeCategory10); | |
var toys = d3.range(0, 9).map(function (i) { | |
return { | |
x: 50 + Math.random() * (w - 100), | |
y: h - 125 + Math.random() * 100, | |
shape: i % d3.symbols.length, | |
color: color(Math.random() * 10), | |
angle: Math.random() * 360 | |
} | |
}); | |
var symbols = svg.append('g') | |
.classed('toys', true) | |
.style('filter', 'url(#3d)') | |
.selectAll('.symbol') | |
.data(toys) | |
.enter() | |
.append('path') | |
.classed('symbol', true) | |
.attr('cursor', 'pointer') | |
.attr('transform', translate) | |
.attr('stroke', 'black') | |
.attr('stroke-width', '0') | |
.attr('fill', "gray") | |
.attr('d', d3.symbol().size(function () { | |
return 512 + Math.random() * 512; | |
}).type(function (d, i) { | |
return d3.symbols[i % d3.symbols.length]; | |
})) | |
.each(dragged) | |
.call(d3.drag() | |
.on("start", dragstarted) | |
.on("drag", dragged) | |
.on("end", dragended)); | |
function dragstarted(d) { | |
d3.select(this) | |
.classed('active', true) | |
.raise() | |
.attr("transform", translate) | |
.attr("stroke-width", 2); | |
} | |
function dragged(d) { | |
if (d3.event) { | |
d.x = d3.event.x; | |
d.y = d3.event.y; | |
} | |
d3.select(this) | |
.attr("transform", translate) | |
.attr("fill", check(d) ? d.color : "gray"); | |
} | |
function translate(d) { | |
var scale = d3.select(this).classed('active') ? " scale(1.3)" : ""; | |
return "rotate(" + d.angle + " " + d.x + " " + d.y + ") " + | |
"translate(" + d.x + "," + d.y + ")" + scale; | |
} | |
function dragended() { | |
d3.select(this) | |
.classed('active', false) | |
.attr("transform", translate) | |
.attr("stroke-width", 0); | |
var left = []; | |
symbols.filter(function (d) { | |
!check(d) && left.push(d); | |
}); | |
repeat(left.length) | |
} | |
function repeat(stop) { | |
d3.select('.text-effect').style('display', stop ? 'none' : 'block') | |
var transition = symbols.transition() | |
.attr("fill", function (d) { | |
return check(d) ? d.color : "gray" | |
}); | |
if (stop) | |
return; | |
transition | |
.attr('fill', function () { | |
return color(Math.random() * 10); | |
}) | |
.ease(d3.easeLinear) | |
.duration(1000) | |
.attr('fill', function () { | |
return color(Math.random() * 10); | |
}) | |
.on('end', function () { | |
repeat(false) | |
}) | |
} | |
function check(d) { | |
return d.x < 500 && d.x > 300 && d.y < 450 && d.y > 75; | |
} | |
} | |
function l(x, y) { | |
return "L" + p(x, y) | |
} | |
function m(x, y) { | |
return "M" + p(x, y) | |
} | |
function p(x, y) { | |
return (c[0] + x) + "," + (c[1] + y) + " "; | |
} | |
function filter_smoothMin(id) { | |
// https://tympanus.net/codrops/2015/03/10/creative-gooey-effects/ | |
var filter = defs.append('filter') | |
.attr('id', id); | |
filter.append('feGaussianBlur') | |
.attr('in', 'SourceGraphic') | |
.attr('stdDeviation', '3') | |
//to fix safari: http://stackoverflow.com/questions/24295043/svg-gaussian-blur-in-safari-unexpectedly-lightens-image | |
.attr('color-interpolation-filters', 'sRGB') | |
.attr('result', 'blur'); | |
filter.append('feColorMatrix') | |
.attr('in', 'blur') | |
.attr('mode', 'matrix') | |
.attr('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9') | |
} | |
function filter_3d(id) { | |
// https://www.w3.org/TR/SVGFilterPrimer12/ | |
var filter = defs.append('filter') | |
.attr('id', id) | |
.attr('filterUnits', 'userSpaceOnUse') | |
.attr('x', 0) | |
.attr('y', 0) | |
.attr('width', w) | |
.attr('height', h); | |
filter.append('feGaussianBlur') | |
.attr('in', 'SourceAlpha') | |
.attr('stdDeviation', 4) | |
.attr('result', "blur"); | |
filter.append('feSpecularLighting') | |
.attr('in', 'blur') | |
.attr('surfaceScale', 5) | |
.attr('specularConstant', .75) | |
.attr('specularExponent', 20) | |
.attr('lighting-color', "#bbbbbb") | |
.attr('result', "specOut") | |
.append('fePointLight') | |
.attr('x', -5000) | |
.attr('y', -10000) | |
.attr('z', 20000); | |
filter.append('feComposite') | |
.attr('in', 'specOut') | |
.attr('in2', 'SourceAlpha') | |
.attr('operator', 'in') | |
.attr('result', "specOut"); | |
filter.append('feComposite') | |
.attr('in', 'SourceGraphic') | |
.attr('in2', 'specOut') | |
.attr('operator', 'arithmetic') | |
.attr('k1', 0) | |
.attr('k2', 1) | |
.attr('k3', 1) | |
.attr('k4', 0) | |
.attr('result', "litPaint"); | |
} | |
function appendSvg() { | |
return d3.select('body').append('svg') | |
.style('margin-left', 'calc(50vw - ' + w / 2 + 'px)') | |
.style('margin-top', 'calc(50vh - ' + h / 2 + 'px)') | |
.style('background-color', 'steelblue') | |
.attr('width', w).attr('height', h) | |
.attr('viewBox', '0 0 ' + w + ' ' + h) | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment