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判断条件提示是否要离开页面
May 02 Javascript
百度判断手机终端并自动跳转js代码及使用实例
Jun 11 Javascript
window.location的重写及判断location是否被重写
Sep 04 Javascript
Javascript中call与apply的学习笔记
Sep 22 Javascript
不依赖Flash和任何JS库实现文本复制与剪切附源码下载
Oct 09 Javascript
详解用webpack2搭建angular2的项目
Jun 22 Javascript
jsonp跨域请求详解
Jul 13 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
Feb 16 Javascript
ES6中异步对象Promise用法详解
Jul 31 Javascript
vue给对象动态添加属性和值的实例
Sep 09 Javascript
layui+SSM的数据表的增删改实例(利用弹框添加、修改)
Sep 27 Javascript
Element Tooltip 文字提示的使用示例
Jul 26 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
《PHP边学边教》(04.编写简易的通讯录――视频教程1)
2006/12/13 PHP
PHP strncasecmp字符串比较的小技巧
2011/01/04 PHP
PHP实现一维数组转二维数组的方法
2015/02/25 PHP
PHP生成随机字符串(3种方法)
2015/09/25 PHP
PHP递归算法的简单实例
2019/02/28 PHP
php 使用html5 XHR2实现上传文件与进度显示功能示例
2020/03/03 PHP
PHP实现限制域名访问的实现代码(本地验证)
2020/09/13 PHP
Prototype1.5 rc2版指南最后一篇之Position
2007/01/10 Javascript
JQuery 构建客户/服务分离的链接模型中Table中的排序分析
2010/01/22 Javascript
用JavaScript实现动画效果的方法
2013/07/20 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
动态读取JSON解析键值对的方法
2014/06/03 Javascript
js判断checkbox是否选中个数的方法(超简单)
2016/08/19 Javascript
JS基于封装函数实现的表格分页完整示例
2018/06/26 Javascript
node.js到底要不要加分号浅析
2018/07/11 Javascript
vue 2.8.2版本配置刚进入时候的默认页面方法
2018/09/21 Javascript
浅谈vue.use()方法从源码到使用
2019/05/12 Javascript
VUE实现Studio管理后台之鼠标拖放改变窗口大小
2020/03/04 Javascript
vue-cli点击实现全屏功能
2020/03/07 Javascript
微信小程序实现简单文字跑马灯
2020/05/26 Javascript
详解Python编程中基本的数学计算使用
2016/02/04 Python
详解Python装饰器由浅入深
2016/12/09 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
python使用adbapi实现MySQL数据库的异步存储
2019/03/19 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
如何用OpenCV -python3实现视频物体追踪
2019/12/04 Python
python plotly画柱状图代码实例
2019/12/13 Python
解决Python pip 自动更新升级失败的问题
2020/02/21 Python
win10从零安装配置pytorch全过程图文详解
2020/05/08 Python
如何实现更换Jupyter Notebook内核Python版本
2020/05/18 Python
美国网上花店:JustFlowers
2017/02/12 全球购物
Vertbaudet西班牙网上商店:婴儿服装、童装、母婴用品和儿童家具
2019/10/16 全球购物
全球最大化妆品零售网站:SkinStore
2020/10/24 全球购物
营业员个人总结的自我评价
2013/10/25 职场文书
学期自我评价
2014/01/27 职场文书
尊师重教主题班会
2015/08/14 职场文书