基于html5 canvas做批改作业的小插件_html5教程技巧

来源:脚本之家  责任编辑:小易  

Canvas是使用JavaScript程序绘图(动态生成),SVG是使用XML文档描述来绘图。从这点来看:SVG更适合用来做动态交互,而且SVG绘图很容易编辑,只需要增加或移除相应的元素就可以了。同时SVG是基于矢量的,所有它能够很好的处理图形大小的改变。Canvas是基于位图的图像,它不能够改变大小,只能缩放显示;所以说Canvas更适合用来实现类似于Flash能做的事情(当然现在Canvas与Flash相比还有一些不够完善的地方)。关于最后一点二者谁更有前途:从上面我们可以知道二者是有不同用途的,作为一个开发者,你应该做的是理解应用程序的具体需求并选择正确的技术来实现它www.zgxue.com防采集请勿采集本网。

今天公司有一个新的需求,就是要在返回的作业照片里面可以涂鸦批改,批改完后就连同批改后的照片上传到服务器。这对我不怎么熟悉canvas的人来说是个挑战。

指定两个canvas的postion:absolution,然后设置者两个canvas的left与top属性,需要注意的是建议把小的canvas放到上面,方法是设置两个canvas的z-index为不同的值,值大的在上面。绘图的过程可以

需求分析

    能进行批改,就是相当于画笔 能进行画笔的撤回功能 能进行全部画笔的清除功能 可以转化画笔的颜色

chart.js是一款基于HTML5 Canvas的图表插件,chart.js的功能非常强大,它不仅提供了常见的柱形图、折线图、饼状图,而且还提供了环形图、雷达图,样式外观多样,图表的色彩搭配也比较清新。chart.js还有

技术上的实现思路

先把他的开发逻辑想好,把它分成好几个小步骤,然后一个一个来救很容易做成了。

  在听到这需求后的第一反应就是用canvas来做,所以我在w3school阅读了 canvas的API .

canvas只是HTML5的一个新标签他只提供了一个平台,需要js来完成游戏的操作给你一个HTML5开发水果忍着的游戏,抱歉发布了连接,需要的话去零零H5下载吧

1.将图片转到canvas,用到API: drawImage()

SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动

2画笔的实现 当按下鼠标(mousedown)记录开始点startX, startY 当移动鼠标的时候(mousemove)就获取当前的鼠标的坐标e.clientX, e.clientY,获取到了当前的坐标后,与上一个点的坐标轴的左边进行连线(lineTo ),这样就能画出了一条横线了 当鼠标松开左键(mouseup)时候,就清除mousemove的函数

3.清除功能:讲原始的图片再次用drawImage()函数来重置

4.撤回功能:在每次按下鼠标那时候,用getImageData()函数获取当前的图像记录到数组里面,然后按撤回则使用putImageData()函数放在canvas

5.画笔的颜色:在mousemove里面改变strokeStyle笔的颜色

代码实现

移动鼠标画出线条的代码

let self = this; this.canvasNode = document.createElement('canvas'); let styleString = this.utils.formatStyle(CANVAS_STYLE); // CANVAS_STYLE是canvas的样式 this.canvasNode.setAttribute('id','canvas'); // 一定要设置这width 和 height let ratio = this.imgNode.width / this.imgNode.height, height = this.imgNode.height, width = this.imgNode.width; let tempWidth , tempHeight; // 按比例伸缩 if(ratio >= window.innerWidth / window.innerHeight){ if(width > window.innerWidth){ tempWidth = window.innerWidth; tempHeight = height * window.innerWidth / width; } else { tempWidth = width; tempHeight = height; } }else{ if(height > window.innerHeight){ tempWidth = width * window.innerHeight / width; tempHeight = window.innerHeight; }else{ tempWidth = width; tempHeight = height; } } this.canvasNode.height = tempHeight; this.canvasNode.width = tempWidth; styleString = Object.assign({'width': tempWidth, 'height': tempHeight}, CANVAS_STYLE); this.canvasNode.setAttribute('style', styleString); let ctx = this.canvasNode.getContext('2d'), startX = 0, startY = 0; let image = new Image() ; image.setAttribute("crossOrigin",'Anonymous') // 加时间戳因为这图片的域名没设置跨域https://www.jianshu.com/p/c3aa975923de image.src = this.imgNode.src + '?t=' + new Date().getTime(); image.height = tempHeight; image.width = tempWidth; image.onload = function(){ ctx.drawImage(image, 0, 0, tempWidth, tempHeight); } // 鼠标移动事件 let mousemoveFn = function(e) { ctx.beginPath(); ctx.lineWidth = 3; ctx.strokeStyle = self.currentColor; if(startX == e.clientX - self.canvasNode.offsetLeft || startY === e.clientY - self.canvasNode.offsetTop ) return ctx.moveTo(startX,startY); ctx.lineTo(e.clientX - self.canvasNode.offsetLeft , e.clientY - self.canvasNode.offsetTop ); ctx.stroke(); startX = e.clientX - self.canvasNode.offsetLeft; startY = e.clientY - self.canvasNode.offsetTop ; // 37是header的高度 } // 鼠标按下事件 this.canvasNode.addEventListener("mousedown",function(e){ startX = e.clientX - self.canvasNode.offsetLeft; startY = e.clientY - self.canvasNode.offsetTop ; // 如果在mouseup那里记录 则在撤回时候要做多一个步骤 let imageData = ctx.getImageData(0,0, self.canvasNode.width, self.canvasNode.height); self.imageDataArray.push(imageData); // 这imageDataArray用来记录画笔的笔画 self.canvasNode.addEventListener("mousemove", mousemoveFn, false); },false); this.canvasNode.addEventListener('mouseup', function(e){ self.canvasNode.removeEventListener('mousemove', mousemoveFn); }); this.bgNode.appendChild(this.canvasNode);

遇到的问题

1.图片的跨域问题   因为这个域名只设置了192.168.6.*的跨域,所以我localhost的域名会报跨域的问题(只对192.168.6.*的跨域是同事告诉我的,不然我还在傻乎乎的查问题)

解决办法:设置vue.congfig.js文件的dev下的host

2.图片的按比例伸缩完按保存后图片的尺寸变了   我用toDataURL()方法输出的base64后的图片尺寸变了。原因:在我把图片draw上canvas上时候,用了上面代码的图片那比例伸缩的算法把图片变小了,所以画在canvas上的图片也变小了...

解决办法:(待解决)

总结

第一次接触canvas与图片相结合的功能,让我熟悉了canvas的api 在遇到没做过的功能之前,一定要先定下心来运用你所知道的知识思考下有没可行的方法,找到了突破点就可以做了 在你碰上不熟悉的知识时候,一定要先看api,我这canvas之前不怎么会的,之后我细看了几遍的api,我就可以上手去做功能了,并且在w3school看到的例子让我觉得canvas真的很强大

到此这篇关于基于html5 canvas做批改作业的小插件的文章就介绍到这了,更多相关canvas 批改作业插件内容请搜索真格学网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持真格学网!

创建画布Create the canvasvar canvas=document.createElement("canvas");var ctx=canvas.getContext("2d");canvas.width=512;canvas.height=480;document.body.appendChild(canvas);首先我们需要创建一张画布作为游戏的舞台。这里通过JS代码而不是直接在HTML里写一个元素目的是要说明代码创建也是很方便的。有了画布后就可以获得它的上下文来进行绘图了。然后我们还设置了画布大小,最后将其添加到页面上。准备图片背景图片var bgReady=false;var bgImage=new Image();bgImage.onload=function(){bgReady=true;};bgImage.src="images/background.png;游戏嘛少不了图片的,所以我们先加载一些图片先。简便起见,这里仅创建简单的图片对象,而不是专门写一个类或者Helper来做图片加载。bgReady这个变量用来标识图片是否已经加载完成从而可以放心地使用了,因为如果在图片加载未完成情况下进行绘制是会报错的。整个游戏中需要用到的三张图片:背景,英雄及怪物我们都用上面的方法来处理。游戏对象游戏对象var hero={speed:256,/每秒移动的像素x:0,y:0};var monster={x:0,y:0};var monstersCaught=0;现在定义一些对象将在后面用到。我们的英雄有一个speed属性用来控制他每秒移动多少像素。怪物游戏过程中不会移动,所以只有坐标属性就够了。monstersCaught则用来存储怪物被捉住的次数。处理用户的输入处理按键var keysDown={};addEventListener("keydown",function(e){keysDown[e.keyCode]=true;},false);addEventListener("keyup",function(e){delete keysDown[e.keyCode];},false);现在开始处理用户的输入(对初次接触游戏开发的前端同学来说,这部分开始可能就需要一些脑力了)。在前端开发中,一般是用户触发了点击事件然后才去执行动画或发起异步请求之类的,但这里我们希望游戏的逻辑能够更加紧凑同时又要及时响应输入。所以我们就把用户的输入先保存下来而不是立即响应。为此,我们用keysDown这个对象来保存用户按下的键值(keyCode),如果按下的键值在这个对象里,那么我们就做相应处理。开始一轮游戏当用户抓住一只怪物后开始新一轮游戏var reset=function(){hero.x=canvas.width/2;hero.y=canvas.height/2;将新的怪物随机放置到界面上monster.x=32+(Math.random()*(canvas.width-64));monster.y=32+(Math.random()*(canvas.height-64));};reset方法用于开始新一轮和游戏,在这个方法里我们将英雄放回画布中心同时将怪物放到一个随机的地方。更新对象更新游戏对象的属性var update=function(modifier){if(38 in keysDown){/用户按的是↑hero.y-=hero.speed*modifier;}if(40 in keysDown){/用户按的是↓hero.y+hero.speed*modifier;}if(37 in keysDown){/用户按的是←hero.x-=hero.speed*modifier;}if(39 in keysDown){/用户按的是→hero.x+hero.speed*modifier;}英雄与怪物碰到了么?ifhero.x(monster.x+32)monster.x(hero.x+32)hero.y(monster.y+32)monster.y(hero.y+32){monstersCaught;reset();}};这就是游戏中用于更新画面的update函数,会被规律地重复调用。首先它负责检查用户当前按住的是中方向键,然后将英雄往相应方向移动。有点费脑力的或许是这个传入的modifier 变量。你可以在main 方法里看到它的来源,但这里还是有必要详细解释一下。它是基于1开始且随时间变化的一个因子。例如1秒过去了,它的值就是1,英雄的速度将会乘以1,也就是每秒移动256像素;如果半秒钟则它的值为0.5,英雄的速度就乘以0.5也就是说这半秒内英雄以正常速度一半的速度移动。理论上说因为这个update 方法被调用的非常快且频繁,所以modifier的值会很小,但有了这一因子后,不管我们的代码跑得快慢,都能够保证英雄的移动速度是恒定的。现在英雄的移动已经是基于用户的输入了,接下来该检查移动过程中所触发的事件了,也就是英雄与怪物相遇。这就是本游戏的胜利点,monstersCaught+1然后重新开始新一轮。渲染物体画出所有物体var render=function(){if(bgReady){ctx.drawImage(bgImage,0,0);}if(heroReady){ctx.drawImage(heroImage,hero.x,hero.y);}if(monsterReady){ctx.drawImage(monsterImage,monster.x,monster.y);}计分ctx.fillStyle="rgb(250,250,250);ctx.font="24px Helvetica;ctx.textAlign="left;ctx.textBaseline="top;ctx.fillText("Monsterrs caught:"+monstersCaught,32,32);};之前的工作都是枯燥的,直到你把所有东西画出来之后。首先当然是把背景图画出来。然后如法炮制将英雄和怪物也画出来。这个过程中的顺序是有讲究的,因为后画的物体会覆盖之前的物体。这之后我们改变了一下Canvas的绘图上下文的样式并调用fillText来绘制文字,也就是记分板那一部分。本游戏没有其他复杂的动画效果和打斗场面,绘制部分大功告成!主循环函数游戏主函数var main=function(){var now=Date.now();var delta=now-then;update(delta/1000);render();then=now;立即调用主函数requestAnimationFrame(main);};上面的主函数控制了整个游戏的流程。先是拿到当前的时间用来计算时间差(距离上次主函数被调用时过了多少毫秒)。得到modifier后除以1000(也就是1秒中的毫秒数)再传入update函数。最后调用render 函数并且将本次的时间保存下来。关于游戏中循环更新画面的讨论可参见「Onslaught!Arena Case Study」。关于循环的进一步解释requestAnimationFrame 的浏览器兼容性处理var w=window;requestAnimationFrame=w.requestAnimationFrame|w.webkitRequestAnimationFrame|w.msRequestAnimationFrame|w.mozRequestAnimationFrame;如果你不是完全理解上面的代码也没关系,我只是觉得拿出来解释一下总是极好的为了循环地调用main函数,本游戏之前用的是setInterval。但现今已经有了更好的方法那就是requestAnimationFrame。使用新方法就不得不考虑浏览器兼容性。上面的垫片就是出于这样的考虑,它是Paul Irish 博客原版的一个简化版本。启动游戏!少年,开始游戏吧!var then=Date.now();reset();main();总算完成了,这是本游戏最后一段代码了。先是设置一个初始的时间变量then用于首先运行main函数使用。然后调用 reset 函数来开始新一轮游戏(如果你还记得的话,这个函数的作用是将英雄放到画面中间同时将怪物放到随机的地方以方便英雄去捉它)内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 基于html5 canvas做批改作业的小插件
  • video下autoplay属性无效的解决方法(添加muted属性)
  • html2canvas生成的图片偏移不完整的解决方法
  • html5简介及新增功能介绍
  • html5让容器充满屏幕高度或自适应剩余高度的布局实现
  • html5在手机端调用相机的方法实现
  • html5页面获取微信公众号的openid的方法
  • 钉钉企业内部h5微应用开发详解
  • html5 横向滑动导航栏的方法示例
  • html5触摸事件(touchstart、touchmove和touchend)的实现
  • 怎样用HTML5 Canvas制作一个简单的游戏
  • SVG 与 HTML5 的 canvas 各有什么优点,哪个更有前途
  • 请教关于HTml5的问题,基于canvas 的绘图怎么样进行各种绘图操作?
  • 怎样用HTML5 Canvas制作一个简单的游戏
  • html5 两个canvas重叠放在一个div里面,每个canvas各填充一张图片,代码怎么写?
  • 如何让基于html5 canvas的图表插件chart.js中的柱状图形横向显示
  • 怎样用HTML5 Canvas制作一个简单的游戏
  • 怎样用HTML5 Canvas制作一个简单的游戏
  • SVG 与 HTML5 的 canvas 各有什么优点,哪个更有前途
  • SVG 与 HTML5 的 canvas 各有什么优点,哪个更有前途
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全主页网页制作html5插件批改作业canvashtml5简介及新增功能介绍html5让容器充满屏幕高度或自适应剩余高度的布局实现html5在手机端调用相机的方法实现html5 横向滑动导航栏的方法示例html5触摸事件(touchstart、touchmove和touchend)的实现html/xhtmlhtml5cssxml/xsltdreamweaver教程frontpage教程心得技巧css 如何让背景图片拉伸填充避免重复显示html5 input placeholder 颜色修改示例基于第一个phonegap(cordova)的应用详解 html5配合css3实现带提示文字的输入框(摆脱js)html5定位获取当前位置并在百度地图上显示将html5 canvas的内容保存为图片借助todataurl实现html5中如何显示视频呢 html5视频播放demo让ie支持html5的方法微信浏览器取消缓存的方法html5的存储方式sessionstorage和localstorage详解基于html5 canvas做批改作业的小插件video下autoplay属性无效的解决方法(添加muted属性)html2canvas生成的图片偏移不完整的解决方法html5简介及新增功能介绍html5让容器充满屏幕高度或自适应剩余高度的布局实现html5在手机端调用相机的方法实现html5页面获取微信公众号的openid的方法钉钉企业内部h5微应用开发详解html5 横向滑动导航栏的方法示例html5触摸事件(touchstart、touchmove和touchend)的实
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved