互動(dòng)白板項(xiàng)目文檔(一)

實(shí)現(xiàn)效果圖:


image.png
1. 創(chuàng)建vue2項(xiàng)目
vue create vue2-board
2. 將項(xiàng)目進(jìn)行一個(gè)簡(jiǎn)單的配置青伤,比如全局scss樣式文件边灭,將p標(biāo)簽潦牛、ul li標(biāo)簽眶掌、h1、h2等標(biāo)簽的默認(rèn)樣式去除巴碗,ps:推薦樣式重置文件reset.css朴爬,樣式地址:https://meyerweb.com/eric/tools/css/reset/
2.1 在src路徑下新建styles文件夾,內(nèi)建index.scss橡淆,然后在main.js內(nèi)引入該文件召噩。import './styles/index.scss'代碼如下:
/* http://meyerweb.com/eric/tools/css/reset/ */
/* v1.0 | 20080212 */

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
    margin: 0;
    padding: 0;
    border: 0;
    outline: 0;
    font-size: 100%;
    vertical-align: baseline;
    background: transparent;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}

/* remember to define focus styles! */
:focus {
    outline: 0;
}

/* remember to highlight inserts somehow! */
ins {
    text-decoration: none;
}
del {
    text-decoration: line-through;
}

/* tables still need 'cellspacing="0"' in the markup */
table {
    border-collapse: collapse;
    border-spacing: 0;
}
2.2 安裝必要的插件element-uifabric
cnpm i element-ui fabric --save
2.3 main.js引入插件element-ui逸爵,fabric在需要的頁(yè)面在導(dǎo)入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
2.4 清空App.vue,開(kāi)始編碼具滴,在此頁(yè)面引入 fabric
<template>
  <div id="app">頁(yè)面初始化</div>
</template>

<script>
import { fabric } from "fabric";
export default {
  name: "App",
};
</script>

<style lang="scss">
html,
body {
  width: 100%;
  height: 100%;
}
#app {
  height: 100%;
  background-color: #eee;
}
</style>
3. 先開(kāi)發(fā)靜態(tài)頁(yè)面,也就是右側(cè)的操作欄痊银,
//豎形div抵蚊,定位到右側(cè)
 <div class="tools"></div>

//css
.tools {
    width: 46px;
    height: 500px;
    background: rgba(51, 51, 51, 0.4);
    border-radius: 4px;
    position: absolute;
    right: 10px;
    top: 10%;
  }
<template>
  <div id="app">
    <!-- 右側(cè)操作欄 -->
    <div class="tools">
      <ul>
        <el-tooltip class="item" effect="dark" content="畫(huà)筆" placement="left">
          <li>
            <i class="el-icon-edit"></i>
          </li>
        </el-tooltip>
        <li>
          <i class="el-icon-top-left"></i>
        </li>
        <li>
          <i class="el-icon-minus"></i>
        </li>
        <li>
          <i class="el-icon-full-screen"></i>
        </li>
        <li>
          <i class="el-icon-edit-outline"></i>
        </li>
        <li>
          <el-color-picker v-model="fontColor"></el-color-picker>
        </li>
        <li>
          <i class="el-icon-d-arrow-left"></i>
        </li>
        <li>
          <i class="el-icon-brush"></i>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { fabric } from "fabric";
export default {
  name: "App",
  data() {
    return {
      fontColor: "#409EFF",
    };
  },
};
</script>

<style lang="scss">
html,
body {
  width: 100%;
  height: 100%;
}
#app {
  height: 100%;
  background-color: #eee;
  .tools {
    // width: 46px;
    // height: 500px;
    background: rgba(51, 51, 51, 0.4);
    border-radius: 4px;
    position: absolute;
    right: 10px;
    top: 10%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px 5px;
    ul {
      li {
        width: 38px;
        height: 38px;
        background: #565656;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-bottom: 10px;
        color: #fff;
        border-radius: 4px;
        font-size: 20px;
        cursor: pointer;
        border: 1px solid transparent;
        &:hover {
          background: #333;
          border: 1px solid #fff;
        }
      }
    }
  }
}
</style>
4. 既然是vue,我們就要循環(huán)渲染出來(lái)右側(cè)的操作欄
<template>
  <div id="app">
    <!-- 右側(cè)操作欄 -->
    <div class="tools">
      <ul>
        <el-tooltip
          v-for="(item, index) in brushModelData"
          :key="index"
          class="item"
          effect="dark"
          :content="item.tips"
          placement="left"
        >
          <li v-if="item.type != 5">
            <i :class="item.icon"></i>
          </li>
          <li v-if="item.type == 5">
            <el-color-picker v-model="fontColor" size="mini"></el-color-picker>
          </li>
        </el-tooltip>
      </ul>
    </div>
  </div>
</template>

<script>
import { fabric } from "fabric";
export default {
  name: "App",
  data() {
    return {
      fontColor: "#409EFF",
      brushModelData: [
        { icon: "el-icon-edit", tips: "畫(huà)筆", type: 0 },
        { icon: "el-icon-top-left", tips: "箭頭", type: 1 },
        { icon: "el-icon-minus", tips: "直線", type: 2 },
        { icon: "el-icon-full-screen", tips: "矩形", type: 3 },
        { icon: "el-icon-edit-outline", tips: "文本", type: 4 },
        { icon: "el-icon-edit", tips: "顏色", type: 5 },
        { icon: "el-icon-d-arrow-left", tips: "撤銷(xiāo)", type: 6 },
        { icon: "el-icon-brush", tips: "清空", type: 7 },
      ],
    };
  },
};
</script>

<style lang="scss">
html,
body {
  width: 100%;
  height: 100%;
}
#app {
  height: 100%;
  background-color: #eee;
  .tools {
    // width: 46px;
    // height: 500px;
    background: rgba(51, 51, 51, 0.4);
    border-radius: 4px;
    position: absolute;
    right: 10px;
    top: 10%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px 5px;
    ul {
      li {
        width: 38px;
        height: 38px;
        background: #565656;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-bottom: 10px;
        color: #fff;
        border-radius: 4px;
        font-size: 20px;
        cursor: pointer;
        border: 1px solid transparent;
        &:hover {
          background: #333;
          border: 1px solid #fff;
        }
        i {
          font-weight: bold;
        }
        &:last-child{
          margin-bottom: 0;
        }
      }
    }
  }
}
</style>
5. 靜態(tài)頁(yè)面處理好了溯革,下面來(lái)初始化 fabric
//設(shè)置一個(gè)畫(huà)板區(qū)域贞绳,和當(dāng)前頁(yè)面同比大小
<!-- 畫(huà)板區(qū)域 -->
<div class="conent">
   <canvas id="canvas"></canvas>
</div>

.conent{
    width: 100%;
    height: 100%;
    background: red;
  }

methods:{
    /**
     * 初始化畫(huà)板
     */
    initBoard(){
      //固定寫(xiě)法 ('canvas')括號(hào)內(nèi)的參數(shù) 是canvas的id,{ }是一些參數(shù)
      new fabric.Canvas('canvas',{
        isDrawingMode:true,//默認(rèn)開(kāi)啟自由繪畫(huà)模式
      })
    }
  },
  mounted(){
    this.initBoard()
  }
image.png
可以看到畫(huà)板太小了致稀,下面設(shè)置下畫(huà)板的大小和紅色區(qū)域一般大
//首先把我們實(shí)例化出來(lái)的fabric賦值給一個(gè)變量
data() {
    return {
      canvas:null
    };
  },

/**
 * 初始化畫(huà)板
 */
initBoard(){
  this.canvas =  new fabric.Canvas('canvas',{
     isDrawingMode:true,//默認(rèn)開(kāi)啟自由繪畫(huà)模式
   })
//最好是定義一個(gè)可復(fù)用的方法
this.handleResize();
 },
handleResize() {
      /** 設(shè)置canvas畫(huà)布大小 */
      /** 先獲取content的寬高冈闭,給content一個(gè)ref屬性 canvasWrap */
      // console.log(this.$refs.canvasWrap.offsetWidth);
      let w = this.$refs.canvasWrap.offsetWidth
      let h = this.$refs.canvasWrap.offsetHeight
      this.canvas.setWidth(w);
      this.canvas.setHeight(h);
    },
mounted() {
    this.initBoard();
    //解決頁(yè)面大小變化動(dòng)態(tài)改變canvas畫(huà)布的大小
    window.addEventListener('resize',this.handleResize)
  },
下面改變下畫(huà)布的背景顏色和畫(huà)筆的默認(rèn)顏色和畫(huà)筆的默認(rèn)粗細(xì)
 // 改變畫(huà)布的背景顏色
 this.canvas.backgroundColor = '#fff';
 // 設(shè)置默認(rèn)顏色
 this.canvas.freeDrawingBrush.color = this.color;
 // 設(shè)置默認(rèn)畫(huà)筆粗細(xì)
 this.canvas.freeDrawingBrush.width = this.width;
當(dāng)前模式是自由繪制模式,我們給左側(cè)的操作欄一個(gè)默認(rèn)選擇狀態(tài) active抖单,并且實(shí)現(xiàn)動(dòng)態(tài)切換active
image.png
 <li v-if="item.type != 5" :class="{ active: isActive == index }" @click="setBrushModel(index, item)">
   <i :class="item.icon"></i>
 </li>
 <li v-if="item.type == 5" :class="{ active: isActive == index }" @click="setBrushModel(index, item)">
      <el-color-picker v-model="fontColor" size="mini"></el-color-picker>
 </li>
 * 點(diǎn)擊切換畫(huà)筆功能
     */
    setBrushModel(index, item) {
      if (item.type !== 5 && item.type !== 6 && item.type !== 7) {
        this.isActive = index;
      }
    },
li.active {
        background-color: #333;
        border-color: #fff;
        i {
          font-weight: bold;
        }
      }
下面實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的萎攒,變換畫(huà)筆的顏色
<el-color-picker v-model="fontColor" size="mini" @change="changePenColor"></el-color-picker>
/** 改變畫(huà)筆顏色 */
    changePenColor(){
      this.canvas.freeDrawingBrush.color = this.fontColor;
    }
下面實(shí)現(xiàn) 最簡(jiǎn)單的撤銷(xiāo)和清空的操作
switch (item.type) {
        //撤銷(xiāo)
        case 6:
          if (this.canvas._objects.length > 0) {
            this.canvas._objects.pop();
            // 重繪
            this.canvas.renderAll();
          }
          break;
        //清空
        case 7:
          this.canvas.clear();
          this.canvas.backgroundColor = "#fff";
          break;
        default:
          break;
      }

待續(xù).......

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市矛绘,隨后出現(xiàn)的幾起案子耍休,更是在濱河造成了極大的恐慌,老刑警劉巖货矮,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羊精,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡囚玫,警方通過(guò)查閱死者的電腦和手機(jī)喧锦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)读规,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人燃少,你說(shuō)我怎么就攤上這事束亏。” “怎么了阵具?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵碍遍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我怔昨,道長(zhǎng)雀久,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任趁舀,我火速辦了婚禮赖捌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘矮烹。我一直安慰自己越庇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布奉狈。 她就那樣靜靜地躺著卤唉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仁期。 梳的紋絲不亂的頭發(fā)上桑驱,一...
    開(kāi)封第一講書(shū)人閱讀 51,775評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音跛蛋,去河邊找鬼熬的。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赊级,可吹牛的內(nèi)容都是我干的押框。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼理逊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼橡伞!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起晋被,我...
    開(kāi)封第一講書(shū)人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤兑徘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后羡洛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體挂脑,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了最域。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锈麸,死狀恐怖镀脂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忘伞,我是刑警寧澤薄翅,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站氓奈,受9級(jí)特大地震影響翘魄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舀奶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一暑竟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧育勺,春花似錦但荤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至南蓬,卻和暖如春纺非,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赘方。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工烧颖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒜焊。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓倒信,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親泳梆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鳖悠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容