Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created February 20, 2016 20:50
Show Gist options
  • Save enjalot/7e1206395f4aad86b8f5 to your computer and use it in GitHub Desktop.
Save enjalot/7e1206395f4aad86b8f5 to your computer and use it in GitHub Desktop.
{
"userId": "enjalot",
"description": "custom ease",
"created_at": "2015-11-20T17:19:45Z",
"updated_at": "2015-11-26T06:24:48Z",
"api": [
"d3.select",
"d3.scale.linear",
"d3.svg.line",
"d3.behavior.drag",
"d3.mouse",
"d3.svg.axis"
],
"colors": [
"#eaf4fa",
"#eafaf2",
"#ff8e9d",
"#111111",
"#ffffff",
"#333333",
"#331122",
"#eeffee"
],
"readme": "Draw a custom easing function in the white box on the left by clicking and dragging on it. When you let go the shapes on the right will be animated by converting the drawn path into an easing function with [mojs](http://mojs.io/tutorials/easing/path-easing/) and transitioned with [d3.js](https://github.com/mbostock/d3/wiki/Transitions#ease)\n\nBuilt with [blockbuilder.org](http://blockbuilder.org)",
"code": "<!DOCTYPE html>\n<head>\n <meta charset=\"utf-8\">\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js\"></script>\n \n <style>\n body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }\n #ease { \n position: absolute;\n top: 50px;\n left: 50px;\n width: 400px; height: 400px; \n background-color: #eaf4fa;\n }\n #ease .container {\n cursor: pointer;\n }\n #anim { \n position: absolute;\n top: 50px;\n left: 520px;\n width: 400px; height: 400px; \n background-color: #eafaf2;\n cursor: pointer;\n }\n \n \n path.ease {\n fill: none;\n stroke: #ff8e9d;\n stroke-width: 5;\n pointer-events: none;\n }\n .yaxis {\n pointer-events: none;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -khtml-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n }\n .yaxis path {\n fill: none;\n stroke: #111;\n \n }\n </style>\n</head>\n\n<body>\n <script src=\"http://cdn.jsdelivr.net/mojs/latest/mo.min.js\"></script>\n <svg id=\"ease\"></svg>\n <svg id=\"anim\"></svg>\n <script>\n var easesvg = d3.select(\"#ease\");\n var easeWidth = 400;\n var easeHeight = 400;\n var animsvg = d3.select(\"#anim\");\n \n var ey0 = 50;\n var ey1 = 350;\n var ex0 = 50;\n var ex1 = 300;\n var easeYscale = d3.scale.linear()\n .range([ey1, ey0])\n var easeXscale = d3.scale.linear()\n .range([0, ex1])\n \n var moEaseXScale = d3.scale.linear()\n .range([0, 100])\n var moEaseYScale = d3.scale.linear()\n //.domain([ey1, ey0])\n .range([0, 100])\n \n var line = d3.svg.line()\n .x(function(d) { return easeXscale(d.x) })\n .y(function(d) { return ey1 - easeYscale(d.y) })\n .interpolate(\"linear\")\n var lineEase = d3.svg.line()\n .x(function(d) { return moEaseXScale(d.x) })\n .y(function(d) { return moEaseYScale(d.y) })\n .interpolate(\"linear\")\n \n var points = [];\n var drag = d3.behavior.drag()\n .on(\"dragstart\", function() {\n points = [{\n x: 0,\n y: 1\n }]\n })\n .on(\"drag\", function() {\n var x = (d3.mouse(this)[0]-ex0)/ex1;\n var pm1 = points[points.length-1];\n if(x < pm1.x) x = pm1.x+1;\n if(x > 1) return;\n var point = {\n x: x,\n y: (d3.mouse(this)[1]-ey0/2)/ey1\n }\n // TODO smooth?\n points.push(point)\n update();\n })\n .on(\"dragend\", function() {\n var pm1 = points[points.length-1];\n if(pm1.x < 1) {\n points.push({\n x: 1,\n y: pm1.y\n })\n }\n update();\n animate()\n })\n \n var yg = easesvg.append(\"g\")\n \t.classed(\"yaxis\", true)\n .attr(\"transform\", \"translate(50,0)\")\n var axis = d3.svg.axis()\n .scale(easeYscale)\n .orient(\"left\")\n .tickValues([0, 1])\n yg.call(axis);\n \n var easecontainer = easesvg.append(\"rect\").classed(\"container\", true)\n .attr({\n x: ex0,\n y: ey0,\n width: ex1,\n height: ey1-ey0,\n \"fill-opacity\": 0.5,\n \"fill\": \"#fff\"\n })\n \n var path = easesvg.append(\"path\")\n \t.classed(\"ease\", true)\n .attr(\"transform\", \"translate(\" + [ex0, ey0] + \")\");\n \n function update() {\n path.datum(points)\n .attr(\"d\", line)\n }\n \n var rectStart = {\n x: 50, y: ey1 - 25,\n width: 50, height: 50,\n fill: \"#333\"\n }\n var rectEnd = {\n x: 50, y: ey0 - 25,\n width: 50, height: 50\n }\n var circleStart = {\n cx: 200,cy: 200, r: 5,\n fill: \"#312\"\n }\n var circleEnd = {\n cx: 200,cy: 200, r: 50,\n fill: \"#efe\"\n }\n var rect = animsvg.append(\"rect\")\n .attr(rectStart)\n var circle = animsvg.append(\"circle\")\n .attr(circleStart);\n \n var easeLine = easesvg.append(\"line\")\n .attr({\n x1: ex0, y1: ey0,\n x2: ex0, y2: ey1,\n stroke: \"#111\"\n })\n\n var duration = 1500;\n var endDuration = 1000;\n \n function animate() {\n //we pass the svg line string to the mojs easing function creator\n var ease = mojs.easing.path(lineEase(points));\n \n console.log(\"0, 0.5, 1: \", ease(0), ease(0.5), ease(1))\n \n \n rect.transition()\n .duration(duration)\n \t.ease(ease)\n \t.attr(rectEnd)\n .transition()\n .duration(endDuration)\n //.ease(\"linear\")\n .ease(ease)\n .attr(rectStart)\n \n circle.transition()\n .duration(duration)\n \t.ease(ease)\n \t.attr(circleEnd)\n .transition()\n .duration(endDuration)\n //.ease(\"linear\")\n .ease(ease)\n .attr(circleStart)\n \n easeLine.transition()\n .duration(duration)\n .ease(\"linear\")\n .attr({\n x1: ex1+ex0, x2: ex1+ex0\n })\n .transition()\n .duration(endDuration)\n .ease(\"linear\")\n .attr({\n x1: ex0, x2: ex0\n })\n \n }\n animsvg.on(\"click\", animate);\n easecontainer.call(drag)\n \n </script>\n</body>\n",
"filenames": [
"README.md",
"index.html",
"thumbnail.png"
],
"thumb": "b647171ecc011aeb4d5501bbfde2543fb810ee0a"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment