Skip to content

Instantly share code, notes, and snippets.

@strangerintheq
Created January 9, 2019 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save strangerintheq/8665a7e7f3e8bc824c190b372acc2e3c to your computer and use it in GitHub Desktop.
Save strangerintheq/8665a7e7f3e8bc824c190b372acc2e3c to your computer and use it in GitHub Desktop.
drag toys on tree
<!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&nbsp;&nbsp;19" contenteditable>20&nbsp;&nbsp;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