微信小程序实现在线画板

本文实例为大家分享了微信小程序实现手指触摸画板的具体代码,供大家参考,具体内容如下

1、WXML 代码

<!--index.wxml-->
<!-- 弹出框 -->
<view class='alert' hidden='{{alertShow}}' bindtap="alertClick">
<!-- catchtap 阻止冒泡事件 -->
  <view class="alert-main" catchtap='qwe'>
    <form bindsubmit='fabuProject'>
      <view class="timu qwe">
        <view>题目:</view>
        <input type="text" name="name" placeholder='1-6个字(例:中国)'/>
      </view>
      <view class="tishi qwe">
        <view>提示:</view>
        <input type="text" name="notice" placeholder='1-10个字(例:国家)'/>
      </view>
      <view class='form-btn qwe'>
        <button form-type='submit'>提交</button>
        <button form-type='reset'>重置</button>
      </view>
    </form> 
  </view>
</view>
<!-- 内容主题 -->
<view class="container">
  <!-- 头部 -->
  <view class="header d-f w100p">
    <view class="left d-f">题目《 {{project.name}} 》
    <image class="icon" bindtap="getProject" src="../../imgs/icon_refresh.png" />
    </view>
    <view class="right d-f" bindtap="diy">自己出题<image class="icon" src="../../imgs/icon_topic.png" /></view>
  </view>
  <!-- 绘图区域 -->
  <view class="canvas">
    <canvas hidden='{{!alertShow}}' class="mycanvas bxz-bb w100p" canvas-id="canvas" bindtouchstart="canvasStart" bindtouchmove='canvasMove' bindtouchend='canvasEnd'></canvas>
  </view>
  <!-- 操作面板 -->
  <view class="tool_bar d-f w100p bxz-bb">
    <!-- <view class="cancel"><image class="icon" src="../../imgs/icon_cancel.png" />上一步</view> -->
    <!-- chengCancel 点击橡皮擦 -->
    <view class="cancel" bindtap="chengCancel"><image class="icon" src="../../imgs/icon_eraser.png" />橡皮擦</view>
    <view class="cancel" bindtap="clearCanvas"><image class="icon" src="../../imgs/icon_del.png" />清除</view>
  </view>
  <!-- 粗细和颜色 -->
  <view class="set_bar bxz-bb w100p">
    <!-- 粗细 -->
    <view class="linewidth_bar d-f">
      <text class="title">粗细</text>
      <view class="right_demo d-f">
      <!-- 判断橡皮擦是否被选中 -->
        <block wx:if="{{cancelChange}}">
          <view wx:for="{{linewidth}}" class="linewidth_demo bdrs50p {{index == currentLinewidth ?'active':''}}" bindtap="changeLineWidth" id="{{index}}" style="width:{{item*2}}rpx;height:{{item*2}}rpx;background:#fff"></view>
        </block>
        <block wx:else>
          <view wx:for="{{linewidth}}" class="linewidth_demo bdrs50p {{index == currentLinewidth ?'active':''}}" bindtap="changeLineWidth" id="{{index}}" style="width:{{item*2}}rpx;height:{{item*2}}rpx;background:{{color[currentColor]}};"></view>
        </block>
      </view>
    </view>
    <!-- 颜色 -->
    <view class="color_bar d-f">
      <text class="title">颜色</text>
      <view class="right_demo d-f">
        <!-- wx:for 遍历颜色 -->
        <!-- index 每一个颜色的编号 -->
        <!-- 三元运算符 判断那个颜色是被选中的 -->

        <block wx:if="{{cancelChange}}">
          <i class="iconfont icon-huabi" wx:for="{{color}}" style="color:{{item}};" id="{{index}}" bindtap="changeColor"></i>
        </block>
        <block wx:else>
          <i class="iconfont icon-huabi {{index == currentColor ?'active':''}}" wx:for="{{color}}" style="color:{{item}};" id="{{index}}" bindtap="changeColor"></i>
        </block>
      </view>
    </view>
  </view>

  <view class="btn">
    <button bindtap="fabu">发布作品</button>
  </view> 
</view>

2、WXSS 代码

@import 'iconfont.wxss';

.container {
  padding: 0 24rpx;
  background: #eaeaea;
}
.bxz-bb { box-sizing: border-box; }
.d-f { display: flex; }
.d-b { display: block; }
.w100p { width: 96%;margin:0 auto }
.bdrs50p { border-radius: 50%; }
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100vh;
  padding: 0;
  box-sizing: border-box;
} 


.container > .header {
  justify-content: space-between;
  padding-top: 40rpx;
  padding-bottom: 32rpx;
  font-size: 30rpx;
}

.container > .header .left {
  align-items: center;
  color: #e22;
}

.container .left .icon {
  width: 44rpx;
  height: 44rpx;
}

.container > .header .right {
  align-items: center;
  color: #333;
}

.container .right .icon {
  width: 40rpx;
  height: 40rpx;
  padding-left: 18rpx;
}

.mycanvas {
  height: 700rpx;
  margin-bottom: 22rpx;
  background: #fff;
  box-shadow: 0 0 10rpx #ccc;
}
.canvas{
  height: 700rpx;
  margin-bottom: 22rpx;
  width:100%;  
}
.tool_bar {
  justify-content: space-between;
  padding: 0 12rpx;
  margin-bottom: 30rpx;
  font-size: 28rpx;
}

.tool_bar .icon {
  width: 40rpx;
  height: 40rpx;
  padding-right: 8rpx;
  vertical-align: bottom;
}
.set_bar { padding: 0 64rpx; }
.set_bar .title {
  padding-right: 30rpx;
}
.set_bar .right_demo { align-items: center; }
.color_bar .right_demo {
  justify-content: space-between;
  flex: 1;
}
.linewidth_bar .linewidth_demo {
  border: 5rpx solid transparent;
  margin: 0 22rpx;
}
.linewidth_bar .linewidth_demo.active { border-color: #fff;box-shadow: 0rpx 0rpx 10rpx orange }
.icon-huabi { font-size: 44rpx; }
.icon-huabi.active { font-size: 64rpx; }
.btn{
  margin-top:20rpx;
}
.btn button{
  border:0rpx;
  border-radius: 10rpx;
  height:80rpx;
  line-height: 80rpx;
  background: orange;
  color:#fff;
}

/* 弹出框 */
.alert{
  width:100%;
  height:100vh;
  background:rgba(0,0,0,0.3);
  position: fixed;
  left:0;
  top:100rpx;
  z-index:999;
}
.alert-main{
  width:95%;
  height:400rpx;
  position: absolute;
  left:0;
  top:20rpx;
  right:0;
  margin:auto;
  background:#fff;
}
.alert-main .qwe{
  display: flex;
  height:100rpx;
  margin:0 auto;
  margin-top:20rpx;
  line-height: 100rpx;
  width:96%;
}
.alert-main .tishi{
}
.alert-main .form-btn{
}
.alert-main input{
  width:500rpx;
  height:80rpx;
  background: #fff;
  margin: 10rpx 0;
  border:1px solid #7d7d7d;
  border-radius: 5rpx;
}
.alert-main button{
  width:200rpx;
  height:50rpx;
  text-align: center;
  line-height: 50rpx;
  margin-top:25rpx;
  margin-bottom:25rpx;
}

3、JS 代码

let app = getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 弹框是否显示
    alertShow:true,
    // 初始化标题
    project: '太阳',
    // 绘图线的粗细
    linewidth: [2, 3, 4, 5,6,7,8,9],
    // 当前默认的粗细
    currentLinewidth: 0,
    // 绘图的颜色
    color: ['#da1c34', '#8a3022', '#ffc3b0', '#ffa300', '#66b502', '#148bfd', '#000', '#9700c2', '#8a8989'],
    // 当前默认的颜色
    currentColor: 0,
    // 橡皮擦是否被点击
    cancelChange:false,
    // 判断是否开始绘画
    isStart:false
  },
  // 点击自己出题
  diy:function(){
    this.setData({
      "alertShow":false
    });
  },
  // 点击弹框的灰色区域
  alertClick:function(){
    this.setData({
      "alertShow": true
    });
  },
  // 改变颜色的事件
  changeColor:function(e){
    // 获取点击画笔的编号
    let colorIndex = e.currentTarget.id;
    // 修改默认的颜色编号
    this.setData({
      cancelChange: false,
      currentColor: colorIndex
    });
    // 设置颜色
    this.mycanvas.setStrokeStyle(this.data.color[this.data.currentColor]);
  },
  // 改变线的粗细
  changeLineWidth:function(e){
    // 获取点击粗细的编号
    let widthIndex = e.currentTarget.id;
    // 修改当前的粗细
    this.setData({ currentLinewidth:widthIndex});
    // 设置粗细
    this.mycanvas.setLineWidth(this.data.linewidth[this.data.currentLinewidth]);
  },

  // 点击橡皮擦

  chengCancel:function(){
    // 设置橡皮擦被选中
    this.setData({
      cancelChange:true
    });
    // 画笔颜色设置成白色
    this.mycanvas.setStrokeStyle("#fff");
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 获取题目的
  
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  },

  /**
   * 生命周期函数--监听页面显示
   */
  // 获取标题的函数
 
  onShow: function () {
    

    let data = this.data;

    // 创建画板
    this.mycanvas = wx.createCanvasContext("canvas");
    // 设置线的样式
    this.mycanvas.setLineCap("round");
    this.mycanvas.setLineJoin("round");
    // 初始化颜色
    this.mycanvas.setStrokeStyle(data.color[data.currentColor]);
    // 初始化粗细
    this.mycanvas.setLineWidth(data.linewidth[data.currentLinewidth]);

  },
  // 绘画开始
  canvasStart:function(e){
    // 获取触摸点的x,y位置
    let x = e.touches[0].x;
    let y = e.touches[0].y;

    // 将画笔移动到指定坐标
    this.mycanvas.moveTo(x,y);
  },
  // 绘画进行中
  canvasMove:function(e){
    // 获取移动过程中的x,y位置
    let x = e.touches[0].x;
    let y = e.touches[0].y;
    // 指定移动的位置
    this.mycanvas.lineTo(x,y);
    // 开始画线
    this.mycanvas.stroke();
    // 将绘画绘制到canvas
    this.mycanvas.draw(true);
    // 绘制完成,将起始点进行移动
    this.mycanvas.moveTo(x,y);


  },
  // 绘画结束
  canvasEnd:function(){
    // 判断是否开始绘画
    this.setData({
      isStart:true
    });

  },
  // 清除画板
  clearCanvas:function(){
    // 清除区域
    this.mycanvas.clearRect(0,0,400,400);
    this.mycanvas.draw(true);
  },

})

以上是本文全部内容,本文为小程序你猜我画部分功能,如需了解全部请留言。

了解更多,可以查看相关课程

 

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
最近做了一个类似Windows画图板的小程序,拿来和大家分享一下。功能和界面全部模仿于Windows自带的画图板,界面如截图。功能主要有: 手绘线、简单图形、文字输入、图块拖放、重复撤销、画面缩放、打开保存图片文件,另外为了直接从数据库或者XML中存取图片,另外还提供了从Base64编码存取图片的接口,其他还实现了和画图板同样效果的工具箱及颜料盒。 1、 绘图: 绘制功能主要在OnLButtonDown、OnMouseMove、OnLButtonUp中实现,根据当前选择的工具和工具的样式进行绘制。程序中每种工具的绘制都是通过一个图元对象实现,比如钢笔、画刷因为本质上都是手绘线所以都通过CDrawPen来实现、直线和矩形等都通过CDrawShape来实现,所有的图元对象都放在文件DrawObject.h中,具体的实现请参见代码。 另外为了避免屏幕的闪烁,程序中做了两个处理:一、把视图自己的重绘背景代码屏蔽掉,即响应视图的WM_ERASEBKGND消息,直接返回TRUE,并在Ondraw中程序自己绘制背景就可以了;二,在Ondraw中绘制的时候,先绘制到内存DC中,然后再贴回视图的DC。这样就基本上就可以避免屏幕的闪烁了。 2、 撤销重做: 由于整个程序较为简单,就没有采用把动作记录下来的方式,只是采取了一个较简单的方法,在每当一个图元绘制动作结束时就把画布的内容存到bmp中以备撤销,这些历史画面存放在一个bmp数组中,并定义了一个Stack类来管理该数组(此实现方式参考了在线杂志21期《类似画笔的绘图控件-卫琳》,在此表示感谢!),然后在屏幕上绘制的时候就是把当前位图贴到屏幕上,并把还没存取位图的图元绘上就行了。 3、 缩放: 一般视图缩放的实现是通过DC的两个函数来实现:SetViewportExt和SetWindowExt,但是这两个函数只在MM_ISOTROPIC和MM_ANISOTROPIC这两种映射模式下有效果,而常用的带滚动条的视图类CScrollView却不支持这两种模式(参见CScrollView::SetScrollSizes)的实现。所以只好把MFC的CScrollView的代码拿过来改了一下以支持MM_ISOTROPIC映射模式,如下所示,具体参见程序文件“ADMMScrollView.h”: ::SetMapMode(hdc,MM_ISOTROPIC); int XLogMm = ::GetDeviceCaps(hdc, HORZSIZE); int YLogMm = ::GetDeviceCaps(hdc, VERTSIZE); int XLogPix = ::GetDeviceCaps(hdc, HORZRES); int YLogPix = ::GetDeviceCaps(hdc, VERTRES); ::SetWindowExtEx(hdc,XLogMm*100,YLogMm*100,NULL); ::SetViewportExtEx(hdc,(int)(XLogPix*fZoomScale), (int)(YLogPix*fZoomScale),NULL); 4、 工具箱: 首先为了实现工具箱的按钮分两列显示的效果,需要设置一下按钮的TBBS_WRAPPED,参见程序中的CToolPaletteBar类;然后,选择不同工具时展现出工具的样式,比如选择“直线”时列出可用的直线宽度样式,该功能通过在ToolBar上放一个CListCtrl实现,当前的工具样式通过图标的方式展现,效果和画图板的类似。 5、 颜料盒: 从CDialogBar类继承了一个类,然后在WM_PAINT响应函数里面绘制一个个小颜色矩形,并重写其OnLButtonDown、OnRButtonDown、OnLButtonDblClk来和用户交互,实现出来的效果还不错,看上去和画图板的颜料盒一样。 6、 鼠标光标样式: 首先在资源文件中增加需要的光标资源,然后在视图的OnSetCursor消息函数中调用SetCursor函数来设置光标样式就可以了,注意要判断HitTest参数是否为HTCLIENT,不然的话鼠标移到了滚动条上的时候光标还是画笔的样式就让人觉得怪怪的了。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

it_czh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值