js canvas实现写字动画效果


Posted in Javascript onNovember 30, 2018

本文实例为大家分享了js canvas实现写字动画效果展示的具体代码,供大家参考,具体内容如下

页面html:

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>学写一个字</title>
 <script src="jquery-2.1.3.min.js" type="text/javascript"></script>
 <link href="handwriting.css" rel="stylesheet" type="text/css"/>
 <meta name="viewport"
   content=" height = device-height,
     width = device-width,
     initial-scale = 1.0,
     minimum-scale = 1.0,
     maximum-scale = 1.0,
     user-scalable = no"/> //兼容移动端
 
</head>
<body>
 
 <canvas id="canvas">
  您的浏览器不支持canvas
 </canvas>//写字区域
 <div id="controller">
  <div id="black_btn" class="color_btn color_btn_selected"></div>
  <div id="blue_btn" class="color_btn"></div>
  <div id="green_btn" class="color_btn"></div>
  <div id="red_btn" class="color_btn"></div>
  <div id="orange_btn" class="color_btn"></div>
  <div id="yellow_btn" class="color_btn"></div>
 
  <div id="clear_btn" class="op_btn">清 除</div>
  <div class="clearfix"></div>
 </div>
 
 <script src = "handwriting.js"></script>
</body>
</html>

页面css:

#canvas{
 display:block;
 margin:0 auto;
}
#controller{
 margin:0 auto;
}
.op_btn{
 float: right;
 margin:10px 0 0 10px;
 border:2px solid #aaa;
 width:80px;
 height:40px;
 line-height:40px;
 font-size:20px;
 text-align:center;
 border-radius: 5px 5px;
 cursor:pointer;
 background-color: white;
 font-weight:bold;
 font-family: Microsoft Yahei, Arial;
}
.op_btn:hover{
 background-color:#def;
}
.clearfix{
 clear:both;
}
 
.color_btn{
 float: left;
 margin: 10px 10px 0 0;
 border:5px solid white;
 width:40px;
 height:40px;
 border-radius: 5px 5px;
 cursor:pointer;
}
.color_btn:hover{
 border: 5px solid violet;
}
.color_btn_selected{
 border: 5px solid blueviolet;
}
#black_btn{
 background-color: black;
}
#blue_btn{
 background-color: blue;
}
#green_btn{
 background-color: green;
}
#red_btn{
 background-color: red;
}
#orange_btn{
 background-color: orange;
}
#yellow_btn{
 background-color: yellow;
}

页面js:

var canvasWidth = Math.min( 800 , $(window).width() - 20 );//如果屏幕小于800px,则取值为屏幕大小宽度,便于移动端的展示,-20是为了使得米字格不紧贴于边缘
var canvasHeight = canvasWidth;
 
var strokeColor = "black";
var isMouseDown = false; //鼠标按下时候的状态
var lastLoc = {x:0,y:0}; //鼠标上一次结束时的位置
var lastTimestamp = 0; //上一次时间,与笔刷粗细有关
var lastLineWidth = -1; //笔刷粗细
 
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
 
canvas.width = canvasWidth;
canvas.height = canvasHeight;
 
$("#controller").css("width",canvasWidth+"px");
drawGrid();//画米字格
 
$("#clear_btn").click(
 function(e){
  context.clearRect( 0 , 0 , canvasWidth, canvasHeight );
  drawGrid();
 }
)
$(".color_btn").click(
 function(e){
  $(".color_btn").removeClass("color_btn_selected");
  $(this).addClass("color_btn_selected");
  strokeColor = $(this).css("background-color");
 }
)
//适用于移动端触控
function beginStroke(point){
 
 isMouseDown = true
 //console.log("mouse down!");
 lastLoc = windowToCanvas(point.x, point.y); //上一次坐标位置
 lastTimestamp = new Date().getTime();
 
}
function endStroke(){
 isMouseDown = false;
}
function moveStroke(point){
 
 var curLoc = windowToCanvas( point.x , point.y );
 var curTimestamp = new Date().getTime();
 var s = calcDistance( curLoc , lastLoc );
 var t = curTimestamp - lastTimestamp;
 
 var lineWidth = calcLineWidth( t , s );
 
 //draw
 context.beginPath();
 context.moveTo( lastLoc.x , lastLoc.y );
 context.lineTo( curLoc.x , curLoc.y );
 
 context.strokeStyle = strokeColor;
 context.lineWidth = lineWidth;
 context.lineCap = "round";
 context.lineJoin = "round";
 context.stroke();
 
 lastLoc = curLoc;
 lastTimestamp = curTimestamp;
 lastLineWidth = lineWidth;
}
 
canvas.onmousedown = function(e){
 e.preventDefault();
 beginStroke( {x: e.clientX , y: e.clientY} );
};
canvas.onmouseup = function(e){
 e.preventDefault();
 endStroke();
};
canvas.onmouseout = function(e){
 e.preventDefault();
 endStroke();
};
canvas.onmousemove = function(e){
 e.preventDefault();
 if( isMouseDown ){
  moveStroke({x: e.clientX , y: e.clientY})
 }
};
 
canvas.addEventListener('touchstart',function(e){
 e.preventDefault();
 touch = e.touches[0];
 beginStroke( {x: touch.pageX , y: touch.pageY} )
});
canvas.addEventListener('touchmove',function(e){
 e.preventDefault();
 if( isMouseDown ){
  touch = e.touches[0];
  moveStroke({x: touch.pageX , y: touch.pageY});
 }
});
canvas.addEventListener('touchend',function(e){
 e.preventDefault();
 endStroke();
});
 
var maxLineWidth = 30;
var minLineWidth = 1;
var maxStrokeV = 10;
var minStrokeV = 0.1;
function calcLineWidth( t , s ){
 
 var v = s / t;
 
 var resultLineWidth;
 if( v <= minStrokeV )
  resultLineWidth = maxLineWidth;
 else if ( v >= maxStrokeV )
  resultLineWidth = minLineWidth;
 else{
  resultLineWidth = maxLineWidth - (v-minStrokeV)/(maxStrokeV-minStrokeV)*(maxLineWidth-minLineWidth);
 }
 
 if( lastLineWidth == -1 )
  return resultLineWidth;
 
 return resultLineWidth*1/3 + lastLineWidth*2/3;
}
 
function calcDistance( loc1 , loc2 ){
 
 return Math.sqrt( (loc1.x - loc2.x)*(loc1.x - loc2.x) + (loc1.y - loc2.y)*(loc1.y - loc2.y) );
}
 
function windowToCanvas( x , y ){
 var bbox = canvas.getBoundingClientRect();
 return {x:Math.round(x-bbox.left) , y:Math.round(y-bbox.top)}
}
function drawGrid(){
 
 context.save();
 
 context.strokeStyle = "rgb(230,11,9)";
 
 context.beginPath();
 context.moveTo( 3 , 3 );
 context.lineTo( canvasWidth - 3 , 3 );
 context.lineTo( canvasWidth - 3 , canvasHeight - 3 );
 context.lineTo( 3 , canvasHeight - 3 );
 context.closePath();
 context.lineWidth = 6;
 context.stroke();
 
 context.beginPath();
 context.moveTo(0,0);
 context.lineTo(canvasWidth,canvasHeight);
 
 context.moveTo(canvasWidth,0);
 context.lineTo(0,canvasHeight);
 
 context.moveTo(canvasWidth/2,0);
 context.lineTo(canvasWidth/2,canvasHeight);
 
 context.moveTo(0,canvasHeight/2);
 context.lineTo(canvasWidth,canvasHeight/2);
 
 context.lineWidth = 1;
 context.stroke();
 
 context.restore();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用js怎么把&amp;字符换成&quot;&amp;amp:&quot;
Oct 19 Javascript
用CSS+JS实现的进度条效果效果
Jun 05 Javascript
用js判断页面刷新或关闭的方法(onbeforeunload与onunload事件)
Jun 22 Javascript
jQuery中:has选择器用法实例
Dec 30 Javascript
原生js实现class的添加和删除简单代码
Jul 12 Javascript
聊一聊Vue.js过渡效果
Sep 07 Javascript
用jQuery.ajaxSetup实现对请求和响应数据的过滤
Dec 20 Javascript
jQuery阻止移动端遮罩层后页面滚动
Mar 15 Javascript
JavaScript 巧学巧用
May 23 Javascript
用vue的双向绑定简单实现一个todo-list的示例代码
Aug 03 Javascript
react-native组件中NavigatorIOS和ListView结合使用的方法
Sep 30 Javascript
JavaScript使用闭包模仿块级作用域操作示例
Jan 21 Javascript
webpack打包多页面的方法
Nov 30 #Javascript
Element Table的row-class-name无效与动态高亮显示选中行背景色
Nov 30 #Javascript
VUE2.0+ElementUI2.0表格el-table实现表头扩展el-tooltip
Nov 30 #Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
Nov 30 #Javascript
js字符串倒序的实例代码
Nov 30 #Javascript
实例讲解JavaScript截取字符串
Nov 30 #Javascript
支付宝小程序自定义弹窗dialog插件的实现代码
Nov 30 #Javascript
You might like
索尼ICF-SW100收音机评测
2021/03/02 无线电
让你的WINDOWS同时支持MYSQL4,MYSQL4.1,MYSQL5X
2006/12/06 PHP
测试php连接mysql是否成功的代码分享
2014/01/24 PHP
php中JSON的使用方法
2015/04/30 PHP
php如何连接sql server
2015/10/16 PHP
PHP实现的分页类定义与用法示例
2017/07/05 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
php获取ajax的headers方法与内容实例
2017/12/27 PHP
解决在laravel中leftjoin带条件查询没有返回右表为NULL的问题
2019/10/15 PHP
laravel框架中控制器的创建和使用方法分析
2019/11/23 PHP
wordpress之js库集合研究介绍
2007/08/17 Javascript
javascript同步Import,同步调用外部js的方法
2008/07/08 Javascript
IE JS编程需注意的内存释放问题
2009/06/23 Javascript
jQueryUI的Dialog的简单封装
2010/06/07 Javascript
jquery post方式传递多个参数值后台以数组的方式进行接收
2013/01/11 Javascript
js的隐含参数(arguments,callee,caller)使用方法
2014/01/28 Javascript
jquery滚动到顶部底部代码
2015/04/20 Javascript
javascript实现可拖动变色并关闭层窗口实例
2015/05/15 Javascript
jQuery购物网页经典制作案例
2016/08/19 Javascript
bootstrap配合Masonry插件实现瀑布式布局
2017/01/18 Javascript
Vue.js组件tab实现选项卡切换
2020/03/23 Javascript
实例详解vue.js浅度监听和深度监听及watch用法
2018/08/16 Javascript
Vue组件中的data必须是一个function的原因浅析
2018/09/03 Javascript
JS学习笔记之原型链和利用原型实现继承详解
2019/05/29 Javascript
[07:59]2014DOTA2叨叨刀塔 林熊猫称被邀请赛现场盛况震撼
2014/07/21 DOTA
python matplotlib实现双Y轴的实例
2019/02/12 Python
Python实现微信中找回好友、群聊用户撤回的消息功能示例
2019/08/23 Python
python+selenium 脚本实现每天自动登记的思路详解
2020/03/11 Python
HTML5到底会有什么发展?HTML5的前景展望
2015/07/07 HTML / CSS
HTML5公共页面提取作为公用代码的方法
2020/06/30 HTML / CSS
西班牙鞋子和箱包在线销售网站:zapatos.es
2020/02/17 全球购物
成功的酒店创业计划书
2013/12/27 职场文书
文科教师毕业的自我评价
2014/01/16 职场文书
计生办班子群众路线教育实践活动个人对照检查材料思想汇报
2014/10/04 职场文书
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js