以上两个值都可以接受颜色名,16进制数据,rgb值,甚至rgba. 一般先进行设置样式然后进行绘制。
例如:
ctx.strokeStyle = "red";
ctx.strokeStyle = "#ccc";
ctx.strokeStyle = "rgb(255,0,0)";
ctx.strokeStyle = "rgba(255,0,0,6)";
例如:
ctx.fillStyle = "rgba(255,0,0, .9)"
ctx.shadowColor = "teal";
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.fillRect(100, 100, 100, 100);
案例: 12设置box盒子阴影.html
01Canvas案例-
设置png图片的阴影,图片透明部分不会被投影。
例如:
//创建线性渐变的对象,
var grd=ctx.createLinearGradient(0,0,170,0);
grd.addColorStop(0,"black"); //添加一个渐变颜色,第一个参数介于 0.0 与 1.0 之间的值,表示渐变中开始与结束之间的位置。
grd.addColorStop(1,"white"); //添加一个渐变颜色
ctx.fillStyle =grd; //关键点,把渐变设置到 填充的样式
var rlg = ctx.createRadialGradient(300,300,10,300,300,200);
rlg.addColorStop(0, 'teal'); //添加一个渐变颜色
rlg.addColorStop(.4, 'navy');
rlg.addColorStop(1, 'purple');
ctx.fillStyle = rlg;//设置 填充样式为延续渐变的样式
ctx.fillRect(100, 100, 500, 500);
var ctx=c.getContext("2d");
var img=document.getElementById("lamp");
var pat=ctx.createPattern(img,"repeat");
ctx.rect(0,0,150,100);
ctx.fillStyle=pat;// 把背景图设置给填充的样式
ctx.fill();
位移画布一般配合缩放和旋转等。
案例: 17位移画布.html
如需将角度转换为弧度,请使用 degrees*Math.PI/180 公式进行计算。
案例:18旋转画布.html
09Canvas案例-绘制
``` 案例1:
var canvas = document.getElementById("canvas");
var dataURL = canvas.toDataURL();
console.log(dataURL); // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby // blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC"
var img = document.querySelector("#img-demo");//拿到图片的dom对象
img.src = canvas.toDataURL("image/png"); //将画布的内容给图片标签显示
```
img参数也可以是画布,也就是把一个画布整体的渲染到另外一个画布上。 ``` var canvas1 = document.querySelector('#cavsElem1'); var canvas2 = document.querySelector('#cavsElem2'); var ctx1 = canvas1.getContext('2d'); var ctx2 = canvas2.getContext('2d'); ctx1.fillRect(20, 20, 40, 40); //在第一个画布上绘制矩形
ctx2.drawImage(canvas1, 10, 10); //将第一个画布整体绘制到第二个画布上
```
11Canvas案例-面向对象版本的矩形
/*
1、 封装属性: x, y w , h, fillStyle strokeStyle rotation opacity
2、render
*/
function ItcastRect( option ) {
this._init( option );
}
ItcastRect.prototype = {
_init: function( option ) {
this.x = option.x || 0; //x ,y 坐标
this.y = option.y || 0;
this.h = option.h || 0; // 矩形的宽高
this.w = option.w || 0;
this.rotation = option.rotation || 0; //矩形的旋转
// 设置矩形的透明度
this.opacity = option.opacity === 0 ? 0 : option.opacity || 1;
this.scaleX = option.scaleX || 1;//设置矩形的 放到缩小
this.scaleY = option.scaleY || 1;
this.strokeStyle = option.strokeStyle || 'red';
this.fillStyle = option.fillStyle || 'blue';
},
render: function( ctx ) {
ctx.save(); // 把当前的上下文的状态保存一下
ctx.beginPath(); //开始一个新的路径
ctx.translate(this.x, this.y); //把整个画布进行位移
//把整个画布进行旋转
ctx.rotate(this.rotation * Math.PI / 180 );
//设置透明度
ctx.globalAlpha = this.opacity;
//设置画布缩小放大
ctx.scale( this.scaleX, this.scaleY );
//给 ctx规划一个路径。注意:规划的路径会一直保存。所以
//最好在每次绘制矩形的时候beginPath一下标志一个新的路径。
ctx.rect(0, 0 , this.w, this.h );
ctx.fillStyle = this.fillStyle;
ctx.fill();
ctx.strokeStyle = this.strokeStyle;
ctx.stroke();
ctx.restore();//还原绘制的状态
}
}
canvas优化
12Canvas案例-canvas优化
lineJoin 设置或返回两条线相交时,所创建的拐角类型
lineWidth 设置或返回当前的线条宽度
//绘制复杂的贝塞尔曲线
ctx.beginPath();
ctx.moveTo(400,400);
//参数说明:context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
// cp1x: 第一个贝塞尔控制点的 x 坐标
// cp1y: 第一个贝塞尔控制点的 y 坐标
// cp2x: 第二个贝塞尔控制点的 x 坐标
// cp2y: 第二个贝塞尔控制点的 y 坐标
// x: 结束点的 x 坐标
// y: 结束点的 y 坐标
ctx.bezierCurveTo(500, 200, 600, 600, 700, 300);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(200,100);
//context.arcTo(x1,y1,x2,y2,r); //类比:css3中的圆角。
ctx.arcTo(240, 100, 240, 110, 40);
ctx.lineTo(240, 300);
ctx.stroke();
context.isPointInPath(x,y);
//isPointInPath() 方法返回 true,如果指定的点位于当前路径中;否则返回 false。
//判断x,y坐标的点是否在当前的路径中。
context.measureText(text).width;
//思考:我们用到的矩形需要哪些绘制的东西呢?
1、矩形的 x、y坐标
2、矩形的宽高
3、矩形的边框的线条样式、线条宽度
4、矩形填充的样式
5、矩形的旋转角度
6、矩形的缩小放大
//下面是把上面所有的功能进行封装的代码:
function ItcastRect( option ) {//矩形构造函数
this._init(option);
}
ItcastRect.prototype = { //矩形的原型对象
_init: function( option ) { //初始化方法
option = option || {};
this.x = option.x === 0 ? 0 : option.x || 100;
this.y = option.y === 0 ? 0 : option.y || 100;
this.w = option.w || 100;
this.h = option.h || 100;
this.angle = option.angle === 0 ? 0 : option.angle || 0;
this.fillStyle = option.fillStyle || 'silver';
this.strokeStyle = option.strokeStyle || 'red';
this.strokeWidth = option.strokeWidth || 4;
this.scaleX = option.scaleX || 1;
this.scaleY = option.Y || 1;
},
render: function( ctx ) {//把矩形渲染到canvas中
ctx.save();
ctx.translate( this.x, this.y );//位移画布
ctx.rotate( this.angle * Math.PI / 180 );//旋转角度
ctx.scale( this.scaleX, this.scaleY );//缩放
ctx.fillStyle = this.fillStyle;
ctx.fillRect( 0, 0, this.w, this.h ); //填充矩形
ctx.lineWidth = this.strokeWidth; //线宽
ctx.strokeStyle = this.strokeStyle; //填充样式
ctx.strokeRect( 0,0,this.w,this.h ); //描边样式
ctx.restore();
},
constructor: ItcastRect
};
//封装圆形的代码的答案:不要偷看
function ItcastCircle( option ) {
this._init( option );
}
ItcastCircle.prototype = {
_init: function( option ) {
option = option || {};
this.x = option.x === 0 ? 0 : option.x || 100;
this.y = option.y === 0 ? 0 : option.y || 100;
this.w = option.w || 100;
this.h = option.h || 100;
this.angle = option.angle === 0 ? 0 : option.angle || 0;
this.fillStyle = option.fillStyle || 'silver';
this.strokeStyle = option.strokeStyle || 'red';
this.strokeWidth = option.strokeWidth || 4;
this.scaleX = option.scaleX || 1;
this.scaleY = option.Y || 1;
this.opactity = option.opactity || 1;
this.counterclockwise =
option.counterclockwise === true ? true : option.counterclockwise || false;
this.startAngle = option.startAngle == 0 ? 0 : option.startAngle || 0;
this.endAngle = option.endAngle == 0 ? 0 : option.endAngle || 0;
this.startAngle = this.startAngle * Math.PI/180;
this.endAngle = this.endAngle * Math.PI / 180;
this.r = option.r || 100;
},
render: function( ctx ) {
ctx.save();
ctx.translate( this.x, this.y);
ctx.scale( this.scaleX, this.scaleY );
ctx.rotate( this.agnle * Math.PI / 180 );
ctx.globalAlpha = this.opacity;
ctx.fillStyle = this.fillStyle;
ctx.strokeStyle = this.strokeStyle;
ctx.moveTo(0, 0);
ctx.arc( 0, 0, this.r, this.startAngle, this.endAngle, this.counterclockwise);
ctx.fill();
ctx.stroke();
ctx.restore();
},
constructor: ItcastCircle
};
https://roopons.com.au/wp-content/plugins/viral-optins/js/rgraph/
http://www.egret-labs.org/
http://threejs.org/
Konva ``` 官网:http://konvajs.github.io/ 特点:
其他的还有很多,希望以后能用到你们的库。
``` //Konva使用的基本案例
//第一步:创建舞台
var stage = new Konva.Stage({
container: 'container', //需要存放舞台的Dom容器
width: window.innerWidth, //设置全屏
height: window.innerHeight
}); //第二步:创建层 var layer = new Konva.Layer(); //创建一个层 stage.add(layer); //把层添加到舞台 //第三步: 创建矩形 var rect = new Konva.Rect({ //创建一个矩形 x: 100, //矩形的x坐标,相对其父容器的坐标 y: 100, width: 100, //矩形的宽度 height: 100, //矩形高度 fill: 'gold', //矩形填充的颜色 stroke: 'navy', //矩形描边的颜色 strokeWidth: 4, //填充宽度 opactity: .2, //矩形的透明度 scale: 1.2, //矩形的缩放 1:原来大小 rotation: 30, //旋转的角度,是deg不是弧度。 cornerRadius: 10, //圆角的大小(像素) id: 'rect1', //id属性,类似dom的id属性 name: 'rect', draggable: true //是否可以进行拖拽 }); //创建一个组 var group = new Konva.Group({ x: 40, y: 40, }); group.add( rect ); //把矩形添加到组中 //第四步: 把形状放到层中 layer.add( group ); //把组添加到层中 layer.draw(); //绘制层到舞台上
```
13使用konva来绘制一个矩形
tween.play(); //启动动画 ```
tween的控制方法
tween的缓动控制选项
动画效果参考: 29Konva动画缓动效果案例.html
to就是对tween的封装,比较简单好用。 ``` //案例: var rect = new Konva.Rect({ x: 10, y: 10, width: 100, height: 100, fill: 'red' }); layer.add(rect); layer.draw();
//动画系统 rect.to({ x: 100, y: 100, opactity: .1, duration: 3, onFinish: function() {
}
});
//to: 就是对tween的简单应用。 ```
Animation动画,实际上就是浏览器通知开发者进行绘制,并提供当前的时间 ``` var anim = new Konva.Animation(function(frame) { //动画系统提供的frame有三个属性可以使用: var time = frame.time, // 动画执行的总时间 timeDiff = frame.timeDiff, // 距离上一帧的时间 frameRate = frame.frameRate; // 帧率(既1000/间隔时间)
//动画的动作
}, layer);
anim.start();//启动动画
//anim.stop();//结束动画 ```
//总体思路,使用tween 配合onFinish事件中重新播放动画,达到循环播放的效果
var loopTween = new Konva.Tween({
node: star, //设置要表现动画的 Konva对象
rotation: 360, //旋转360度
duration: 2, //动画持续时间
easing: Konva.Easings.Linear,
onFinish: function() {
// this === loopTween //true
this.reset();//重置动画
this.play(); //重新播放动画
}
});
loopTween.play();
rect.to({ duration: 2, scale: 1.5, yoyo: true// 此设置也可以用于 tween });
圆形上面的点的坐标的计算公式
group的灵活运用
var group = new Konva.Group({ x: 0, y: 0 }); group.add(rect);
``` var rect = new Konva.Rect({ x: 100, y: 100, fill: 'red', width: 200, height: 200 });
//绑定事件 Konva支持事件:mouseover, mouseout, mouseenter, mouseleave, mousemove, mousedown, mouseup, mousewheel, click, dblclick, dragstart, dragmove, and dragend
rect.on('click', function(){ //jQuery一模一样!!
console.log('^_^ ^_^');
});
//绑定多个事件
rect.on('click mousemove',function(e){
});
//解除绑定事件
rect.off('click'); //这不是jQuery吗?
//触发事件
rect.fire('click');
//取消事件冒泡
rect.on('click', function(evt) {
alert('You clicked the circle!');
evt.cancelBubble = true; //取消事件冒泡
});
```
//组中查找圆形的Konva对象 groupCircle.find('Circle').each(function( circle, index ){ circle.setZIndex( 3 - index ); });
```
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback, /* DOMElement */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// example code from mr doob : http://mrdoob.com/lab/javascript/requestanimationframe/
var canvas, context, toggle;
init(); animate();
function init() {
canvas = document.createElement( 'canvas' );
canvas.width = 512;
canvas.height = 512;
context = canvas.getContext( '2d' );
document.body.appendChild( canvas );
}
function animate() { requestAnimFrame( animate ); draw();
}
function draw() {
var time = new Date().getTime() * 0.002;
var x = Math.sin( time ) * 192 + 256;
var y = Math.cos( time * 0.9 ) * 192 + 256;
toggle = !toggle;
context.fillStyle = toggle ? 'rgb(200,200,20)' : 'rgb(20,20,200)';
context.beginPath();
context.arc( x, y, 10, 0, Math.PI * 2, true );
context.closePath();
context.fill();
}