返回顶部
首页 > 资讯 > 精选 >如何用Vue制作一个像素绘板
  • 269
分享到

如何用Vue制作一个像素绘板

2023-07-04 13:07:49 269人浏览 独家记忆
摘要

本篇内容介绍了“如何用Vue制作一个像素绘板”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!技术栈[vue + vuex + vue-rout

本篇内容介绍了“如何用Vue制作一个像素绘板”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

技术栈

  • [vue + vuex + vue-router] 页面渲染 + 数据共享 + 路由跳转

  • [axiOS] 以 Promise 的方式使用 Http 请求

  • [stylus] CSS 预处理

  • [element-ui] UI 库

  • [webpack] 打包上面这些东西

  • [koa 2 & koa-generator] nodejs 框架和框架脚手架

  • [mongodb & monGoose] 数据库和操作数据库的库

  • [node-canvas] 服务端数据副本记录

  • [Socket.io] 实时推送

  • [pm2] Node 服务部署

  • [Nginx] 部署静态资源访问服务(https),代理请求

  • [letsencrypt] 生成免费的 HTTPS 证书

WEBpack 之所以也被列出来,是因为本项目作为项目 luwuer.com 的一个模块,需要 webpack 来实现独立打包

node-canvas

安装

node-canvas 是我目前遇到过最难安装的依赖,以至于我根本不想在 windows 下安装他,它的功能依赖很多系统下默认不存在的包,在 GitHub 上也能看到很多 issue 的标签是 installation help。以 Centos 7 纯净版为例,在安装它之前你需要安装以下这些依赖,值得注意的是 npm 文档上提供的命令没有 cairo 。

# centos 前置条件sudo yum install GCc-c++ cairo cairo-devel pango-devel libjpeg-turbo-devel giflib-devel# 安装本体yarn add canvas -D

还有一个不明所以的坑,如果前置条件准备就绪后,安装本体仍然一直卡取包这一步(不报错),此时需要单独更新一下 npm

使用示例

参考文档很容易就能掌握基本用法,下方例子中先取到像素点数据生成 ImageData ,然后通过 putImageData 把历史数据画到 canvas 。

const { createCanvas, createImageData} = require('canvas')const canvas = createCanvas(canvasWidth, canvasHeight)const ctx = canvas.getContext('2d')// 初始化const init = callback => { Dot.queryDots().then(data => {  let imgData = new createImageData(   Uint8ClampedArray.from(data),   canvasWidth,   canvasHeight  )  // 移除 Smooth  ctx.mozImageSmoothingEnabled = false  ctx.webkitImageSmoothingEnabled = false  ctx.msImageSmoothingEnabled = false  ctx.imageSmoothingEnabled = false  ctx.putImageData(imgData, 0, 0, 0, 0, canvasWidth, canvasHeight)  successLog('canvas render complete !')  callback() })}

Socket.io

本项目在设计上有两个必须用到推送的地方,一是其他用户的建点信息,二是所有用户发送的聊天消息。

client

// socket.io init// transports: [ 'websocket' ]window.socket = io.connect(window.location.origin.replace(/https/, 'wss'))// 接收图片window.socket.on('dataUrl', data => { this.imageObject.src = data.url this.loadInfo.push('渲染图像...') this.init()})// 接收其他用户建点window.socket.on('newDot', data => { this.saveDot(  {   x: data.index % this.width,   y: Math.floor(data.index / this.width),   color: data.color  },  false )})// 接收所有人的最新推送消息window.socket.on('newChat', data => { if (this.msgs.length === 50) {  this.msgs.shift() } this.msgs.push(data)})

server /bin/www

let http = require('http');let io = require('socket.io')let server = http.createServer(app.callback())let ws = io.listen(server)server.listen(port)ws.on('connection', socket => { // 建立连接的 client 加入房间 chatroom ,为了下方可以广播 socket.join('chatroom') socket.emit('dataUrl', {  url: cv.getDataUrl() }) socket.on('saveDot', async data => {  // 推送给其他用户,即广播  socket.broadcast.to('chatroom').emit('newDot', data)  saveDotHandle(data) }) socket.on('newChat', async data => {  // 推送给所有用户  ws.sockets.emit('newChat', data)  newChatHandle(data) })})

letsencrypt

申请证书

# 获得程序git clone https://github.com/letsencrypt/letsencryptcd letsencrypt# 自动生成证书(环境安装完毕后会有两次确认),证书目录 /etc/letsencrypt/live/{输入的第一个域名} 我这里是 /etc/letsencrypt/live/www.luwuer.com/./letsencrypt-auto certonly --standalone --email html6@foxmail.com -d www.luwuer.com -d luwuer.com

自动续期

# 进入定时任务编辑crontab -e# 提交申请,我这里设置每两月一次,过期时间为三月* * * */2 * cd /root/certificate/letsencrypt && ./letsencrypt-auto certonly --renew

nginx

yum install -y nginx

/etc/nginx/config.d/https.conf

server { # 使用 HTTP/2,需要 Nginx1.9.7 以上版本 listen 443 ssl http2 default_server; # 开启HSTS,并设置有效期为“6307200秒”(6个月),包括子域名(根据情况可删掉),预加载到浏览器缓存(根据情况可删掉) add_header Strict-Transport-Security "max-age=6307200; preload"; # add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload"; # 禁止被嵌入框架 add_header X-Frame-Options DENY; # 防止在IE9、Chrome和Safari中的MIME类型混淆攻击 add_header X-Content-Type-Options nosniff; # ssl 证书 ssl_certificate /etc/letsencrypt/live/www.luwuer.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.luwuer.com/privkey.pem; # OCSP Stapling 证书 ssl_trusted_certificate /etc/letsencrypt/live/www.luwuer.com/chain.pem; # OCSP Stapling 开启,OCSP是用于在线查询证书吊销情况的服务,使用OCSP Stapling能将证书有效状态的信息缓存到服务器,提高TLS握手速度 ssl_stapling_verify on; #OCSP Stapling 验证开启 ssl_stapling on;  #用于查询OCSP服务器DNS  resolver 8.8.8.8 8.8.4.4 valid=300s; # DH-Key交换密钥文件位置 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # 指定协议 TLS ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  # 加密套件,这里用了CloudFlare's Internet facing SSL cipher configuration ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; # 由服务器协商最佳的加密算法 ssl_prefer_server_ciphers on; server_name ~^(\w+\.)?(luwuer\.com)$; # $1 = 'blog.' || 'img.' || '' || 'www.' ; $2 = 'luwuer.com' set $pre $1; if ($pre = 'www.') {  set $pre ''; } set $next $2;  root /root/apps/$pre$next; location / {  try_files $uri $uri/ /index.html;  index index.html; } location ^~ /api/ {  proxy_pass http://43.226.147.135:3000/;  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }  # socket代理配置 location /socket.io/ {  proxy_pass http://43.226.147.135:3000;  proxy_http_version 1.1;  proxy_set_header Upgrade $http_upgrade;  proxy_set_header Connection "upgrade"; } # location /weibo/ { #   proxy_pass https://api.weibo.com/; # } include /etc/nginx/utils/cache.conf;}server { listen 80; server_name www.luwuer.com; rewrite ^(.*)$ https://$server_name$request_uri;}

附录

数据库存储结构思考历程

首先需求是画板可以作画实际大小为 { width: 1024px, height: 512px } ,这就意味着有 1024 * 512 = 524,288 个像素点,或则有 524,288 * 4 = 2,097,152 个表示颜色的数字,这些数据量在不做压缩的情况下,最小存储方式是后者剔除掉 rgba 中的 a ,也就是一个长度为 524,288 * 3 = 1,572,864 的数组,如果赋值给变量占用内存大概 1.5M (数据来源于 Chrome Memory)。为了存储以上结构,我首先分了两种类型的存储结构:

以点为对象存储,也就是说会有 524,288 条数据

  1. 颜色 rbga 存储,后优化为 rgb 存储

  2. 颜色 16 进制存储

整个画布数据当作一条数据存储

虽然看起来结构2有点蠢,但起初我确实思考过这样的结构,那时我还不清楚原来取数据最耗时的不是查询而是 IO 。
后来我分别测试 1.1 和 1.2 这两种结构,然后直接否定了结构 2,因为在测试中我发现了 IO 耗时占总耗时超过 98% ,而结构 2 无疑不能因为单条数据取得绝对的性能优势。

1.1

  • 存储大小 10M

  • 取出全部数据 8000+ms

  • 全表查询 150ms (findOne 和 find 对比结果)

  • 其余耗时 20ms (findOne 和 find 对比结果)

1.2

  • 存储大小 10M

  • 取出全部数据 7500+ms

  • 全表查询

  • 其余耗时

结构 2 如果取数据不是毫秒级,就是死刑,因为这种结构下单个像素变动就需要存储整个图片数据

老实讲这个测试结果让我有些难以接受,问了好几个认识的后端为什么性能这么差、有没有解决办法,但都没什么结果。更可怕的是,测试是在我 i7 CPU 的台式电脑上进行的,当我把测试环境放到单核服务器上时,取全表数据的耗时还要乘以 10 。好在只要想一个问题久了,即使有时只是想着这个问题发呆,也总能迸发出一些莫名的灵感。我想到了关键之一数据可以只在服务启动时取出放到内存中,像素发生改变时数据库和内存数据副本同步修改,于是得以继续开发下去。最终我选择了 1.1 的结构,选择原因和下文的“数据传输”有关。

const mongoose = require('mongoose')let schema = new mongoose.Schema({ index: {  type: Number,  index: true }, r: Number, g: Number, b: Number}, { collection: 'dots'})

index 代替 x & y 以及移除 rgba 中的 a 在代码中再补上,都能显著降低 collection 的实际存储大小

在测试过程中其实还有个特别奇怪的问题,就是单核小霸王服务器上,我如果一次性取出所有数据存储到一个 Array 中,程序会在中途奔溃,没有任何报错信息。起初我以为是 CPU 满荷载久了导致的奔溃(top 查看硬件使用信息),所以还特意新租了一个服务器,想用一个群里的朋友提醒的“分布式”。再后面一段时间,我通过分页取数据,发现程序总是在取第二十万零几百条(一个固定数字)是陡然奔溃,所以为 CPU 证了清白。

Vue的优点

Vue具体轻量级框架、简单易学、双向数据绑定、组件化、数据和结构的分离、虚拟DOM、运行速度快等优势,Vue中页面使用的是局部刷新,不用每次跳转页面都要请求所有数据和dom,可以大大提升访问速度和用户体验。

“如何用Vue制作一个像素绘板”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 如何用Vue制作一个像素绘板

本文链接: https://lsjlt.com/news/345226.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何用Vue制作一个像素绘板
    本篇内容介绍了“如何用Vue制作一个像素绘板”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!技术栈[vue + vuex + vue-rout...
    99+
    2023-07-04
  • Vue+Koa2+mongoose怎么制作一个像素绘板
    小编给大家分享一下Vue+Koa2+mongoose怎么制作一个像素绘板,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!技术栈[v...
    99+
    2024-04-02
  • 如何用Python绘制一个仿黑洞图像
    本篇内容主要讲解“如何用Python绘制一个仿黑洞图像”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何用Python绘制一个仿黑洞图像”吧!单位制利用einsteinpy模块中的Shadow类...
    99+
    2023-07-05
  • 用Python绘制一个仿黑洞图像
    目录简介单位制观测绘图简介 黑洞图像大家都知道,毕竟前几年刚发布的时候曾火遍全网,甚至都做成表情包了。 问题在于,凭什么认为这就是黑洞的照片,而不是一个甜甜圈啥的给整模糊了得到的呢...
    99+
    2023-02-24
    Python绘制仿黑洞图像 Python仿黑洞 Python黑洞
  • 如何使用HTML5 Canvas画线技巧来实现绘制一个像素宽的细线
    如何使用HTML5 Canvas画线技巧来实现绘制一个像素宽的细线,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 ...
    99+
    2024-04-02
  • 使用canvas怎么实现一个像素画板
    本篇文章给大家分享的是有关使用canvas怎么实现一个像素画板,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Pixel = function (o...
    99+
    2023-06-09
  • 使用canvas怎么绘制一个圆角头像
    使用canvas怎么绘制一个圆角头像?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。首先, 拿到头像在画布上的坐标和宽高:(具体怎么获取不在此做具体介绍)let&...
    99+
    2023-06-09
  • 如何使用JavaScript绘制图像
    本篇内容主要讲解“如何使用JavaScript绘制图像”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用JavaScript绘制图像”吧!   ...
    99+
    2024-04-02
  • 使用Canvas如何绘制一个多边形
    使用Canvas如何绘制一个多边形?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。function drawPolygonPath(sideNum,&n...
    99+
    2023-06-09
  • 如何使用纯CSS绘制一个爱心
    小编给大家分享一下如何使用纯CSS绘制一个爱心,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!css的全称是什么css的全称是Cascading Style She...
    99+
    2023-06-14
  • HTML中如何实现一个canvas智绘画板
    这篇文章主要介绍了HTML中如何实现一个canvas智绘画板,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 一、项目介绍名称:智绘画板技术栈:HTML5,CSS3,...
    99+
    2023-06-09
  • 如何利用Matlab绘制有趣图像
    这篇文章主要介绍了如何利用Matlab绘制有趣图像,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.随机樱花树function sakura% @auth...
    99+
    2023-06-29
  • 如何基于Vue制作一个猜拳小游戏
    目录前言:项目效果展示:代码实现思路:实现代码:总结:前言: 在工作学习之余玩一会游戏既能带来快乐,还能缓解生活压力,跟随此文一起制作一个小游戏吧。 描述:石头剪子布,是一种猜拳游戏...
    99+
    2023-01-05
    vue 小游戏 vue猜拳小游戏 vue 小游戏动画
  • Python如何利用Turtle库绘制一个小老虎
    这篇文章将为大家详细讲解有关Python如何利用Turtle库绘制一个小老虎,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。导语哈喽铁汁们好久不见吖~小编已经复工了于是马不停蹄赶来给大家准备新年礼物算开工礼...
    99+
    2023-06-29
  • 如何在Android中利用Drawable绘制一个圆角
    如何在Android中利用Drawable绘制一个圆角?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1. 创建类RoundCircleDrawable继承Drawablepub...
    99+
    2023-05-30
    android drawable
  • linux中怎么使用Arduino制作一个绘图仪
    这篇文章主要介绍了linux中怎么使用Arduino制作一个绘图仪,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。由于我是一个很怀旧的人,我真的很喜欢最初的 Arduino U...
    99+
    2023-06-16
  • 如何使用LoadImage和StretchDIBits绘制PNG图像
    要使用LoadImage和StretchDIBits绘制PNG图像,需要进行以下步骤:1. 包含Windows.h头文件,以便能够使...
    99+
    2023-09-26
    LoadImage
  • 如何使用FrontPage制作一个网页
    这篇文章给大家介绍如何使用FrontPage制作一个网页,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、网页及其组成通过浏览器在WWW上所看到的每一幅画面都是一个网页(Web Page),如图1-1所示。图1-1网页...
    99+
    2023-06-08
  • 如何在Android中使用OpenGL绘制一个2D图形
    今天就跟大家聊聊有关如何在Android中使用OpenGL绘制一个2D图形,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体如下:Android为OpenGL ES支持提供了GLSu...
    99+
    2023-05-30
    android opengl
  • 如何从零开始制作一个linuxiso镜像(图文教程)
    一、前言     对于一个极简化的linux系统而言,只需要三个部分就能组成,它们分别是一个linux内核、一个根文件系统和引导。以下是本文制作linux iso镜像所用到的系统和软件:...
    99+
    2022-05-19
    linux iso镜像
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作