Konva上手实践(一)

3,108 阅读4分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

背景

因为要做一个可视化拖动组件生成海报的项目,一种方案是使用html2canvas,而另一种是通过canvas,因为像尝试一下,所有准备基于Canvas来做这个,但是手写Canvas工作量肯定不小,所以秉着能偷点懒就偷点懒的原则去寻找相应的Canvas操作库,在一番寻找之后发现了两个比较合适的Canvas

fabric是一个老牌canvas库,基本常用功能都已经封装好了,常用组件和功能很完善,比如选择功能支持,可以直接通过属性 selectable一键开启,相当快捷.

konva相对fabric就是一个生力军,它使用了TypeScript编写,对TypeScript原生支持,而且有着清晰的层级渲染Stage -> Layer -> Group -> Shape,代码体积也相对fabric要精简一些.

fabrickonva在文档上面都非常丰富,它们都有着完成的教程文档以及相应的api文档,大多数问题都可以在文档中找到答案.

konva可输入组件上(TextBox)上的实现要比fabric差一些,fabric提供了TextBox组件,直接可以支持文本编辑,而konva需要通过dom进行交互去实现.

不过还是选择的konva来进行开发,毕竟TypeScript类型提示和Layer的层级结构更符合用户直觉.

安装Konva

正如官网所说,Konva.js - HTML5 2d canvas js library for desktop and mobile ,konva是一个专门面向基于canvas的2d操作库, 可以很好的适用于桌面端和移动端开发.

konva中有着

  • Stage
  • Layer
  • Group
  • Shape

几种节点类型,其中Stage作为根节点,Layer表示根节点下的图层,图层Layer下可以直接包含Shape也可是通过Group来组合图形,Shape也就是我们最终创建的各种图形和图片节点.

              Stage
                |
         +------+------+
         |             |
       Layer         Layer
         |             |
   +-----+-----+     Shape
   |           |
 Group       Group
   |           |
   +       +---+---+
   |       |       |
Shape   Group    Shape
           |
           +
           |
         Shape

我们首先安装konva

npm install konva

也可以script进行加载

<script src="https://unpkg.com/konva@8/konva.min.js"></script> 

创建舞台

为了实现舞台的缩放和显示我们需要预先定义布局默认的缩放比以及尺寸.

export const appConfig = {
    editor: {
        content: {
            scale: 3,
            width: 1080,
            height: 1920
        }
    }
}

这样我们可以假设我们创建了一个显示区域,它的默认宽度是1080px,默认高度是1920px,但是如果按这个尺寸显示在界面,那肯定会占满整个屏幕,所以我们设置默认缩放比为3,就是说会按1080/3,1920/3进行显示在界面上,但是导出图片依然按照1080x1920进行导出.

下来我们来创建舞台

<div
    id="canvas-container"
    bind:this="{container}"
    class="content-container absolute inset-0">
</div>
const width = container.clientWidth
const height = container.clientHeight

// 创建舞台实例
const stage = new Konva.Stage({
    container: container,
    width: width,
    height: height
})

我们创建div作为容器,按容器的clientWidth,clientHeight来创建Stage.

下来我们创建内容区域,已经背景区域

// 获取图层尺寸
const { width, height, scale } = appConfig.editor.content
// 创建内容布局
const contentLayer = new Konva.Layer({
    name: 'content',
    x: stage.width() / 2 - width / 2,
    y: stage.height() / 2 - height / 2,
    scaleX: 1 / scale,
    scaleY: 1 / scale,
    clip: {
        x: 0,
        y: 0,
        width: width,
        height: height
    }
})

我们把内容区域放置到舞台的中间,appConfig.editor.content.width,appConfig.editor.content.height是我们默认配置的内容布局尺寸,appConfig.editor.content.scale是默认设置的缩放比例.

konvaLayer不支持设置widthheight,但是我们可以通过clip按我们需要的宽度高度进行裁剪

下来我们创建背景区域

const backgroundLayer = new Konva.Layer({ name: 'background' }

现在我们在视觉上并没有办法区别出内容区域与背景区域的区别,我们为内容区域添加背景.

const { width, height } = appConfig.editor.content
// 创建背景图形
const background = new Konva.Rect({
    width: width,
    height: height,
    fill: '#fff',
    name: 'background'
})
// 添加背景到图层
contentLayer.add(background)

将内容区域和背景区域都添加到舞台:

// 添加图层
stage.add(contentLayer)
stage.add(backgroundLayer)
// 重绘布局
contentLayer.draw()
backgroundLayer.draw()

现在我们把基本的舞台创建完成.

image.png

之后我们需要添加舞台的缩放功能以及其他功能.

源码地址: github

如果您觉得这篇文章有帮助到您的的话不妨🍉关注+点赞+收藏+评论+转发🍉支持一下哟~~😛