零基础-5小时开发一个electron应用-[实践]

2017-12-26 admin

一、背景

三、技能升级

​ 明明可以用颜值取胜,非要靠才华?不对,明明可以用代码搞定,非要搞设计?步入正题,正好最近对electron比较感兴趣,又是要做工具,那就直接怼

1.electron介绍

​ electron最开始不叫这个名字,叫“Atom Shell”,顾名思义,它给我们的应用整合提供了一个可运行的平台,electron通过将ChromiumNode.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的,它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可。现在比较流行的Atom编辑器也是基于electron开发。

官网介绍传送门

2.项目结构

.
├── dist                //应用程序打包输出
├── app
      ├── assets        //资源
      ├── config        //配置
      ├── pages         //主入口
      └── dist          //bundle文件输出
├── .babelrc            
├── index.html
├── app.js            
├── webpack.config.dev.js // dev环境开发
├── webpack.config.js   // prod环境打包
├── package.json
  • app.js为应用启动脚本

    const {app, BrowserWindow} = require('electron')
    const path = require('path')
    const url = require('url')
    // 保持一个对于 window 对象的全局引用,如果你不这样做,
    // 当 JavaScript 对象被垃圾回收, window 会被自动地关闭
    let win
    function createWindow () {
      // 创建浏览器窗口。
      win = new BrowserWindow({width: 800, height: 600})
      // 然后加载应用的 index.html。
      win.loadURL(url.format({
        pathname: path.join(__dirname, 'index.html'),
        protocol: 'file:',
        slashes: true
      }))
      // 打开开发者工具。
      win.webContents.openDevTools()
      // 当 window 被关闭,这个事件会被触发。
      win.on('closed', () => {
        // 取消引用 window 对象,如果你的应用支持多窗口的话,
        // 通常会把多个 window 对象存放在一个数组里面,
        // 与此同时,你应该删除相应的元素。
        win = null
      })
    }
    // Electron 会在初始化后并准备
    // 创建浏览器窗口时,调用这个函数。
    // 部分 API 在 ready 事件触发后才能使用。
    app.on('ready', createWindow)
    // 当全部窗口关闭时退出。
    app.on('window-all-closed', () => {
      // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
      // 否则绝大部分应用及其菜单栏会保持激活。
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })
    app.on('activate', () => {
      // 在macOS上,当单击dock图标并且没有其他窗口打开时,
      // 通常在应用程序中重新创建一个窗口。
      if (win === null) {
        createWindow()
      }
    })
    

3.不同系统的启动方式

系统 启动方式
macOS / Linux $ ./node_modules/.bin/electron .
Windows $ .\node_modules.bin\electron .

4.开发过程

技术选型为electron + react + webpack,总体思路是利用Canvas做图片的合并:

  • 第一步,模板设计,模板的宽高(画布宽高),获取截图相对于模型图片的x,y偏移,以及截图的大小

  • 第二步,将第一步获取的数据抽象成配置文件config/flex.js

  • 第三步,初始化画布

    /**
     * [initCanvas 初始画布]
     */
    initCanvas = () => {
      const canvas = document.createElement('canvas')
      canvas.width = this.state.canvasWidth
      canvas.height = this.state.canvasHeight
      const context = canvas.getContext('2d')
      this.setState({
        context,
        canvas,
      })
    }
    
  • 第四部,首先将机型模板图片利用canvas绘制

    /**
     * [draw description]
     * @param  {[type]}   url      [图片url]
     * @param  {[type]}   x        [相对x偏移]
     * @param  {[type]}   y        [相对y偏移]
     * @param  {Function} callback [合成后回调]
     */
    draw = (url, x, y, callback) => {
      const image = new Image();
      image.onload = () => {
        if (!callback) {
          // 模板
          this.state.context.drawImage(image, x, y)
        } else {
          // 截图
          this.state.context.drawImage(image, x, y, this.state.width, this.state.height)
          callback(this.state.canvas.toDataURL('image/png'))      }
      }
      image.src = url;
    }
    componentDidMount() {
      this.initCanvas()
      // 绘制模型机图片
      this.draw(this.state.theme, 0, 0)
      document.getElementById('upload').addEventListener('change', this.uploadImage)
    }
    

第五步,截图上传事件处理

/**
 * [uploadImage 上传图片回调]
 * @param  {[type]} event [description]
 */
uploadImage = (event) => {
  const reader = new FileReader()
  const file = event.target.files[0] || event.dataTransfer.files[0]
  reader.onload = (e) => {
    const base64 = e.target.result;
    if (file.size > 1024 * 1024 * 10) {
      toast.warn("图片大小不能超过10M", {
        position: toast.POSITION.BOTTOM_RIGHT,
      })
      return
    }
    this.combine(base64,  (url) => {
      this.setState({
        theme: url,
        combineSuccess: true,
      })
    })
  }
  reader.readAsDataURL(file)
}
componentDidMount() {
  this.initCanvas()
  this.draw(this.state.theme, 0, 0)
  document.getElementById('upload').addEventListener('change', this.uploadImage)
}
componentWillUnmount() {
  document.getElementById('upload').removeEventListener('change', this.uploadImage)
}

5.调试

  • 一期暂时没有实现代码的热加载
  • 首先启动npm run watch(webpack –watch)命令监听文件变动,然后npm run mac(或npm run win)启动electron
  • 文件每次变更需要手动刷新窗口 【注】如果要实现热加载可以参考segmentfault.com/a/119000000…

6.打包构建

(1)应用icon www.easyicon.net/covert/可以用在线转换工具

  • mac 为512 x 512

  • win 为256 x 256 (2)代码打包

    npm run build
    

(3)应用程序打包

// 打包exe文件
npm run build:win
// 打包dmg文件
npm run build:mac

四、下载图片遇到的问题

事情总没有那么完美,当截图大于1M会出现无法下载图片的情况,图片base64编码过大,a标签的href属性限制了字符串的长度,经过一番调研,base64改为文件流下载:

/**
 * [baseb4ToBlob base64转blob]
 * @param  {[type]} dataURL [base64编码]
 */
base64ToBlob(dataURL) {
  const parts = dataURL.split(';base64,')
  const contentType = parts[0].split(':')[1]
  const raw = window.atob(parts[1])
  const uInt8Array = new Uint8Array(raw.length)
  for (let i = 0; i < raw.length; ++i) {
    uInt8Array[i] = raw.charCodeAt(i)
  }
  const blob = new Blob([uInt8Array], {type: contentType})
  return window.URL.createObjectURL(blob)
}

五、结果

根据STAR法则,恒量下得到了什么结果:

方案 耗时 用户
PS大法 5 min 会PS的小哥哥小姐姐
iPhoneView 10 s Anyone
  • What?效率提升300%~~~~哈哈哈哈哈
  • 其他收获,electron开发入门,新技能get

六、代码仓库

github.com/geneking/ip… 如果觉得不错,请顺手star :)

[转载]原文链接:http://www.keycode.me/2017/12/22/编程/快速开发一个electron应用[实践]/

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-5157.html

文章标题:零基础-5小时开发一个electron应用-[实践]

相关文章
YouTube正式默认使用HTML5视频播放器
YouTube视频网站现在默认使用HTML5播放器,这意味着更好的性能、 稳定性、 电池寿命和甚至是更好的安全性。现在用户通过Chrome、IE 11、Safari 8和Beta版本的Firefox进行浏览的时候都默认使用HTML5视频播放...
2015-11-12
HTML5的5个不错的开发工具推荐
HTML5规范终于在今年正式定稿,对于从事多年HTML5开发的人员来说绝对是一个重大新闻。数字天堂董事长,DCloud CEO王安也发表了文章,从开发者和用户两个角度分析了HTML对两个人群的优势。其实,关于HTML5的开发工具,我们以往的...
2015-11-12
HTML5凭什么可以代替Flash
本世纪初,全球网络建设仍处于早期阶段,发达国家网民刚刚在从窄带向宽带网络过渡。由于网络带宽、PC运算速度等因素限制,早期的网站基本以静态文字和图片内容为主。但随着宽带网络在全球范围快速普及,网民对内容的需求也不断变化。死板的文字加图片的网站...
2015-11-12
HTML5究竟会火到什么地步
这已经是第N次,HTML5火热了起来,这次的火热是否可以延续? H5的最大优势就是可以在网页上直接调试和修改,而且更重要的是,它几乎不用考虑用户的机型与适配性问题。智能手机主要被分裂为两大系统:Android和iOS,一个做应用的团队,怎么...
2015-11-12
2014年最流行前端开发框架对比评测
如今,各种开发框架层出不穷,各有千秋。哪些是去年较受开发者关注的呢?前不久,云适配根据Github上的流行程度整理了2014年最受欢迎的6个前端开发框架,并进行对比说明,希望帮助有需要的朋友选择合适自己的前端框架。 1. Bootstrap...
2015-11-12
2015年3月国内浏览器市场份额概括,chrome占32.97
本报告数据,来源于百度统计所覆盖的超过150万的站点,而不是baidu.com的流量数据。 注:奇虎360浏览器份额在2010年10月至2011年3月,和2012年9月以来,两次大幅下降,是因为360浏览器去掉了原本的浏览器特征(User...
2015-11-12
梳理前端开发使用eslint-prettier检查和格式化代码
问题痛点 在团队的项目开发过程中,代码维护所占的时间比重往往大于新功能的开发。因此编写符合团队编码规范的代码是至关重要的,这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性。 对于代码版本管理系统(svn 和 git或者其他)...
2018-05-07
HTML5这次的火热是否又是昙花一现?
即使你不是技术控,你也应该感受到过去一年时间身边发生的HTML5事件,去年由微信朋友圈引爆的《围住神经猫》以及之后一系列的小游戏,都证明了HTML5的营销价值。 HTML5已经出来很多年了,HTML5是一个基于浏览器的协作标准,可以让各种不...
2015-11-12
Web前端开发与iOS终端开发的异同
毕业之前一直在做前端开发,毕业后就转成做iOS开发,这两者有很多挺有意思的对比,尝试写下我能想到的它们的一些相同点和不同点。 语言 前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,...
2016-01-13
React Native 用JavaScript编写原生ios应用
ReactNative 可以基于目前大热的开源JavaScript库React.js来开发iOS和Android原生App。而且React Native已经用于生产环境——Facebook Groups iOS 应用就是基于它开发的。 Re...
2015-11-12
回到顶部