Skip to content

一个仿Vue风格的图片上传工具,使用方式类似于Vue风格

Notifications You must be signed in to change notification settings

is-liyiwei/mgue

Repository files navigation

一个仿Vue风格的图片上传工具,但不是Vue的插件,只是使用方式类似于Vue风格,原生无依赖,数据与ui分离,使用插件方式拓展方法

存在的bug与问题

  • gif图无法进行任何压缩、绘图操作,直接上传

  • 没有绘图操作时不要写drawStart和drawEnd方法,会导致图片进入canvas操作,从而使图片变大。(插件上设计的问题,暂未找到解决办法)

  • 插件设计上存在缺陷,虽然有插件和示例,但无法提供开箱即用的api,使用上比较繁琐

use browser

<script type="text/javascript" src="./index.js"></script>

use module

npm i mgue --save
import mgue from 'mgue'

// use plugins

import fillTextPlugin from 'mgue/mgueFillText'
import fillRectPlugin from 'mgue/mgueFillRect'
import fillCirclePlugin from 'mgue/mgueFillCircle'

import rotatePlugin from 'mgue/mgueRotate'
import scalePlugin from 'mgue/mgueScale'
import translatePlugin from 'mgue/mgueTranslate'

// 注册插件
Mgue.use(fillTextPlugin)
Mgue.use(fillRectPlugin)
Mgue.use(fillCirclePlugin)

// 旋转,缩放,位移插件,使用方法参考demo目录下的文件,原理差不多
Mgue.use(rotatePlugin)
Mgue.use(scalePlugin)
Mgue.use(translatePlugin)

插件使用(是不是很像Vue,就是参(chao)考(xi)了Vue的思路!0.0)

// 编写插件
let fillTextPlugin = {}
fillTextPlugin.install = function (mgue, options) {
  console.log(options)
   // 1. 添加全局方法或属性,一般不使用
  mgue.myGlobalMethod = function () {
    console.log('myGlobalMethod')
    // 逻辑...
  }
  // 2. 添加实例方法
  mgue.prototype.$fillText = function (ctx, opts) {
    ctx.font = opts.font;
    ctx.fillStyle = opts.fillStyle;
    ctx.textAlign = opts.textAlign;  
    ctx.fillText(opts.txt, opts.w , opts.h);
  }
}

if (typeof exports == "object") {
  module.exports = fillTextPlugin;
} else if (typeof define == "function" && define.amd) {
  define([], function () {
    return fillTextPlugin
  })
} else if (window) {
  window.fillTextPlugin = fillTextPlugin;
}

// 注册插件
mgue.use(MyPlugin, {
  params: 'test' // 可以添加额外的参数
})

// 使用插件
var gradient = ctx.createLinearGradient(0, 0, canvas.width, 0)
    gradient.addColorStop("0", "white")
    gradient.addColorStop("0.5", "#00bfff")
    gradient.addColorStop("1.0", "white")

    // 使用插件,这是个加文字到图片上的插件
    this.$fillText(ctx, {
      font: `${img.width / 10}px microsoft yahei`,
      fillStyle: gradient,
      txt: '居中填充文字',
      textAlign: 'center',
      w: canvas.width / 2,
      h: canvas.height / 2
    })
// 插件的使用一般是对canvas进行操作,所以插件一般用在drawStart方法里面,该方法会暴露出当前的绘图对象和img本身
// ctx, img, canvas,目录下有三个常用方法的插件,用于添加文本,图形,可用于加水印标识等等,也可自己写插件,按照上面
// 的方法使用即可,本意上就是对canvas进行操作,只要有足够的绘图功底,Nothing is impossible!!!

drawStart() { // 绘图开始钩子
  let { ctx, img, canvas } = this
  this.$pluginFn(ctx, {

  })
}

示例,可直接下载此项目,查看demo文件夹下对应的文件

后端代码以node为示例,基于express,依赖formidable库

var express = require('express');
var router = express.Router();
var formidable = require('formidable');
var fs = require('fs');

router.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    res.header('Access-Control-Allow-Headers', 'heData');
    next();
});

router.post('/web/upload', function(req, res, next) {
  // console.log(req)
  // console.log(req.body)
  // console.log(req.params)
  // console.log(req.query)
  res.header( 'Content-Type','text/javascript;charset=utf-8');        //设置返回字符串编码
    var form = new formidable.IncomingForm();                            //创建对象
    form.uploadDir = "./public/images/";                        //设置临时文件存放的路径
    form.encoding='utf-8';                                                //设置上传数据的编码
    form.keepExtensions = true;                                            //设置是否保持上传文件的拓展名
    form.maxFieldsSize = 2 * 1024 * 1024;                               //文件大小

    // form.on('progress', function (bytesReceived, bytesExpected) {
    //     console.log(bytesReceived);
    //     console.log(bytesExpected);
    // });

    form.parse(req, function(err, fields, files) {
    if (err) {
      console.log(err);
      return;
    }

    console.log('headers', req.headers.hedata) // 这里heData变成了全部小写,不知道是什么原因
    console.log('params', fields); // 这里是额外的参数
    console.log(files.imgFiles); // imgFiles数据

    var extName = '';                      //后缀名
    switch (files.imgFiles.type) {
      case 'image/pjpeg':
        extName = 'jpg';
        break;
      case 'image/jpeg':
        extName = 'jpg';
        break;         
      case 'image/png':
        extName = 'png';
        break;
      case 'image/x-png':
        extName = 'png';
        break;
      case 'image/gif':
        extName = 'gif';
        break;         
    }

    if(extName == '') {
        res.statusCode = 404;
        res.statusMessage = 'files type error form statusMessage';
        res.send('files type error');
        return;
    }

    var dataName = new Date(files.imgFiles.lastModifiedDate).getTime()

    var avatarName = dataName + '.' + extName;
    var newPath = form.uploadDir + avatarName;

    console.log(newPath);
    fs.renameSync(files.imgFiles.path, newPath);  //重命名

    setTimeout( () => {
        res.send({
            avatarName
        });
    }, 2000)  // 定时器是为了测试uploadStart事件
  });
});

module.exports = router;

参考文献

About

一个仿Vue风格的图片上传工具,使用方式类似于Vue风格

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published