初始kineticjs一


由於kineticjs作者大約有6年沒有更新了,所以文檔也很少,接下來我們就來操作一波

kineticjs可以說是對canvas進行的一次封裝,具體沒看,個人理解,直接調用方法就好了

拿到框架直接引入就是干

既然是繪制類的js庫,那肯定要從簡單的入手,繪制形狀,線條,圖片等等,先易后難,你們說對吧

kineticjs是需要你先new一個Kinetic對象的,然后創建舞台stage,接着就是往舞台上添加圖層layer,圖層上可以繪制text icon img line,對了,還有一個點需要注意一下:只有舞台可以添加多個layer,這個layer是不能嵌套的,但是kineticjs也提供了一個group的方法,讓你將多個layer分成一個組放在一起

話不多說,線上代碼,由於我是在vue+ts項目下編寫的,所以下面的代碼可能需要vue的基礎,不過現在大多數的公司前端都會vue,應該不是難事

我是直接在public/index.html中引入的kineticjs文件

<script type="text/javascript" src="js/kinetic-v5.1.0.min.js"></script>

先放出目錄結構

 

 

 主要是在app.vue和publicMap.ts這個兩個文件中編寫的

app.vue

<template>
  <div id="app">
    <div id="container"></div>
    <div class="rg">
      <div>編輯標簽</div>
      <div class="item">
        <el-row :gutter="20">
          <el-col :span="18">
            <div class="grid-content bg-purple">
              <el-input v-model="form.name" @change="changeName"></el-input>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.nameColor"></el-color-picker>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="item">
        <el-row :gutter="20">
          <el-col :span="18">
            <div class="grid-content bg-purple">
              <el-input v-model="form.price"></el-input>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.priceColor"></el-color-picker>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="item">
        <el-row :gutter="20">
          <el-col :span="8">
            <div class="grid-content bg-purple">背景</div>
          </el-col>
          <el-col :span="8">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.nameBg"></el-color-picker>
            </div>
          </el-col>
          <el-col :span="8">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.priceBg"></el-color-picker>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="item">
        <el-row :gutter="20">
          <el-col :span="18">
            <div class="grid-content bg-purple">
              <el-input v-model="form.type"></el-input>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.typeColor"></el-color-picker>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="item">
        <el-row :gutter="20">
          <el-col :span="18">
            <div class="grid-content bg-purple">
              <el-input v-model="form.dt"></el-input>
            </div>
          </el-col>
          <el-col :span="6">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.dtColor"></el-color-picker>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="item">
        <el-row :gutter="20">
          <el-col :span="16">
            <div class="grid-content bg-purple">背景</div>
          </el-col>
          <el-col :span="8">
            <div class="grid-content bg-purple">
              <el-color-picker v-model="form.typeBg" @change="changeTypeBg"></el-color-picker>
            </div>
          </el-col>
        </el-row>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { PublicMap } from "./utils/publicMap";

@Component
export default class App extends Vue {
  scene: any;
  form = {
    name: "現價",
    price: "¥99.0000",
    nameColor: "#080808",
    priceColor: "#ffffff",
    nameBg: "#F4E803",
    priceBg: "#F40303",
    type: "HOT IN SUMMER",
    dt: "夏季熱賣",
    typeColor: "#ffffff",
    dtColor: "#ffffff",
    typeBg: "#0733F5"
  };
  mounted() {
    console.log(window);
    this.getInit();
  }
  getInit() {
    this.scene = new PublicMap("container");
    this.scene.init();
  }
}
</script>

<style lang="less">
* {
  margin: 0;
  padding: 0;
}
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  justify-content: space-between;
  .item {
    margin: 20px;
    display: flex;
    align-items: center;
  }
}
</style>

這個文件中需要說一下,template中

<div id="container"></div>主要是這個,這個是舞台的容器

publicMap是我封裝的一個對象而已,里面的init方法是初始化創建舞台的方法
publicMap.ts
class PublicMap {
    rootId: string;
    stage: any;
    group1: any;
    group2: any;
    constructor(id: any) {
        // 創建時傳進來的容器id
        this.rootId = id;
    }
    //初始化舞台
    init() {
        this.stage = new (window as any).Kinetic.Stage({
            container: this.rootId,
            width: 400,
            height: 400
        });
        this.drawImg()
    }
    //繪制圖片
    drawImg() {
        const layer = new (window as any).Kinetic.Layer();
        const imageObj = new Image();
        imageObj.onload = () => {
            const yoda = new (window as any).Kinetic.Image({
                x: 0,
                y: 0,
                image: imageObj,
                width: 400,
                height: 400,
            });
            layer.add(yoda);
            this.stage.add(layer);
            this.drawRect()
            this.drawRect2()
        };
        imageObj.src = "./test.png";
    }
    // 繪制第一個group
    drawRect() {
        const group = new (window as any).Kinetic.Group({
            draggable: true, // 允許拖拽需要配置為true
        });
        const layer = new (window as any).Kinetic.Layer();
        const rect = new (window as any).Kinetic.Rect({
            width: 100,
            height: 50,
            fill: '#F4E803'
        });
        const textpath = new (window as any).Kinetic.Text({
            id: 'id2',
            x: 26,
            y: 13,
            fill: '#080808',
            fontSize: '24',
            fontFamily: 'Arial',
            text: '現價'
        });
        const rect1 = new (window as any).Kinetic.Rect({
            x: 100,
            y: 0,
            width: 200,
            height: 50,
            fill: '#F40303'
        });
        const textpath1 = new (window as any).Kinetic.Text({
            x: 120,
            y: 13,
            fill: '#ffffff',
            fontSize: '24',
            fontFamily: 'Arial',
            text: '¥99.0000'
        });
        group.add(rect)
        group.add(textpath)
        group.add(rect1)
        group.add(textpath1)
        layer.add(group)
        this.group1 = group
        this.stage.add(layer);
    }
    // 繪制第二個group
    drawRect2() {
        const group = new (window as any).Kinetic.Group({
            draggable: true,// 允許拖拽需要配置為true
        });
        const layer = new (window as any).Kinetic.Layer();
        const rect = new (window as any).Kinetic.Rect({
            id:'id1',
            x:50,
            y:200,
            width: 300,
            height: 100,
            fill: '#0733F5'
        });
        console.log(rect)
        const textpath = new (window as any).Kinetic.Text({
            x: 110,
            y: 220,
            fill: '#ffffff',
            fontSize: '24',
            fontFamily: 'Arial',
            text: 'HOT IN SUMMER'
        });
        const line = new (window as any).Kinetic.Line({
            x: 0,
            y: 0,
            points: [120, 250, 280, 250],
            stroke: '#ffffff',
          });
        const textpath1 = new (window as any).Kinetic.Text({
            x: 150,
            y: 260,
            fill: '#ffffff',
            fontSize: '24',
            fontFamily: 'Arial',
            text: '夏季熱賣'
        });
        group.add(rect)
        group.add(textpath)
        group.add(line)
        group.add(textpath1)
        layer.add(group)
        this.group2 = group
        this.stage.add(layer);
    }
    // 繪制文本
    drawText() {
        const layer = new (window as any).Kinetic.Layer();
        const textpath = new (window as any).Kinetic.TextPath({
            x: 100,
            y: 50,
            fill: '#333',
            fontSize: '24',
            fontFamily: 'Arial',
            text: 'All the world\'s a stage, and all the men and women merely players.',
            data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50'
        });

        layer.add(textpath);
        this.stage.add(layer);
    }
}

export { PublicMap }

上面就包含了繪制文本,繪制圖片,繪制形狀,繪制線條等方法

界面如下:

 

 靜態繪制了之后,可能有需求需要動態的修改文字顏色等信息

圖片右邊的表單用的elementui的,可以自行處理

接下來說兩個點,一個動態修改背景,一個動態修改文本,其實兩個都差不多的

不知道大家有沒有注意到我上面在繪制rect/Text的時候添加了id的

這個id要是唯一的,因為修改的時候你需要獲取這個對象

修改背景顏色,就添加一個@change事件,然后再change事件中獲取對象,修改對象,重新繪制

changeTypeBg() {
    this.scene.stage.get("#id1")[0].clearCache();
    this.scene.stage.get("#id1")[0].setFill(this.form.typeBg);
    this.scene.stage.draw();
  }

修改之后調用stage的draw方法,非常重要,不調用的話,你打印出來會看到確實顏色改了,但是界面不會渲染,這點需要注意哦

修改文字

changeName() {
    this.scene.stage.get("#id2")[0].clearCache();
    this.scene.stage.get("#id2")[0].setText(this.form.name);
    this.scene.stage.draw();
  }

好了,看一下修改之后的效果

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM