SOURCE

console 命令行工具 X clear

                    
>
console
var canvas = document.getElementById('curve'),
ctx = canvas.getContext('2d'),
box = document.getElementById('box'),
code = document.getElementById('codeOutput'),
supportsTouch = ('createTouch' in document),
time = document.getElementById('time'),
timeVal = 500;

var supportsBezierRange = (function() {
  var el = document.createElement('div');
  el.style.WebkitTransitionTimingFunction = 'cubic-bezier(1,0,0,1.1)';
  return !! el.style.WebkitTransitionTimingFunction.length;
})();

// bezier contructor
function BezierHandle(x, y) {
  this.x = x;
  this.y = y;
  this.width = 12;
  this.height = 12;
}

BezierHandle.prototype = {

  // get the edges for easy grabby coordinates
  getSides: function() {
    this.left = this.x - (this.width / 2);
    this.right = this.left + this.width;
    this.top = this.y - (this.height / 2);
    this.bottom = this.top + this.height;
  },

  draw: function() {
    // figure out the edges
    this.getSides();
    ctx.fillStyle = "#222";
    ctx.fillRect(this.left, this.top, this.width, this.height);
  }

};

// make 2 new handles
var handles = [new BezierHandle(50, 280), new BezierHandle(150, 180)];

function Graph() {
  this.x = 0;
  this.y = 130;
  this.height = 200;
  this.width = 200;
}

Graph.prototype = {

  draw: function() {

    ctx.save();

    ctx.fillStyle = "#fff";
    ctx.fillRect(this.x, this.y, this.width, this.height);

    // the 0.5 offset is to account for stroke width to make lines sharp
    ctx.strokeStyle = '#666';
    ctx.lineWidth = 1;
    ctx.strokeRect(this.x + 0.5, this.y - 0.5, this.width - 1, this.height);

    ctx.restore();
  }

};

var graph = new Graph();

// get the x and y pos, normalized by getOffset
function getPos(event) {
  var mouseX = event.pageX - getOffSet(event.target).left,
  mouseY = event.pageY - getOffSet(event.target).top;

  return {
    x: mouseX,
    y: mouseY
  };
}

//from quirksmode.org. Modified slightly to return obj
function getOffSet(obj) {
  var curleft = curtop = 0;
  if (obj.offsetParent) {
    do {
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    } while ( obj = obj . offsetParent );

    return {
      left: curleft,
      top: curtop
    };
  }
}

var drag = false,
draggingObj, oldX, oldY;

function onPress(event) {
  //console.log('press')
  // to get rid of text cursor
  event.preventDefault();
  event.stopPropagation(); //not sure if this is needed
  var cursorEvent = supportsTouch ? event.touches[0] : event;

  var mouseCoordinates = getPos(cursorEvent),
  x = mouseCoordinates.x,
  y = mouseCoordinates.y;

  //check to see if over any handles
  for (var i = 0; i < handles.length; i++) {
    var current = handles[i],
    curLeft = current.left,
    curRight = current.right,
    curTop = current.top,
    curBottom = current.bottom;

    //20 px padding for chubby fingers
    if (supportsTouch) {
      curLeft -= 20;
      curRight += 20;
      curTop -= 20;
      curBottom += 20;
    }

    //console.log('current.x:',current.x, 'current.y:',current.y)
    if (x >= curLeft && x <= curRight && y >= curTop && y <= curBottom) {
      //over the current handle
      //console.log('over')
      //drag = true;
      draggingObj = current;
      oldX = event.pageX;
      oldY = event.pageY;

      var currentlySelected = $('#presets option:selected');

      currentlySelected.removeAttr('selected')
        .parent().parent().find('option').last().attr('selected', 'selected');

      document.addEventListener('mouseup', onRelease, false);
      document.addEventListener('touchend', touchEnd, false);

      document.addEventListener('mousemove', onMove, false);
      document.addEventListener('touchmove', touchMove, false);

      // set move cursor
      document.body.style.cursor = canvas.style.cursor = 'move';

    }
  }

}

function onMove(event) {

  var cursorEvent = supportsTouch ? event.touches[0] : event;

  var x = cursorEvent.pageX - getOffSet(canvas).left,
  y = cursorEvent.pageY - getOffSet(canvas).top;

  if (x > graph.width) {
    x = graph.width;
  }
  if (x < 0) {
    x = 0;
  }
  if (y > canvas.height) {
    y = canvas.height;
  }
  if (y < 0) {
    y = 0;
  }

  draggingObj.x = x;
  draggingObj.y = y;

  updateDrawing();

}

function touchMove(event) {
  onMove(event);
  event.preventDefault();
}

function onRelease(event) {
  //console.log('release')
  drag = false;

  // restore pointer cursor
  canvas.style.cursor = 'pointer';
  document.body.style.cursor = 'default';

  document.removeEventListener('mousemove', onMove, false);
  document.removeEventListener('touchmove', touchMove, false);
  document.removeEventListener('mouseup', onRelease, false);
  document.removeEventListener('touchend', touchEnd, false);
}

function touchEnd(event) {
  onRelease(event);
  event.preventDefault();
}

canvas.addEventListener('mousedown', onPress, false);
canvas.addEventListener('touchstart', function touchPress(event) {
  onPress(event);
  event.preventDefault();
},
false);

function updateDrawing() {
  // clear
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // draw graph
  graph.draw();

  // get handles
  var cp1 = handles[0],
  cp2 = handles[1];

  // draw bezier curve
  ctx.save();
  ctx.strokeStyle = '#4C84D3';
  ctx.lineWidth = 3;
  ctx.beginPath();
  ctx.moveTo(graph.x, graph.y + graph.height);
  //start at bottom left, first handle is cp1, second handle is cp2, end is top right
  ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, graph.width, graph.y);
  ctx.stroke();
  ctx.restore();

  // draw anchor point lines
  ctx.strokeStyle = '#f00';
  ctx.beginPath();
  ctx.moveTo(graph.x, graph.y + graph.height);
  ctx.lineTo(cp1.x, cp1.y);
  ctx.moveTo(graph.width, graph.y);
  ctx.lineTo(cp2.x, cp2.y);
  ctx.stroke();

  // draw handles
  for (var i = 0; i < handles.length; i++) {
    handles[i].draw();
  }

  //console.log(cp1.x, cp1.y, cp2.x, cp2.y)
  // output code
  var x1 = (cp1.x / graph.width).toFixed(3),
  y1 = ((graph.height + graph.y - cp1.y) / graph.height).toFixed(3),
  x2 = (cp2.x / canvas.width).toFixed(3),
  y2 = ((graph.height + graph.y - cp2.y) / graph.height).toFixed(3),

  //console.log( cp1.x, cp1.y )
  points = '(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ')',
  bezier = 'cubic-bezier' + points,

  easeName = $('#presets option:selected').text();

  if (easeName.indexOf('custom') > -1) {
    easeName = 'custom';
  }

  var webkitTrans = '-webkit-transition: all ' + timeVal + 'ms ' + bezier;
  var webkitTiming = '-webkit-transition-timing-function: ' + bezier;

  if (y1 > 1 || y1 < 0 || y2 > 1 || y2 < 0) {

    var webkitY1 = y1,
    webkitY2 = y2;

    if (y1 > 1) webkitY1 = 1;
    if (y1 < 0) webkitY1 = 0;
    if (y2 > 1) webkitY2 = 1;
    if (y2 < 0) webkitY2 = 0;

    webkitTrans = '-webkit-transition: all ' + timeVal + 'ms ' + 'cubic-bezier(' + x1 + ', ' + webkitY1 + ', ' + x2 + ', ' + webkitY2 + ')' + '; /* older webkit */' + '<br>-webkit-transition: all ' + timeVal + 'ms ' + bezier;
    webkitTiming = '-webkit-transition-timing-function: cubic-bezier(' + x1 + ', ' + webkitY1 + ', ' + x2 + ', ' + webkitY2 + ')' + '; /* older webkit */' + '<br>-webkit-transition-timing-function: ' + bezier;

  }

  // output code snippets
  code.innerHTML = '<p>' + webkitTrans + '; <br>&nbsp;&nbsp; -moz-transition: all ' + timeVal + 'ms ' + bezier + '; <br>&nbsp;&nbsp;&nbsp;&nbsp; -o-transition: all ' + timeVal + 'ms ' + bezier + '; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transition: all ' + timeVal + 'ms ' + bezier + '; /* ' + easeName + ' */</p>' + '<p>' + webkitTiming + '; <br>&nbsp;&nbsp; -moz-transition-timing-function: ' + bezier + '; <br>&nbsp;&nbsp;&nbsp;&nbsp; -o-transition-timing-function: ' + bezier + '; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; transition-timing-function: ' + bezier + '; /* ' + easeName + ' */</p>';

}

function setTransitions() {

  var cp1 = handles[0],
  cp2 = handles[1];

  var x1 = (cp1.x / graph.width).toFixed(3),
  y1 = ((graph.height + graph.y - cp1.y) / graph.height).toFixed(3),
  x2 = (cp2.x / canvas.width).toFixed(3),
  y2 = ((graph.height + graph.y - cp2.y) / graph.height).toFixed(3),

  //console.log( cp1.x, cp1.y )
  points = '(' + x1 + ', ' + y1 + ', ' + x2 + ', ' + y2 + ')';

  //console.log(points)
  timeVal = time.value;

  // set all transition types. ugly ugly vendor prefixes
  box.style.WebkitTransition = box.style.MozTransition = box.style.MsTransition = box.style.OTransition = box.style.transition = 'all ' + timeVal + 'ms cubic-bezier' + points;

  if (!supportsBezierRange) {

    var wy1, wy2;

    if (y1 > 1) wy1 = 1;
    if (y1 < 0) wy1 = 0;
    if (y2 > 1) wy2 = 1;
    if (y2 < 0) wy2 = 0;

    box.style.WebkitTransition = 'all ' + timeVal + 'ms cubic-bezier' + '(' + x1 + ', ' + wy1 + ', ' + x2 + ', ' + wy2 + ')';
  }

}

function presetChange() {

  var coordinates = this.value.split(','),
  cp1 = handles[0],
  cp2 = handles[1];

  cp1.x = coordinates[0] * graph.width;
  cp1.y = graph.y + graph.height - (coordinates[1] * graph.height);
  cp2.x = coordinates[2] * graph.width;
  cp2.y = graph.y + graph.height - (coordinates[3] * graph.height);

  updateDrawing();

}

var $presets = $('#presets'),
$time = $('#time'),
$presetOpts = $('#presets option');

$presets.change(presetChange);

// get the button value and toggle the class
$('.testButton').click(function() {

  //updateDrawing();
  setTransitions();
  $('#box').toggleClass($(this).val());
});

$time.change(function() {
  setTransitions();
  updateDrawing();
});

$time.keyup(function() {
  $(this).trigger('change');
});

// arrow key support
$(document).keydown(function(event) {

  var currentlySelected, currentIdx;

  if (event.keyCode === 39 && event.target !== time) {
    //right key && not in time input
    currentlySelected = $('#presets option:selected');
    currentIdx = $presetOpts.index(currentlySelected);

    if (currentIdx < $presetOpts.length - 1) {
      currentlySelected.attr('selected', '');
      $presetOpts.eq(currentIdx + 1).attr('selected', 'selected');
      $presets.trigger('change');
    }
  } else if (event.keyCode === 37 && event.target !== time) {
    // left key && not in time input
    currentlySelected = $('#presets option:selected');
    currentIdx = $presetOpts.index(currentlySelected);

    if (currentIdx > 0) {
      currentlySelected.attr('selected', '');
      $presetOpts.eq(currentIdx - 1).attr('selected', 'selected');
      $presets.trigger('change');
    }
  }

});

setTransitions();
$presets.trigger('change');
<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<link rel="stylesheet" type="text/css" href="./css/style.css"/>
	</head>

	<body>

		<section class="demo">

			<div class="controls clearfix">
				<div class="graph">
					<figure>
						<canvas id="curve" width="200" height="450"></canvas>
					</figure>
				</div>

				<div class="options">

					<label for="presets"><span class="text">Easing:</span>
						<select name="presets" id="presets">
							<optgroup label="defaults">
								<option value="0.250, 0.250, 0.750, 0.750" selected>linear</option>
								<option value="0.250, 0.100, 0.250, 1.000">ease (default)</option>
								<option value="0.420, 0.000, 1.000, 1.000">ease-in</option>
								<option value="0.000, 0.000, 0.580, 1.000">ease-out</option>
								<option value="0.420, 0.000, 0.580, 1.000">ease-in-out</option>
							</optgroup>
							<optgroup label="Penner Equations (approximated)">
								<option value="0.550, 0.085, 0.680, 0.530">easeInQuad</option>
								<option value="0.550, 0.055, 0.675, 0.190">easeInCubic</option>
								<option value="0.895, 0.030, 0.685, 0.220">easeInQuart</option>
								<option value="0.755, 0.050, 0.855, 0.060">easeInQuint</option>
								<option value="0.470, 0.000, 0.745, 0.715">easeInSine</option>
								<option value="0.950, 0.050, 0.795, 0.035">easeInExpo</option>
								<option value="0.600, 0.040, 0.980, 0.335">easeInCirc</option>
								<option value="0.600, -0.280, 0.735, 0.045">easeInBack</option>

								<option value="0.250, 0.460, 0.450, 0.940">easeOutQuad</option>
								<option value="0.215, 0.610, 0.355, 1.000">easeOutCubic</option>
								<option value="0.165, 0.840, 0.440, 1.000">easeOutQuart</option>
								<option value="0.230, 1.000, 0.320, 1.000">easeOutQuint</option>
								<option value="0.390, 0.575, 0.565, 1.000">easeOutSine</option>
								<option value="0.190, 1.000, 0.220, 1.000">easeOutExpo</option>
								<option value="0.075, 0.820, 0.165, 1.000">easeOutCirc</option>
								<option value="0.175, 0.885, 0.320, 1.275">easeOutBack</option>

								<option value="0.455, 0.030, 0.515, 0.955">easeInOutQuad</option>
								<option value="0.645, 0.045, 0.355, 1.000">easeInOutCubic</option>
								<option value="0.770, 0.000, 0.175, 1.000">easeInOutQuart</option>
								<option value="0.860, 0.000, 0.070, 1.000">easeInOutQuint</option>
								<option value="0.445, 0.050, 0.550, 0.950">easeInOutSine</option>
								<option value="1.000, 0.000, 0.000, 1.000">easeInOutExpo</option>
								<option value="0.785, 0.135, 0.150, 0.860">easeInOutCirc</option>
								<option value="0.680, -0.550, 0.265, 1.550">easeInOutBack</option>



							</optgroup>
							<optgroup label="custom">
								<option value="0.500, 0.250, 0.500, 0.750">custom (drag the handles)</option>
							</optgroup>
						</select>
					</label>

					<label for="time"><span class="text">Duration:</span>
						<input type="number" step="100" value="500" size="7" maxlength="4" pattern="[0-9]*" name="time" value="time" id="time">
					</label>

					<label for="buttons"><span class="text">Effect:</span><br />
						<input type="button" name="left" value="left" id="left" class="testButton">
						<input type="button" name="width" value="width" id="width" class="testButton">
						<input type="button" name="height" value="height" id="height" class="testButton">
						<input type="button" name="opacity" value="opacity" id="opacity" class="testButton">
					</label>

					<div class="anim">
						<div id="box">
							<!-- demo thing is here -->
						</div>
					</div>

				</div>
			</div>

		</section>
		
		<div id="codeOutput" style="float: left;width: 100%;"></div>
		
		<script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="./js/common.js" type="text/javascript" charset="utf-8"></script>
	</body>

</html>
canvas {
	display: block;
	cursor: pointer;
}

.demo {
	padding: 0 0 30px 0;
	border-top: 1px solid #F0EFEB;
}

.controls {
	border-bottom: 1px solid #fff;
}

.graph {
	float: left;
	margin-left: -20px;
}

canvas {
	display: block;
	cursor: pointer;
}

figure {
	display: block;
	position: relative;
	padding-left: 20px;
	width: 200px;
}

figcaption {
	display: block;
	position: absolute;
}

#axisAnimation {
	left: -33px;
	top: 210px;
	-webkit-transform: rotate(-90deg);
	-moz-transform: rotate(-90deg);
	-ms-transform: rotate(-90deg);
	-o-transform: rotate(-90deg);
	transform: rotate(-90deg);
}

#axisTime {
	left: 100px;
	top: 335px;
}

.options {
	margin-top: 130px;
	margin-left: 30px;
	width: 300px;
	float: left;
}

label {
	display: block;
	margin-bottom: 10px;
}

label .text {
	display: inline-block;
	width: 60px;
}

.options input[type="button"] {
	width: 100px;
	font-size: 15px;
	color: #454545;
	text-shadow: 0 -1px 0 #51c0e3, 0 1px 0 rgba(255, 255, 255, 0.22);
	text-transform: capitalize;
	padding: 5px;
	margin-right: 5px;
	border: none;
	-webkit-border-radius: 50px;
	-moz-border-radius: 50px;
	border-radius: 50px;
	-webkit-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	-moz-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	-ms-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	-o-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	box-shadow: 0px 0px 2px #00c2ff;
	background: #F3F2EA;
	/* old browsers */
	background: -moz-linear-gradient(top, #F3F2EA 0%, #A39F5F 100%);
	/* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #51c0e3));
	/* webkit */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F3F2EA', endColorstr='#A39F5F', GradientType=0);
	/* ie */
	outline: none;
	margin-top: 10px;
}

.options input[type="button"]:active {
	text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.22), 0 1px 0 rgba(0, 0, 0, 0.40);
	-webkit-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	-moz-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	-ms-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	-o-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	background: #F3F2EA;
	/* old browsers */
	background: -moz-linear-gradient(top, #029ccc 0%, #F3F2EA 100%);
	/* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #029ccc), color-stop(100%, #F3F2EA));
	/* webkit */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#029ccc', endColorstr='#F3F2EA', GradientType=0);
	/* ie */
}

.anim {
	background: repeat-y top left,  repeat-y top right;
}

#box {
	width: 100px;
	height: 100px;
	background: #00c2ff  no-repeat center center;
	position: relative;
	margin-top: 3px;
	left: 0px;
	opacity: 1;
	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
	border-radius: 6px;
	-webkit-transform: translateZ(0);
	-moz-transform: translateZ(0);
	-ms-transform: translateZ(0);
	-o-transform: translateZ(0);
	transform: translateZ(0);
	/* to trigger GPU acceleration */
}

#box.left {
	left: 460px;
}

#box.opacity {
	opacity: 0;
}

#box.width {
	width: 560px;
}

#box.height {
	height: 560px;
}

#snippets {
	clear: both;
	border-top: 1px solid #F0EFEB;
	padding-top: 15px;
}

#codeOutput {
	font-family: Courier, monospace;
}

#donate {
	margin-top: 20px;
}

#donate .donation {
	display: inline-block;
	text-align: center;
	text-decoration: none;
	width: 87px;
	font-size: 14px;
	margin: 0 3px;
	color: #454545;
	text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.40), 0 1px 0 rgba(255, 255, 255, 0.22);
	text-transform: capitalize;
	padding: 4px;
	border: none;
	-webkit-border-radius: 50px;
	-moz-border-radius: 50px;
	border-radius: 50px;
	-webkit-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	-moz-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	-ms-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	-o-box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.65);
	background: #EFF2EA;
	/* old browsers */
	background: -moz-linear-gradient(top, #EFF2EA 0%, #9BAF7E 100%);
	/* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #EFF2EA), color-stop(100%, #9BAF7E));
	/* webkit */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EFF2EA', endColorstr='#9BAF7E', GradientType=0);
	/* ie */
	position: relative;
}

#donate .donation:active {
	text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.22), 0 1px 0 rgba(0, 0, 0, 0.40);
	-webkit-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	-moz-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	-ms-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	-o-box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.65);
	background: #9BAF7E;
	/* old browsers */
	background: -moz-linear-gradient(top, #9BAF7E 0%, #EFF2EA 100%);
	/* firefox */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9BAF7E), color-stop(100%, #EFF2EA));
	/* webkit */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9BAF7E', endColorstr='#EFF2EA', GradientType=0);
	/* ie */
}

#resources {
	padding-bottom: 30px;
}

#resources li {
	margin-bottom: 4px;
}

#needs {
	margin-bottom: 35px;
}

#oldBrowser {
	display: none;
	visibility: hidden;
}

.no-csstransitions #oldBrowser {
	display: block;
	visibility: visible;
	position: absolute;
	top: 130px;
	background-color: rgba(0, 0, 0, 0.8);
	font-size: 25px;
	color: #fff;
	text-align: center;
	width: 100%;
	padding: 20px 0;
}