Canvan拖拽绘制多边形,Canvan实现图片反转,显示为底片效果

1. 绘制多边形

在画布中以鼠标按下的点为圆心,以鼠标划过的距离为半径绘制多边形:

var Polygon = function(){
    this.mouseIn = false
    this.startPoints = {} //鼠标在画布中按下的点左边
    this.line_list = {}
    this.imageData = null

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    canvas.onmousedown = (event) => {
        this.saveImage(ctx, canvas)
        let some = this.pointsOnCanvas(event, canvas)
        this.startPoints.x = some.x;
        this.startPoints.y = some.y
        this.mouseIn = true
    }
    canvas.onmousemove = (event) => {
        if(this.mouseIn){   //如果按下鼠标并拖行
            this.loadingImage(ctx)
            this.line_list = this.pointsOnCanvas(event, canvas)
            ctx.beginPath()
            let radius = this.getRadius()
            let startAngel = 0 //开始角度
            let sides = 8 //边数
            let startX = this.mousedown.x + radius * Math.cos(Math.PI*startAngel/180)  //这里其实是角度转为弧度的算法:2*Math.PI/360 * startAngel(2π弧度=360度,所以1度=2π/360)
            let startY = this.mousedown.y + radius * Math.sin(Math.PI*startAngel/180)
            ctx.moveTo(startX, startY)
            for(let i=1;i<sides;i++){
                let nextX = this.mousedown.x + radius * Math.cos(Math.PI/180 * (i*360/sides)+startAngel)
                let nextY = this.mousedown.y + radius * Math.sin(Math.PI/180 * (i*360/sides)+startAngel)
                ctx.lineTo(nextX, nextY);
            }
            ctx.closePath();
            ctx.lineWidth = 2;
            ctx.stroke();
        }
    }
    canvas.onmouseup = () => {
        this.mouseIn = false //鼠标抬起来了
    }
     //算出你点击在canvas画布的坐标 并返回
    Polygon.prototype.pointsOnCanvas = function(event, canvas){
        var rect = canvas.getBoundingClientRect()
        return {
            x: event.clientX - rect.left,
            y: event.clientY - rect.top
        } 
    }
    // 获取半径
    Polygon.prototype.getRadius = function(){
        var x_width = Math.abs(line_list.x - this.mousedown.x)
        var y_width = Math.abs(line_list.y - this.mousedown.y) 
        return Math.sqrt(x_width*x_width + y_width*y_width) 
    }
    Polygon.prototype.saveImage = function(ctx, canvas){  //储存此刻画布数据
        this.imageData = ctx.getImageData(0,0,canvas.width,canvas.height)
    }
    Polygon.prototype.loadingImage = function(ctx){ //导入画布数据
        ctx.putImageData(this.imageData,0,0)
    }
}

效果如下:


Polygon.gif

2. 实现图片反转,显示为底片效果

<input type="file" onChange="chooseFile" />
<img :src="src"> //正常图片
<img :src="revertSrc"> //反转后的图片

function chooseFile(e){
    let imgFile = e.target.files[0]
    let reader = new FileReader()
    let img = new Image()
    reader.onload = () => {
        src = reader.result
        img.src = reader.result
    }
    img.onload = () => {
        revertSrc = createRevertPic(img)
    }
    reader.readAsDataURL(imgFile)
}
//图片反转
function createRevertPic(img){
    var canvas = document.createElement("canvas");
    canvas.width = img.width;   
    canvas.height = img.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img,0,0);  
    var c = ctx.getImageData(0, 0, img.width, img.height);
    for(var i = 0; i < c.height; ++i){
        for(var j = 0; j < c.width; ++j){
            var x = i*4*c.width + 4*j,  //imagedata读取的像素数据存储在data属性里,是从上到下,从左到右的,每个像素需要占用4位数据,分别是r,g,b,alpha透明通道
            r = c.data[x],
            g = c.data[x+1],
            b = c.data[x+2];
            c.data[x+3] = 150;    //透明度设置为150,0表示完全透明
            //图片反相:
            c.data[x] = 255-r;
            c.data[x+1] = 255-g;
            c.data[x+2] = 255-b; 
        }
    }
    ctx.putImageData(c,0,0);
    return canvas.toDataURL();  //返回canvas图片数据为base64的url
}

效果如下:


dipian.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266