canvas常用API 總結(jié)

getContext 獲取canvas繪圖的上下文環(huán)境
之后在繪圖環(huán)境上有以下API
lineJoin 線頭線尾的形狀 round為圓角
lineWidth 線的寬度
font 設(shè)置字體
fillText 填充文字 第一個(gè)參數(shù)是文本 第二個(gè)參數(shù)是X坐標(biāo)梯轻,第三個(gè)參數(shù)是Y坐標(biāo)
strokeRect 空心矩形顾彰,接收四個(gè)參數(shù)
fillStyle 填充樣式 可以接受rgba或漸變
漸變例子

var gradient=can2_context.createLinearGradient(0,500,0,700);
gradient.addColorStop(0,'blue')
gradient.addColorStop(0.25,'white')
gradient.addColorStop(1,'blue')
can2_context.fillStyle=gradient;
can2_context.fillRect(0,500,canvas_2.width,700)

createLinearGradient的四個(gè)參數(shù)表示漸變的方向 0,500,0,700表示的是垂直方向漸變
addColorStop 第一個(gè)參數(shù)填0~1之間的數(shù) 第二個(gè)參數(shù)添顏色
fillRect 實(shí)心矩形


放射性漸變
這里用到了createRadialGradient這個(gè)API 這個(gè)API接收6個(gè)參數(shù)署尤,前三個(gè)表示底下的圓,后三個(gè)表示上面的圓陆爽,返回的實(shí)例依然可以用addColorStop

function Radia(bottom_x,bottom_y,bottom_r,top_x,top_y,top_r){
  this.bottom_x=bottom_x;
  this.bottom_y=bottom_y;
  this.bottom_r=bottom_r;
  this.top_x=top_x;
  this.top_y=top_y;
  this.top_r=top_r;
  this.gradient=can2_context.createRadialGradient(this.bottom_x,this.bottom_y,this.bottom_r,this.top_x,this.top_y,this.top_r)
}
Radia.prototype.addColor=function(){
  
  for(var i=0;i<arguments.length;i++){
    this.gradient.addColorStop(arguments[i].num,arguments[i].color)
 }

}
Radia.prototype.draw=function(x1,y1,x2,y2){
   can2_context.fillStyle=this.gradient;
   can2_context.fillRect(x1,y1,x2,y2)
}

var some1=new Radia(canvas_2.width/2, canvas_2.height-100, 0, canvas_2.width/2, 0, 300)
some1.addColor({num:0.2,color:"blue"},{num:1,color:"yellow"},{num:0.7,color:"white"})
some1.draw(0, 0, canvas_2.width, canvas_2.height) 

圖像填充 createPattern
圖像填充也是一種fillStyle
該方法的第一個(gè)參數(shù)指定了圖案所用圖像,它可以是images元素扳缕,canvas元素或者video元素.第2個(gè)參數(shù)告訴瀏覽器慌闭,對(duì)圖形進(jìn)行掃描或填充時(shí),應(yīng)該如何重復(fù)該圖案躯舔,這個(gè)參數(shù)的有效值是repeat,repeat-x,repeat-y,no-repeat

var canvas_2=document.getElementById("canvas_2");
var can2_context=canvas_2.getContext("2d");
var img=new Image();
img.src='./images/hover2.png'

function fillimage(){
    var pattern=can2_context.createPattern(img,'no-repeat')
    can2_context.fillStyle=pattern;
    can2_context.fillRect(0,0,canvas_2.width,canvas_2.height)
    

}
img.onload=function(e){
  fillimage()
}

canvas陰影
盡量不要用canvas做出陰影 因?yàn)樾什⒉皇悄敲锤?/p>

shadowBlur表示陰影效果如何延伸double值驴剔。瀏覽器在陰影智商運(yùn)用高斯模糊時(shí),將會(huì)用到該值庸毫,它與像素?zé)o關(guān)仔拟,只會(huì)被用到高斯模糊方程之中,其默認(rèn)值為0
shadowColor CSS格式的顏色字符串飒赃,默認(rèn)值是rgba(0,0,0,0)
shadowOffsetX 陰影在X軸方向的偏移量利花,以像素為單位科侈,默認(rèn)值為0
shadowOffsetY 陰影在Y軸方向的偏移量,以像素為單位炒事,默認(rèn)值是0

var canvas_2=document.getElementById("canvas_2");
var can2_context=canvas_2.getContext("2d");

var SHADOW_COLOR='rgba(0,0,0,0.7)'
function setShadow(){
  can2_context.shadowColor=SHADOW_COLOR;
  can2_context.shadowOffsetX=3;
  can2_context.shadowOffsetY=3; 
  can2_context.shadowBlur=5
}
setShadow();
can2_context.fillStyle="blue"
can2_context.fillRect(0,0,100,100)

關(guān)于beginPath

can2_context.beginPath();
 can2_context.rect(10,10,100,100)
 can2_context.stroke();

//  can2_context.beginPath()
 can2_context.rect(50,50,100,100)
 can2_context.stroke()

先調(diào)用beginPath()來(lái)清楚當(dāng)前路徑中的所有子路徑臀栈,然后調(diào)用rect()來(lái)創(chuàng)建一條包含矩形4個(gè)點(diǎn)的子路徑,再調(diào)用stroke()方法使得這個(gè)矩形出現(xiàn)在canvas上挠乳。
接下來(lái)這段代碼再次調(diào)用rect()方法权薯,不過(guò)這一次,由于沒(méi)有調(diào)用beginPath()方法清除原有的路徑睡扬,所以第二次對(duì)rect()的方法的調(diào)用盟蚣,會(huì)向當(dāng)前中增加一條子路徑。最后該段代碼再一次調(diào)用stroke()方法卖怜。這次stroke()方法的調(diào)用屎开,將會(huì)使得當(dāng)前路徑中的兩條子路徑都被描邊,這意味著它會(huì)重繪第一個(gè)矩形


關(guān)于非零環(huán)繞原則

“非零環(huán)繞規(guī)則”是這么來(lái)判斷有自我交叉情況的路徑的:
對(duì)于路徑中的任意給定區(qū)域马靠,從該區(qū)域內(nèi)部畫一條足夠長(zhǎng)的線段
使此線段的終點(diǎn)完全落在路徑范圍之外奄抽。
接下來(lái),將計(jì)數(shù)器初始化為0甩鳄,然后逞度,每當(dāng)這條線段與路徑上的直線或曲線相交時(shí),就
改變計(jì)數(shù)器的值妙啃。如果是與路徑順時(shí)針部分相交档泽,則加1,如果是與路徑逆時(shí)針部分相交就
減一彬祖。若計(jì)數(shù)器的最終值不是0茁瘦,那么此區(qū)域就在路徑里面,在調(diào)用fill()方法時(shí)储笑,瀏覽器就會(huì)對(duì)其進(jìn)行填充甜熔。如果最終值是0,那么此區(qū)域就不在路徑內(nèi)部突倍,瀏覽器也就不會(huì)對(duì)其進(jìn)行填充


剪紙漏洞效果主要是利用了canvas的非零環(huán)繞規(guī)則
簡(jiǎn)單來(lái)說(shuō)就是canvas fill填充的是同一路徑順時(shí)針和逆時(shí)針中間的部分腔稀,簡(jiǎn)稱
非零環(huán)繞

var canvas_2=document.getElementById("canvas_2");
var can2_context=canvas_2.getContext("2d");
var width_2=canvas_2.width
var height_2=canvas_2.height
var testx=300
var testy=300
function drawCutouts(){

    can2_context.beginPath();
    addOurterRectanglePath()
    addrect()
    addTrianglePath()
    addarc()
    can2_context.fill()
}

function addOurterRectanglePath(){
     can2_context.rect(110,25,370,335)
     can2_context.closePath()
}


function rect(x,y,w,h,direction){

    if(direction){
        can2_context.moveTo(x,y);
        can2_context.lineTo(x,y+h)
        can2_context.lineTo(x+w,y+h)
        can2_context.lineTo(x+w,y)
    }else{
        can2_context.moveTo(x,y)
        can2_context.lineTo(x+w,y)
        can2_context.lineTo(x+w,y+h)
        can2_context.lineTo(x,y+h)

    }
    can2_context.closePath()
}
function addrect(){
    rect(310,55,70,35,true)  //true為逆時(shí)針
}
function addTrianglePath(){
   
   can2_context.moveTo(400,200)
   can2_context.lineTo(250,115)
   can2_context.lineTo(200,200)
   can2_context.closePath()

}



function addarc(){
    if(testy>335){testy=25}
    testy=testy+1
    
    can2_context.arc(testx,testy,40,0,Math.PI*2,true)
   
}

function hi(){
   can2_context.clearRect(0,0,width_2,height_2)
   drawCutouts()

   requestAnimationFrame(hi)

}
hi()

getBoundingClientRect,getImageData羽历,putImageData
//getBoundingClientRect 返回元素的6個(gè)值 left top right bottom width height
注意這里的left top right bottom 都是相對(duì)于可視窗口的左上角的
width是元素的寬度
height是元素的高度
var bbox=canvas.getBoundingClientRect()
bbox.left

bbox.right

//getImageData() 方法返回 ImageData 對(duì)象焊虏,該對(duì)象拷貝了畫布指定矩形的像素?cái)?shù)據(jù)。
//context.getImageData(0,0,canvas.width,canvas.height)

//putImageData() 方法將圖像數(shù)據(jù)(從指定的 ImageData 對(duì)象)放回畫布上秕磷。
//context.putImageData(drawingSurfaceImageData,0,0)


canvas橡皮筋式線段繪制

context.save() 設(shè)置繪圖環(huán)境存檔
context.restore() 讀取繪圖環(huán)境存檔
Math.abs()求絕對(duì)值

var canvas=document.getElementById("canvas"),
   context=canvas.getContext("2d"),
   eraseAllButton=document.getElementById("eraseAllButton"),
   strokeStyleSelect=document.getElementById("strokeStyleSelect"),
   guidewireCheckbox=document.getElementById("guidewireCheckbox"),
   drawingSurfaceImageData,
   mousedown={},
   rubberbandRect={},
   dragging=false,
   guidewires=guidewireCheckbox.checked;


    function windowToCanvas(x,y){
        var bbox=canvas.getBoundingClientRect()//getBoundingClientRect 返回元素的6個(gè)值 left top right bottom width height
     
        return {
            x:x-bbox.left*(canvas.width/bbox.width),
            y:y-bbox.top*(canvas.height/bbox.height)
        }
    }

    function saveDrawingSurface(){
        drawingSurfaceImageData=context.getImageData(0,0,canvas.width,canvas.height) 
     //getImageData() 方法返回 ImageData 對(duì)象诵闭,該對(duì)象拷貝了畫布指定矩形的像素?cái)?shù)據(jù)。
    }
    
    function restoreDrawingSurface(){
        context.putImageData(drawingSurfaceImageData,0,0)
        //putImageData() 方法將圖像數(shù)據(jù)(從指定的 ImageData 對(duì)象)放回畫布上。
    }

   function updateRubberbandRectangle(loc){
       rubberbandRect.width=Math.abs(loc.x-mousedown.x)  //用絕對(duì)值求線段的長(zhǎng)度
       rubberbandRect.height=Math.abs(loc.y-mousedown.y)  //用絕對(duì)值求線段的高度

       if(loc.x>mousedown.x){rubberbandRect.left=mousedown.x}else{
           rubberbandRect.left=loc.x
       }
       if(loc.y>mousedown.y){rubberbandRect.top=mousedown.y}else{
           rubberbandRect.top=loc.y
       }
   }
   function drawRubberbandShape(loc){

       context.beginPath()
       context.moveTo(mousedown.x,mousedown.y)
       context.lineTo(loc.x,loc.y)
       context.stroke()
   }
   function updataRubberband(loc){  //loc是鼠標(biāo)點(diǎn)在canvas上的坐標(biāo)集合對(duì)象
      // updateRubberbandRectangle(loc)
       drawRubberbandShape(loc)
   }
//這三個(gè)函數(shù)式輔助線函數(shù)
   function drawHorizontalLine(y){
       context.beginPath()
       context.moveTo(0,y+0.5)
       context.lineTo(context.canvas.width,y+0.5)
       context.stroke()
   }
   function drawVerticalLine(x){
       context.beginPath()
       context.moveTo(x+0.5,0)
       context.lineTo(x+0.5,context.canvas.height)
       context.stroke()

   }
   function drawGuidewires(x,y){
       context.save()
       context.strokeStyle="rgba(0,0,230,0.4)"
       context.lineWidth=0.5;
       drawVerticalLine(x)
       drawHorizontalLine(y)
       context.restore()
   }
//這三個(gè)函數(shù)式輔助線函數(shù)
   canvas.onmousedown=function(e){  //只執(zhí)行一次
     var loc=windowToCanvas(e.clientX,e.clientY); //獲取鼠標(biāo)點(diǎn)在canvas的點(diǎn)坐標(biāo)
     e.preventDefault();
     saveDrawingSurface()                         //復(fù)制canvas畫布的像素
     mousedown.x=loc.x;                          //鼠標(biāo)點(diǎn)擊的x軸坐標(biāo)  這里mousedown記錄的是初始位置
     mousedown.y=loc.y;                          //鼠標(biāo)點(diǎn)擊的y軸坐標(biāo)   這里mousedown記錄的是初始位置
     dragging=true;
 }
canvas.onmousemove=function(e){
       var loc;
       if(dragging){
           e.preventDefault()
           loc=windowToCanvas(e.clientX,e.clientY);
           restoreDrawingSurface()
           updataRubberband(loc)  //loc是鼠標(biāo)點(diǎn)在canvas上的坐標(biāo)集合對(duì)象
           if(guidewires){        //輔助線
               drawGuidewires(loc.x,loc.y)
           }
       }
   }
   canvas.onmouseup=function(e){
       loc=windowToCanvas(e.clientX,e.clientY)
       restoreDrawingSurface()
       updataRubberband(loc)
       dragging=false
   }
   strokeStyleSelect.onchange=function(){

       context.strokeStyle=strokeStyleSelect.value
   }

三次方貝塞爾曲線的繪制

bezierCurveTo
創(chuàng)建一條代表三次方貝塞爾曲線的路徑疏尿。你需要向該方法傳入三個(gè)點(diǎn)的坐標(biāo)
瘟芝,前兩個(gè)點(diǎn)是該曲線的控制點(diǎn),最后一個(gè)是錨點(diǎn)


canvas畫多邊形

由于canvas只提供了畫矩形和圓形的方法褥琐,
所以涉及到多邊形的話锌俱,只能自己寫方法
其中涉及到 三角函數(shù)的API 比如
Math.PI圓周率
Math.sin
Math.cos
這倆就不多介紹了 sin cos 中學(xué)學(xué)的
大致思路就是只要有中心點(diǎn) 半徑 就可以想畫幾邊形就畫幾邊形,
廢話不多說(shuō)敌呈,上代碼

var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");

var Point = function (x, y) {
   this.x = x;
   this.y = y;
};

var Polygon=function(centerX,centerY,radius,sides,startAngle,strokeStyle,fillStyle,filled){

    this.x=centerX;
    this.y=centerY;
    this.radius=radius;
    this.sides=sides;
    this.startAngle=startAngle;
    this.strokeStyle=strokeStyle;
    this.fillStyle=fillStyle;
    this.filled=filled;
}
Polygon.prototype={
   getPoints:function(){
     var points=[];
     var angle=this.startAngle||0;
     for(var i=0;i<this.sides;i++){
         points.push(new Point(this.x+this.radius*Math.cos(angle),this.y-this.radius*Math.sin(angle)))
         angle+=2*Math.PI/this.sides

     }
    return points

   },
   createPath:function(){
      var points=this.getPoints()
      context.beginPath()
      context.moveTo(points[0].x,points[0].y);
      for(var i=1;i<points.length;i++){
          context.lineTo(points[i].x,points[i].y)
      }
      context.closePath()
   },
   stroke:function(){
       context.save()
       this.createPath()
       context.strokeStyle=this.strokeStyle;
       context.stroke();
       context.restore();
   },
   fill:function(){
      context.save();
      context.fillStyle=this.fillStyle;
      this.createPath()
      context.fill()
      context.restore()

   },

   move: function (x, y) {
          this.x = x;
           this.y = y;
    }

}
var test1=new Polygon(50,50,30,8,0,"red","red")
test1.stroke()

var test2=new Polygon(150,150,30,4,0,"red","red")
test2.fill()


isPointInPath
isPointInPath表示某個(gè)點(diǎn)在當(dāng)前路徑中就會(huì)返回true 反之返回false

var edite=false
var mousedown={}//記錄鼠標(biāo)按下起始點(diǎn)
var imageData1=null;
var mouseIn=null;//記錄鼠標(biāo)是否按了下去
var line_list={} //記錄鼠標(biāo)的終點(diǎn)

var Graphical=[];//存放圖形引用的數(shù)組
var edit_list={}//記錄在編輯模式下按的點(diǎn)
var map_name=null//每個(gè)生成圖形的名稱
var foucsIndex=null //被選中移動(dòng)圖形的下標(biāo)


function saveImage(){  //儲(chǔ)存此刻畫布數(shù)據(jù)
      imageData1= context.getImageData(0,0,canvas.width,canvas.height)
}
function loadingImage(){ //導(dǎo)入畫布數(shù)據(jù)
  context.putImageData(imageData1,0,0)
}



editCheckbox.onchange=function(){
  if(this.checked){
   console.log("進(jìn)入編輯模式")
   edite=true
  }else{
   console.log("進(jìn)入畫圖模式")
   edite=false
  }

}

function windowToCanvas(event){  //算出你點(diǎn)擊在canvas畫布的坐標(biāo) 并返回
   var rect=canvas.getBoundingClientRect()
   return {
      x:event.clientX-rect.left,
      y:event.clientY-rect.top
   } 
}
function line_width(){
  var x_width=Math.abs(line_list.x-mousedown.x)
  var y_width=Math.abs(line_list.y-mousedown.y)
  
  return Math.sqrt(x_width*x_width+y_width*y_width) 
}



canvas.onmousedown=function(event){
    saveImage()
    var some=windowToCanvas(event)
   
    mousedown.x=some.x;
    mousedown.y=some.y
    
    mouseIn=true
    
    Graphical.forEach(function(el,index){
        el.createPath(context)
        if(context.isPointInPath(mousedown.x,mousedown.y)){
            edit_list.x=some.x;
            edit_list.y=some.y
            foucsIndex=index
         
        }

   
    })
   
}
canvas.onmousemove=function(event){

     if(mouseIn&&edite){//如果按下鼠標(biāo)并拖行 如果是編輯模式
        loadingImage()
           
            
            var offset_list=windowToCanvas(event);
            var offsetX=offset_list.x-edit_list.x;
            var offsetY=offset_list.y-edit_list.y;
            context.clearRect(0,0,canvas.width,canvas.height)
            Graphical[foucsIndex].move(mousedown.x+offsetX,mousedown.y+offsetY)
            Graphical.forEach(function(el){
                el.createPath(context)
                el.fill(context)
            })
     } 


  
    if(mouseIn&&!edite){//如果按下鼠標(biāo)并拖行 如果不是編輯模式
        loadingImage()
        line_list=windowToCanvas(event)
        context.beginPath()

        var r=line_width()

        map_name=new Polygon(mousedown.x,mousedown.y,r,sidesSelect.value,0,"red","red")
        map_name.fill(context)
   
        
    }
}

canvas.onmouseup=function(){


    mouseIn=false //鼠標(biāo)抬起來(lái)了
    if(!edite){
        Graphical.push(map_name)
    }

}

globalCompositeOperation
利用修改globalCompositeOperation改變canvas圖像默認(rèn)合成行為
<select name="" id="compositingSelect" size="11">
<option value="source-atop">source-atop</option>
<option value="source-in">source-in</option>
<option value="source-out">source-out</option>
<option value="source-over">source-over</option>
<option value="destination-atop">destination-atop</option>
<option value="destination-in">destination-in</option>
<option value="destination-out">destination-out</option>
<option value="destination-over">destination-over</option>
<option value="lighter">lighter</option>
<option value="copy">copy</option>
<option value="xor">xor</option>
</select>

11個(gè)合成行為


clip()剪切區(qū)域

這里有個(gè)坑要十分注意 調(diào)用clip()方法的時(shí)候贸宏,所定義的剪輯區(qū)域總是局限于期初的那個(gè)剪輯區(qū)域范圍。
簡(jiǎn)單來(lái)說(shuō) clip()方法總是在上一次的剪輯區(qū)域基礎(chǔ)上進(jìn)行操作磕洪,所以說(shuō)我們要把clip()方法放在save()和restore()方法中
clip 是對(duì)已有路徑的剪切

var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")

function windowToCanvas(x,y){

    var bbox=canvas.getBoundingClientRect()
    return {
        x:x-bbox.left,
        y:y-bbox.top
    }
}

function drawText(){

    context.save()
    context.shadowColor="rgba(100,100,150,0.8)"
    context.shadowOffsetX=5;
    context.shadowOffsetY=5;
    context.shadowBlur=10;

    context.fillStyle="cornflowerblue"
    context.fillText("HTML5",20,250)
    context.strokeStyle="yellow"
    context.strokeText("HTML5",20,250)
    context.restore()

}

function setClippingRegion(radius){
    context.beginPath()
    context.arc(canvas.width/2,canvas.height/2,radius,0,Math.PI*2,false)
    context.clip()
}

function fillCanvas(color){
    context.fillStyle=color
    context.fillRect(0,0,canvas.width,canvas.height)
}

function endAnimation(loop){

    clearInterval(loop)
    setTimeout(function(e){
        context.clearRect(0,0,canvas.width,canvas.height)
        drawText()
    },1000)
}

function drawAnimationFrame(radius){
   setClippingRegion(radius);
   fillCanvas('lightgray')
   drawText()

}
function animate(){
   var radius=canvas.width/2,
       loop;
    loop=window.setInterval(function(){
        radius-=canvas.width/100
        fillCanvas('charcoal')
        if(radius>0){
            context.save()
            drawAnimationFrame(radius)
            context.restore()
        }else{
            endAnimation(loop)
        }
    },16)   

}

canvas.onmousedown=function(){
    animate()
}
context.lineWidth=0.5
context.font='128pt Comic-sans'
drawText()

canvas制造漸變和圖案填充文字.

這里主要是利用了 context的createPattern的方法
這個(gè)方法接受兩個(gè)參數(shù) 第一個(gè)參數(shù)是要填充的圖案吭练,第二個(gè)參數(shù)是圖案重復(fù)方式

制造顏色漸變的方法是createLinearGradient

var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")
var image=new Image();
var gradient=context.createLinearGradient(0,0,canvas.width,canvas.height)
var text="Canvas"
var pattern;
function drawGradientText(){
  context.fillStyle=gradient
  context.fillText(text,65,200)
  context.strokeText(text,65,200)

}
function drawPatternText(){
    context.fillStyle=pattern
    context.fillText(text,65,450)
    context.strokeText(text,65,450)
}
image.onload=function(e){
    pattern=context.createPattern(image,"repeat")
    drawPatternText()
}
image.src="./images/hover2.png"
context.font="256px Palation"
context.strokeStyle="cornflowerblue"



context.shadowColor="rgba(100,100,150,0.8)"
context.shadowOffsetX=5
context.shadowOffsetY=5
context.shadowBlur=10

gradient.addColorStop(0,"blue")
gradient.addColorStop(0.25,"blue")
gradient.addColorStop(0.5,"white")
gradient.addColorStop(0.75,'red')
gradient.addColorStop(1.0,'yellow')

drawGradientText()

canvas在圓弧周圍繪制文本的兩種寫法

    var canvas=document.getElementById("canvas")
    var context=canvas.getContext("2d")

    var TEXT_FILL_STYLE="rgba(100,130,240,0.5)"
    var TEXT_STROKE_STYLE="rgba(200,0,0,0.7)"
    var TEXT_SIZE=64;
    circle={
        x:canvas.width/2,
        y:canvas.height/2,
        radius:200
    }
    function drawCircularText(string,startAngle,endAngle){
      var radius=circle.radius //圓的半徑
      var angleDecrement=(startAngle-endAngle)/(string.length-1)//每個(gè)字母占的弧度
      var angle=parseFloat(startAngle) //轉(zhuǎn)一下數(shù)字
      var index=0;
      var character;

      context.save()
      context.fillStyle=TEXT_FILL_STYLE;
      context.strokeStyle=TEXT_STROKE_STYLE;
      context.font=TEXT_SIZE+"px Lucida Sans"

      while(index<string.length){
        character=string.charAt(index)
        context.save()
        context.beginPath()
        context.translate(circle.x+Math.cos(angle)*radius,circle.y-Math.sin(angle)*radius)
        context.rotate(Math.PI/2-angle)   //Math.PI/2為旋轉(zhuǎn)90度  Math.PI/180*X為旋轉(zhuǎn)多少度
        context.fillText(character,0,0)
        context.strokeText(character,0,0)
        angle-=angleDecrement
        index++
        context.restore()

      }
      context.restore()




    }
    context.textAlign="center"
    context.textBaseLine="middle"
   drawCircularText("clockwise around the circle",Math.PI*2,Math.PI/8)

canvas實(shí)現(xiàn)圖像的縮放

這里需要注意的是如果你向canvas之中繪制的圖像有一部分落在canvas之外,
那么瀏覽器就會(huì)將canvas范圍外的那部分圖像忽略掉

var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")

var image=new Image()
var scaleSlider=document.getElementById("scaleSlider")
var scale=1.0
var MINIMUM_SCALE=1.0
var MAXIMUN_SCALE=3.0

function drawImage(){
 var w=canvas.width
 var h=canvas.height
 var sw=w*scale
 var sh=h*scale
 context.clearRect(0,0,canvas.width,canvas.height)
 context.drawImage(image,-sw/2+w/2,-sh/2+h/2,sw,sh)

}
function drawScaleText(value){
  var text=parseFloat(value).toFixed(2)

  scaleOutput.innerText=text



}
scaleSlider.onchange=function(e){
  scale=e.target.value
  if(scale<MINIMUM_SCALE){scale=MINIMUM_SCALE}
    else if(scale>MAXIMUN_SCALE){scale=MAXIMUN_SCALE}
      drawScaleText(scale)
    drawImage()

}
image.src="./timg.jpg"
image.onload=function(e){
   drawImage()
   drawScaleText(scaleSlider.value)
}

利用離屏canvas提高復(fù)制圖像放大的效率并添加水印

<!DOCTYPE html>
<html>
<head>
    <title>圖像與視頻</title>
    <meta charset="utf-8">
    <style type="text/css">
  *{padding: 0;margin: 0}
  a{text-decoration: none}
  img{border: none}
  ul,ol{list-style: none}
  br{font-size: 0;line-height: 0;clear: both}
  body{text-align: center;background: rgba(100,145,250,0.3)}
  canvas{border: 1px solid blue}
  #scaleSlider{
    vertical-align: 10px;
    width: 100px;
    margin-left: 90px;
  }
  #canvas{
    margin:10px 20px 0px 20px;
    border: thin solid #aaaaaa;
    cursor:crosshair;
  }
  #controls{
    margin-left: 15px;
    padding: 0
  }
  #scaleOutput{
    position: absolute;
    width: 60px;
    height: 30px;
    margin-left: 10px;
    vertical-align: center;
    text-align:center;
    color: blue;
    font:18px Arial;
    text-shadow: 2px 2px 4px rgba(100,140,250,0.8)
  }
    </style>
</head>
<body>
<div id="controls">
    <output id="scaleOutput">1.0</output>
    <input type="range" name="" id="scaleSlider" min="1" max="3.0" step="0.01" value="1.0">
</div>
<canvas id="canvas" id="canvas" width="454" height="512"></canvas>

</body>
</html>
<script type="text/javascript">
var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")
var offscreenCanvas=document.createElement("canvas")  //創(chuàng)建離屏canvas
var offscreenContext=offscreenCanvas.getContext("2d")
offscreenCanvas.width=canvas.width
offscreenCanvas.height=canvas.height



var image=new Image()
var scaleSlider=document.getElementById("scaleSlider")
var scaleOutput=document.getElementById("scaleOutput")

//var scale=scaleSlider.value
var scale=1.0
var MINIMUM_SCALE=1.0
var MAXIMUN_SCALE=3.0

function drawScaled(){  //從離屏canvas復(fù)制過(guò)來(lái)圖像并放大
  var w=canvas.width;
  var h=canvas.height;
  var sw=w*scale;
  var sh=h*scale;
context.drawImage(offscreenCanvas,0,0,offscreenCanvas.width,offscreenCanvas.height,-sw/2+w/2,-sh/2+h/2,sw,sh)
}
function drawScaleText(value){  //顯示放大倍率
var text=parseFloat(value).toFixed(2) 
scaleOutput.innerText=text

}
function drawWatermark(context){ //添加水印
  var lineOne='Copyright'
  var lineTwo='Acme Inc'
  var textMetrics
  var FONT_HEIGHT=128
  context.save()
  context.font=FONT_HEIGHT+"px Arial"
  textMetrics=context.measureText(lineOne)
  context.globalAlpha=0.6
  context.fillStyle="cornflowerblue"
  context.strokeStyle="yellow"
  context.shadowColor='rgba(50,50,50,1.0)'
  context.shaowOffsetX=5

  context.translate(canvas.width/2,canvas.height/2-FONT_HEIGHT/2)
  context.fillText(lineOne,-textMetrics.width/2,0)
  context.strokeText(lineOne,-textMetrics.width/2,0)

  textMetrics=context.measureText(lineTwo)
  context.fillText(lineTwo,-textMetrics.width/2,FONT_HEIGHT)
  context.strokeText(lineTwo,-textMetrics.width/2,FONT_HEIGHT)

  context.restore()
}

scaleSlider.onchange=function(e)
   scale=e.target.value

   if (scale<MINIMUM_SCALE){scale=MINIMUM_SCALE}
   else if(scale>MAXIMUN_SCALE){scale=MAXIMUN_SCALE}
   drawScaled()
   drawScaleText(scale)

}

image.src="./timg.jpg"
image.onload=function(){
  context.drawImage(image,0,0,canvas.width,canvas.height)
  offscreenContext.drawImage(canvas,0,0,canvas.width,canvas.height)
  drawWatermark(context)
  drawWatermark(offscreenContext)
  drawScaleText(scale)

}







</script>

利用離屏canvas 手動(dòng)放大圖片任意局部位置效果
這里最重要的就是rubberbandEnd這個(gè)函數(shù) 它會(huì)判斷鼠標(biāo)從按下到松開(kāi) 有沒(méi)有位移過(guò) 如果沒(méi)有就return 最后把離屏的圖片選取局部復(fù)制到可見(jiàn)的canvas之中

<!DOCTYPE html>
<html>
<head>
    <title>圖像與視頻</title>
    <meta charset="utf-8">
    <style type="text/css">
  *{padding: 0;margin: 0}
  a{text-decoration: none}
  img{border: none}
  ul,ol{list-style: none}
  br{font-size: 0;line-height: 0;clear: both}
  body{text-align: center;background: rgba(100,145,250,0.3)}
  canvas{border: 1px solid blue}
  #scaleSlider{
    vertical-align: 10px;
    width: 100px;
    margin-left: 90px;
  }
  #canvas{
    margin:10px 20px 0px 20px;
    border: thin solid #aaaaaa;
    cursor:crosshair;
  }
  #controls{
    margin-left: 15px;
    padding: 0
  }
  #scaleOutput{
    position: absolute;
    width: 60px;
    height: 30px;
    margin-left: 10px;
    vertical-align: center;
    text-align:center;
    color: blue;
    font:18px Arial;
    text-shadow: 2px 2px 4px rgba(100,140,250,0.8)
  }
    </style>
</head>
<body>
      <div id='controls'>
         <input type='button' id='resetButton' value='Reset'/>
      </div>
<canvas id="canvas" id="canvas" width="454" height="512"></canvas>

</body>
</html>
<script type="text/javascript">
console.log("start")
var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")
var offscreenCanvas=document.createElement("canvas")  //創(chuàng)建離屏canvas
var offscreenContext=offscreenCanvas.getContext("2d")
offscreenCanvas.width=canvas.width
offscreenCanvas.height=canvas.height
var mousedown={}
var rubberbandRectangle={}
var dragging=false;
var start_data;


context.fillStyle='rgba(155,187,89,0.3)'
context.lineWidth=2
function windowToCanvas(canvas,x,y){
  var bbox=canvas.getBoundingClientRect()
  return {
     x:x-bbox.left,
     y:y-bbox.top
  }


}


function rubberbandStretch(x,y){

   rubberbandRectangle.left=Math.min(x,mousedown.x)
   rubberbandRectangle.top=Math.min(y,mousedown.y)
   rubberbandRectangle.width=Math.abs(x-mousedown.x)
   rubberbandRectangle.height=Math.abs(y-mousedown.y)

   
   context.fillRect(rubberbandRectangle.left+context.lineWidth,
                    rubberbandRectangle.top+context.lineWidth,
                    rubberbandRectangle.width-2*context.lineWidth,
                    rubberbandRectangle.height-2*context.lineWidth)


}
function rubberbandEnd(x,y){
  if(x==rubberbandRectangle.left||y==rubberbandRectangle.top){
    dragging=false;


    return
  }

  context.clearRect(0,0,canvas.width,canvas.height)
  context.drawImage(offscreenCanvas,rubberbandRectangle.left+context.lineWidth*2,
                           rubberbandRectangle.top+context.lineWidth*2,
                          rubberbandRectangle.width-4*context.lineWidth,
                          rubberbandRectangle.height-4*context.lineWidth,
                           0,0,canvas.width,canvas.height)

  offscreenContext.drawImage(canvas,0,0,canvas.width,canvas.height)
  dragging=false;

  

}
canvas.onmousedown=function(e){
 var loc=windowToCanvas(canvas,e.clientX,e.clientY) //獲取鼠標(biāo)點(diǎn)擊在canvas的坐標(biāo)
  e.preventDefault()
 

  mousedown.x=loc.x
  mousedown.y=loc.y;
  rubberbandRectangle.left=mousedown.x
  rubberbandRectangle.top=mousedown.y
  dragging=true

}
canvas.onmousemove=function(e){
 var loc
 if(dragging){

   context.clearRect(0,0,canvas.width,canvas.height)
   context.drawImage(offscreenCanvas,0,0,canvas.width,canvas.height) //把離屏canvas上的數(shù)據(jù)復(fù)制到當(dāng)前canvas
   loc=windowToCanvas(canvas,e.clientX,e.clientY)
   rubberbandStretch(loc.x,loc.y)   //計(jì)算出選中的矩形坐標(biāo)
 }

}


canvas.onmouseup=function(e){
  var loc=windowToCanvas(canvas,e.clientY,e.clientY)
  
  rubberbandEnd(loc.x,loc.y)  //鼠標(biāo)抬起 開(kāi)始從離屏canvas復(fù)制數(shù)據(jù)
}
resetButton.onclick=function(e){
    dragging=false;

   context.clearRect(0,0,canvas.width,canvas.height)

   context.putImageData(start_data,0,0)
   offscreenContext.putImageData(start_data,0,0)
   
}
function start(){
var src="./timg.jpg"
var img=new Image()
img.src=src
window.onload=function(){
      context.drawImage(img,0,0,canvas.width,canvas.height)
      start_data=context.getImageData(0,0,canvas.width,canvas.height)    //記錄初始數(shù)據(jù)以備還原使用
      offscreenContext.drawImage(img,0,0,offscreenCanvas.width,offscreenCanvas.height)  //離屏canvas儲(chǔ)存圖像
      }

}
start()











</script>

canvas利用requestNextAnimationFrame做動(dòng)畫及碰撞檢測(cè)

<!DOCTYPE html>
   <head>
     <title>Video</title>

      <style> 
         body {
            background: #dddddd;
         }

         #canvas {
            background: #ffffff;
            cursor: pointer;
            margin-left: 10px;
            margin-top: 10px;
            -webkit-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
            -moz-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
            box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
         }

         #controls {
            margin-top: 10px;
            margin-left: 15px;
         }
      </style>
   </head>

  <body>
      <div id='controls'>
         <input id='animateButton' type='button' value='Animate'/>
      </div>

      <canvas id='canvas' width='750' height='500'>
         Canvas not supported
      </canvas>


  </body>
</html>
<script type="text/javascript" src="./js/requestNextAnimationFrame.js"></script>
<script type="text/javascript">
   var canvas=document.getElementById("canvas")
   var context=canvas.getContext("2d")
   var paused=true

   var discs=[
    {x:150,
      y:250,
      lastX:150,
      lastY:250,
      velocityX:-3.2,  //橫坐標(biāo)速率
      velocityY:3.5,   //縱坐標(biāo)速率
      radius:25,
      innerColor:"rgba(255,255,0,1)",
      middleColor:"rgba(255,255,0,0.7)",
      outerColor:"rgba(255,255,0,0.5)",
      strokeStyle:"gray"

    },
      { 
         x: 50,
         y: 150,
         lastX: 50,
         lastY: 150,
         velocityX: 2.2,  //橫坐標(biāo)速率
         velocityY: 2.5,  //縱坐標(biāo)速率
         radius: 25,
         innerColor: 'rgba(100,145,230,1.0)',
         middleColor: 'rgba(100,145,230,0.7)',
         outerColor: 'rgba(100,145,230,0.5)',
         strokeStyle: 'blue'
      },

      { 
         x: 150,
         y: 75,
         lastX: 150,
         lastY: 75,
         velocityX: 1.2,
         velocityY: 1.5,
         radius: 25,
         innerColor: 'rgba(255,0,0,1.0)',
         middleColor: 'rgba(255,0,0,0.7)',
         outerColor: 'rgba(255,0,0,0.5)',
         strokeStyle: 'orange'
      }


   ]
  var numDiscs=discs.length; //圓的個(gè)數(shù)
  var animateButton=document.getElementById("animateButton")

 function update(){
    var disc=null
    for(var i=0;i<discs.length;i++){
       disc=discs[i]
       if(disc.x+disc.velocityX+disc.radius>canvas.width||disc.x-disc.radius+disc.velocityX<0){ //碰撞檢測(cè)
        disc.velocityX=-disc.velocityX
       }
       if(disc.y+disc.velocityY+disc.radius>canvas.height||disc.y-disc.radius+disc.velocityY<0){ //碰撞檢測(cè)
          disc.velocityY=-disc.velocityY
       }
       
      disc.x+=disc.velocityX
      disc.y+=disc.velocityY

    }



 }
function draw(){
   var disc=null

   for(var i=0;i<discs.length;i++){
        disc=discs[i]
        gradient=context.createRadialGradient(disc.x,disc.y,0,disc.x,disc.y,disc.radius)
        gradient.addColorStop(0.3,disc.innerColor)
        gradient.addColorStop(0.5,disc.middleColor)
        gradient.addColorStop(1.0,disc.outerColor)
        context.save()
        context.beginPath()
        context.arc(disc.x,disc.y,disc.radius,0,Math.PI*2,false)
        context.fillStyle=gradient
        context.strokeStyle=disc.strokeStyle
        context.fill()
        context.stroke()
        context.restore()
   }


}
function animation(time){
  if(!paused){
    context.clearRect(0,0,canvas.width,canvas.height)
    draw()
    update()
    
    window.requestNextAnimationFrame(animation)
  }
 


}

animateButton.onclick=function(e){
 paused=!paused
 if(paused){
  animateButton.value="Animation"
 }else{
  window.requestNextAnimationFrame(animation)
  animateButton.value="Pause"

 }


}







    


</script>

canvas制作無(wú)限視差滾動(dòng)背景圖

<!DOCTYPE html>
<html>
<head>
    <title>背景滾動(dòng)</title>
   <meta charset="utf-8">
        <style> 
           body {
                background: #dddddd;
            }

            #canvas {
            position: absolute;
            top: 30px;
            left: 10px;
            background: #ffffff;
            cursor: crosshair;
            margin-left: 10px;
            margin-top: 10px;
            -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            }

         input {
            margin-left: 15px;
            }

        </style>

</head>
<body>
    <canvas id='canvas' width='1024' height='512'>
      Canvas not supported
    </canvas>

    <input id='animateButton' type='button' value='Animate'/>

    <script src='./js/requestNextAnimationFrame.js'></script>
   
</body>
</html>


<script type="text/javascript">
var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")
var animateButton=document.getElementById("animateButton")

var sky=new Image()
var person=new Image()


var paused=true
var lastTime=0
var fps=0
var skyOffset=0
var skyOffset1=500
var SKY_VELOCITY=30

function erase(){
    context.clearRect(0,0,canvas.width,canvas.height)
}
function getfps(){
  var now=(+new Date)
  fps=1000/(now-lastTime)
  lastTime=now
  return fps

}
function draw(){
 

  context.save()
  skyOffset=skyOffset>canvas.width?0:skyOffset+SKY_VELOCITY/getfps()
  context.translate(skyOffset,0)
  context.drawImage(sky,0,0,canvas.width,canvas.height)
  context.drawImage(sky,-canvas.width+2,0,canvas.width,canvas.height)
  context.restore()

   context.save()
   skyOffset1=skyOffset1-3
   if(skyOffset1<-144){skyOffset1=canvas.width-144}
   context.translate(0,0)
   context.drawImage(person,skyOffset1,50)
   context.drawImage(person,canvas.width+skyOffset1,50)
   context.restore()



}

sky.src="./images/hover2.png"


person.src="./images/hover1.png"

window.onload=function(){
draw()

}


function animate(){

    if(paused){
     erase()
     draw()
   
    }

    requestNextAnimationFrame(animate)

}


window.requestNextAnimationFrame(animate)
animateButton.onclick=function(){
  paused=!paused
  
}



</script>

canvas制作隨機(jī)粒子移動(dòng)特效

<!DOCTYPE html>
<html>
<head>
    <title>背景滾動(dòng)</title>
   <meta charset="utf-8">
        <style> 
           body {
                background: #dddddd;
            }

            #canvas {
            position: absolute;
            top: 30px;
            left: 10px;
            background: #ffffff;
            cursor: crosshair;
            margin-left: 10px;
            margin-top: 10px;
            -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            }

         input {
            margin-left: 15px;
            }

        </style>

</head>
<body>
    <canvas id='canvas' width='1024' height='512'>
      Canvas not supported
    </canvas>

    <input id='animateButton' type='button' value='Animate'/>

    <script src='./js/requestNextAnimationFrame.js'></script>
   
</body>
</html>


<script type="text/javascript">
var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")

var Sprite=function(name,painter,behaviors){
  if(name!==undefined){this.name=name}
    if(painter!==undefined){this.painter=painter}
      this.top=0
      this.left=0
      this.width=0
      this.height=0
      this.velocityX=0
      this.velocityY=0
      this.visible=true
      this.animating=false
      this.behaviors=behaviors||[]
      this.RADIUS=0
      return this


}
Sprite.prototype={
   paint:function(context){
    if(this.painter!==undefined&&this.visible){this.painter.paint(this,context)}
   },
   update:function(context,time){
    for(var i=0;i<this.behaviors.length;i++){
      this.behaviors[i].excute(this,context,time)
    }
   }
}

// var RADIUS=5
var pai={
        paint:function(sprite,context){

             context.save()

             context.beginPath()
             sprite.left=sprite.left+sprite.velocityX
             sprite.top=sprite.top+sprite.velocityY

             if(sprite.left+sprite.RADIUS>canvas.width||sprite.left-sprite.RADIUS<0){
                sprite.velocityX=-sprite.velocityX
             }
             if(sprite.top+sprite.RADIUS>canvas.height||sprite.top-sprite.RADIUS<0){
                sprite.velocityY=-sprite.velocityY
             }


             
             context.arc(sprite.left+sprite.width/2,sprite.top+sprite.height/2,sprite.RADIUS,0,Math.PI*2,false)
             context.clip()

             context.shadowBlur=8
             context.lineWidth=2
             context.strokeStyle="rgb(100,100,195)"
             context.fillStyle="rgba(30,144,255,0.15)"
             context.fill()
             context.stroke()
             context.restore()


        }

}
var star_list=[]
for(var i=0;i<100;i++){
  var star=new Sprite("star"+i,pai)
   star.left=parseInt(19+(Math.random()*800))
   star.top=parseInt(19+(Math.random()*450))

  if(i%2==0){
    star.velocityY=parseInt(Math.random()*15+1)
  star.velocityX=parseInt(Math.random()*15+1)

  }else{

       star.velocityY=-(parseInt(Math.random()*15+1))
  star.velocityX=-(parseInt(Math.random()*15+1))
  }

  


  star.RADIUS=parseInt(Math.random()*20+1)
  star_list.push(star)
}
function animate(){
       context.clearRect(0,0,canvas.width,canvas.height)
       context.fillStyle="rgb(0,0,0)"
       context.fillRect(0,0,canvas.width,canvas.height)
       
       for(var i=0;i<star_list.length;i++){

           star_list[i].paint(context)
       }

       window.requestAnimationFrame(animate)
}

window.requestAnimationFrame(animate)


</script>

canvas精靈圖制作人物左右移動(dòng)

var velocityX=10  //X軸的位移速度
var left1=100     //X軸的起始位置 這個(gè)值控制人物的橫坐標(biāo)
var img_start=imgid //最開(kāi)始的精靈貼圖
var advance_or="left" //最開(kāi)始向左移動(dòng)
SpriteSheetPainter=function(cells){
   this.cells=cells||[]
   this.cellIndex=0

}

SpriteSheetPainter.prototype={

   advance:function(){

    if(this.cellIndex==(this.cells.length-1)){this.cellIndex=0}else{
              this.cellIndex++
             }
   },
   advance2:function(){
        
        if(this.cellIndex==0){this.cellIndex=(this.cells.length-1)}else{
              this.cellIndex--
             }

   },
   paint:function(context,canvas){
    var cell=this.cells[this.cellIndex]
    left1=canvas.left-velocityX

    if(left1<0){ //人物左移臨界點(diǎn)判斷
       advance_or="right"
       velocityX=-velocityX
       img_start=imgid2
       
       context.drawImage(img_start,cell.x,cell.y,cell.w,cell.h,canvas.left,canvas.top,canvas.w,canvas.h)
      
    }
     if(left1+canvas.w>1024){ //人物右移臨界點(diǎn)判斷
      advance_or="left"
      velocityX=-velocityX
      img_start=imgid
    
      context.drawImage(img_start,cell.x,cell.y,cell.w,cell.h,canvas.left,canvas.top,canvas.w,canvas.h)
     }

     else{
     if(advance_or=="left"){

      img_start=imgid
      this.advance()
     }
     if(advance_or=="right"){
      img_start=imgid2
      this.advance2()
     }

     context.drawImage(img_start,cell.x,cell.y,cell.w,cell.h,canvas.left,canvas.top,canvas.w,canvas.h)
     }

    
   }
}

window.onload=function(){
   //bomb.paint(context)
   var some=new SpriteSheetPainter([{x:0,y:0,w:41,h:64},
                                    {x:53,y:0,w:41,h:64},
                                    {x:106,y:0,w:41,h:64},
                                    {x:159,y:0,w:41,h:64},
                                    {x:212,y:0,w:41,h:64},
                                    {x:265,y:0,w:41,h:64},
                                    {x:318,y:0,w:41,h:64},
                                    {x:371,y:0,w:41,h:64},
                                    {x:424,y:0,w:41,h:64}
                                    ])

    some.paint(context,{left:100,top:100,w:53,h:64})

   var now=0
   var last=0
   

   function animate(){
     now=(+new Date) 
     var hi=now-last
    
     if(parseInt(hi)>100){
      
      
      last=now

     context.clearRect(0,0,canvas.width,canvas.height)
     // some.advance()
     some.paint(context,{left:left1,top:100,w:53,h:64})

     }
     
     
   
     requestAnimationFrame(animate)
    }

requestAnimationFrame(animate)


}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末析显,一起剝皮案震驚了整個(gè)濱河市线脚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叫榕,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姊舵,死亡現(xiàn)場(chǎng)離奇詭異晰绎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)括丁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門荞下,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人史飞,你說(shuō)我怎么就攤上這事尖昏。” “怎么了构资?”我有些...
    開(kāi)封第一講書人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵抽诉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我吐绵,道長(zhǎng)迹淌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任己单,我火速辦了婚禮唉窃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纹笼。我一直安慰自己纹份,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蔓涧,像睡著了一般件已。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蠢笋,一...
    開(kāi)封第一講書人閱讀 52,166評(píng)論 1 308
  • 那天拨齐,我揣著相機(jī)與錄音,去河邊找鬼昨寞。 笑死瞻惋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的援岩。 我是一名探鬼主播歼狼,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼享怀!你這毒婦竟也來(lái)了羽峰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤添瓷,失蹤者是張志新(化名)和其女友劉穎梅屉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鳞贷,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坯汤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搀愧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惰聂。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖咱筛,靈堂內(nèi)的尸體忽然破棺而出搓幌,到底是詐尸還是另有隱情,我是刑警寧澤迅箩,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布溉愁,位于F島的核電站,受9級(jí)特大地震影響沙热,放射性物質(zhì)發(fā)生泄漏叉钥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一篙贸、第九天 我趴在偏房一處隱蔽的房頂上張望投队。 院中可真熱鬧,春花似錦爵川、人聲如沸敷鸦。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扒披。三九已至癌刽,卻和暖如春疾宏,著一層夾襖步出監(jiān)牢的瞬間镊逝,已是汗流浹背笛丙。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留价说,地道東北人辆亏。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鳖目,于是被迫代替她去往敵國(guó)和親扮叨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1 Canvas接口元素定義 1.1 getContext()方法 為了在canvas上繪制领迈,你必須先得到一個(gè)畫布...
    Kevin_Junbaozi閱讀 1,315評(píng)論 1 2
  • 一:canvas簡(jiǎn)介 1.1什么是canvas彻磁? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,691評(píng)論 2 32
  • ??HTML5 添加的最受歡迎的功能就是 元素衷蜓。這個(gè)元素負(fù)責(zé)在頁(yè)面中設(shè)定一個(gè)區(qū)域,然后就可以通過(guò) JavaScri...
    霜天曉閱讀 3,019評(píng)論 0 2
  • 書中代碼示例效果展示:Core HTML5 Canvas Examples 基礎(chǔ)知識(shí) canvas元素 canva...
    szu_bee閱讀 2,841評(píng)論 2 28
  • 一尘喝、簡(jiǎn)介 HTML5 中的定義:“它是依賴分辨率的位圖畫布恍箭,你可以在 canvas 上面繪制任何圖形,甚至加載照片...
    destiny0904閱讀 10,549評(píng)論 1 4