Vue与Konva:解锁Canvas绘图的无限可能

前言

在现代Web开发中,动态、交互式的图形界面已成为提升用户体验的关键要素。Vue.js,作为一款轻量级且高效的前端框架,凭借其响应式数据绑定和组件化开发模式,赢得了众多开发者的青睐。而当Vue.js邂逅Konva.js,两者结合产生的化学反应更是令人惊叹。今天,就让我们一同深入探索如何利用Vue.js和Konva.js绘制复杂且交互丰富的Canvas图形。


一、Vue Konva简介

Vue Konva是一款基于Vue.js的JavaScript库,它为开发者提供了声明式和响应式的绑定方式,使得在Vue中使用Konva框架变得异常简单。通过Vue Konva,我们可以轻松地在Vue组件中绘制各种复杂的Canvas图形,并且能够实现图形的动态更新和交互。

二、快速上手

  1. 安装
    首先,确保你的项目中已经安装了Vue.js 2.4+版本。接下来,通过npm安装vue-konva和konva:
    对于Vue 3
npm install vue-konva konva --save

对于Vue 2

npm install vue-konva@2 konva --save
  1. 引入和使用VueKonva
    在Vue 3中,你需要在main.js中引入VueKonva并使用它:
import { createApp } from 'vue';
import App from './App.vue';
import VueKonva from 'vue-konva';

const app = createApp(App);
app.use(VueKonva);
app.mount('#app');

在Vue 2中,引入和使用VueKonva的方式如下:

import Vue from 'vue';
import VueKonva from 'vue-konva';

Vue.use(VueKonva);
  1. 在组件模板中引用
    在你的Vue组件中,你可以通过以下方式使用Vue Konva的组件:
<template>
  <v-stage :config="configKonva">
    <v-layer>
      <v-circle :config="configCircle"></v-circle>
    </v-layer>
  </v-stage>
</template>

<script>
export default {
  data() {
    return {
      configKonva: {
        width: 200,
        height: 200
      },
      configCircle: {
        x: 100,
        y: 100,
        radius: 70,
        fill: "red",
        stroke: "black",
        strokeWidth: 4
      }
    };
  }
};
</script>

三、绘制基础图形

Vue Konva提供了与Konva框架相同名称的组件,前缀为v-。你可以通过config属性传递参数来配置这些组件。以下是一些核心形状的示例:

  • v-rect(矩形)
  • v-circle(圆形)
  • v-ellipse(椭圆)
  • v-line(线条)
  • v-image(图片)
  • v-text(文本)
  • v-text-path(文本路径)
  • v-star(星形)
  • v-label(标签)
  • v-path(路径)
  • v-regular-polygon(正多边形)
    在这里插入图片描述
<template>
  <div>
    <v-stage ref="stage" :config="stageSize">
      <v-layer>
        <v-text :config="{text: 'Some text on canvas', fontSize: 15}"/>
        <v-rect :config="{
            x: 20,
            y: 50,
            width: 100,
            height: 100,
            fill: 'red',
            shadowBlur: 10
          }"
        />
        <v-circle :config="{
            x: 200,
            y: 100,
            radius: 50,
            fill: 'green'
          }"
        />
        <v-line :config="{
          x: 20,
          y: 200,
          points: [0, 0, 100, 0, 100, 100],
          tension: 0.5,
          closed: true,
          stroke: 'black',
          fillLinearGradientStartPoint: { x: -50, y: -50 },
          fillLinearGradientEndPoint: { x: 50, y: 50 },
          fillLinearGradientColorStops: [0, 'red', 1, 'yellow']
        }"/>
      </v-layer>
      <v-layer ref="dragLayer"></v-layer>
    </v-stage>
  </div>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;
export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      }
    };
  }
};
</script>

四、自定义形状

除了基础形状,Vue Konva还允许你创建自定义形状。通过使用v-shape组件,你可以定义一个绘图函数,该函数接收一个Konva.Canvas渲染器,你可以利用它访问HTML5 Canvas上下文,并使用特殊方法如context.fillStrokeShape(shape)来自动处理填充、描边和阴影效果。
在这里插入图片描述

<template>
    <v-stage ref="stage" :config="stageSize">
      <v-layer>
        <v-shape :config="{
        width: 260,
        height: 170,
        sceneFunc: function (context, shape) {
          const width = shape.width();
          const height = shape.height();
          context.beginPath();
          context.moveTo(0, 0);
          context.lineTo(width - 40, height - 90);
          context.quadraticCurveTo(width - 110, height - 70, width, height);
          context.closePath();

          // (!) Konva特定方法,非常重要
          context.fillStrokeShape(shape);
        },
        fill: '#00D2FF',
        stroke: 'black',
        strokeWidth: 4
      }"/>
    </v-layer>
  </v-stage>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      }
    };
  }
};
</script>

五、事件监听

Vue Konva使得监听用户输入事件(如click、dblclick、mouseover、tap、dbltap、touchstart等)和拖拽事件(如dragstart、dragmove、dragend)变得非常简单。你可以通过在组件上添加事件监听器来实现这些功能。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

<template>
<v-stage ref="stage" :config="stageSize">
      <v-layer ref="layer">
        <v-regular-polygon
          @mousemove="handleMouseMove"
          @mouseout="handleMouseOut"
          :config="{
            x: 80,
            y: 120,
            sides: 3,
            radius: 80,
            fill: '#00D2FF',
            stroke: 'black',
            strokeWidth: 4
          }"
        />
        <v-text ref="text" :config="{
          x: 10,
          y: 10,
          fontFamily: 'Calibri',
          fontSize: 24,
          text: text,
          fill: 'black'
        }" />
      </v-layer>
    </v-stage>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      },
      text: ''
    };
  },
  methods: {
    writeMessage(message) {
      this.text = message;
    },
    handleMouseOut(event) {
      this.writeMessage('Mouseout triangle');
    },
    handleMouseMove(event) {
      const mousePos = this.$refs.stage.getNode().getPointerPosition();
      const x = mousePos.x - 190;
      const y = mousePos.y - 40;
      this.writeMessage('x: ' + x + ', y: ' + y);
    }
  }
};
</script>

六、绘制图片

在Vue Konva中,绘制图片需要手动创建一个原生的window.Image实例或canvas元素,并将其作为v-image组件的image属性。
在这里插入图片描述

<template>
  <v-stage ref="stage" :config="stageSize">
    <v-layer ref="layer">
      <v-image :config="{
            image: image
          }"/>
    </v-layer>
  </v-stage>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      },
      image: null
    };
  },
  created() {
    const image = new window.Image();
    image.src = "https://konvajs.org/assets/yoda.jpg";
    image.onload = () => {
      // 图片加载完成后设置
      this.image = image;
    };
  }
};
</script>

七、应用滤镜

Vue Konva允许你为图形应用各种滤镜效果。你需要手动缓存Konva.Node,并在需要时重新缓存节点。
在这里插入图片描述

<template>
<v-stage ref="stage" :config="stageSize">
      <v-layer ref="layer">
        <v-rect
          ref="rect"
          @mousemove="handleMouseMove"
          :config="{
            filters: filters,
            noise: 1,
            x: 10,
            y: 10,
            width: 50,
            height: 50,
            fill: color,
            shadowBlur: 10
          }"
        />
      </v-layer>
    </v-stage>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;
import Konva from 'konva';

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      },
      color: 'green',
      filters: [Konva.Filters.Noise]
    };
  },
  methods: {
    handleMouseMove() {
      this.color = Konva.Util.getRandomColor();
      // 重新缓存
      const rectNode = this.$refs.rect.getNode();
      // 可能需要手动重绘图层
      rectNode.cache();
    }
  },
  mounted() {
    const rectNode = this.$refs.rect.getNode();
    rectNode.cache();
  },
};
</script>

八、保存和加载Canvas

Vue Konva提供了简单的方法来保存和加载Canvas状态。你可以通过保存应用的状态来实现这一点,而不需要保存Konva内部的节点。
在这里插入图片描述

<template>
  <div>
    点击Canvas创建一个圆。
    <a href=".">刷新页面</a>。圆应该仍然在这里。
    <v-stage ref="stage"
      :config="stageSize"
      @click="handleClick"
    >
      <v-layer ref="layer">
        <v-circle
          v-for="item in list"
          :key="item.id"
          :config="item"></v-circle>
      </v-layer>
      <v-layer ref="dragLayer"></v-layer>
    </v-stage>
  </div>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      list: [{ x: 100, y: 100, radius: 50, fill: 'blue' }],
      stageSize: {
        width: width,
        height: height
      }
    };
  },
  methods: {
    handleClick(evt) {
      const stage = evt.target.getStage();
      const pos = stage.getPointerPosition();
      this.list.push({
        radius: 50,
        fill: 'red',
        ...pos
      });

      this.save();
    },

    load() {
      const data = localStorage.getItem('storage');
      if (data) this.list = JSON.parse(data);
    },

    save() {
      localStorage.setItem('storage', JSON.stringify(this.list));
    }
  },
  mounted() {
    this.load();
  }
};
</script>

九、拖拽功能

Vue Konva使得实现图形的拖拽功能变得非常简单。你只需要在组件中添加draggable: true属性即可。
在这里插入图片描述
在这里插入图片描述

<template>
<v-stage ref="stage" :config="stageSize">
      <v-layer ref="layer">
        <v-text
          @dragstart="handleDragStart"
          @dragend="handleDragEnd"
          :config="{
            text: 'Draggable Text',
            x: 50,
            y: 50,
            draggable: true,
            fill: isDragging ? 'green' : 'black'
          }"
        />
      </v-layer>
    </v-stage>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      },
      isDragging: false
    };
  },
  methods: {
    handleDragStart() {
      this.isDragging = true;
    },
    handleDragEnd() {
      this.isDragging = false;
    }
  }
};
</script>

十、调整大小和旋转

虽然Vue Konva没有提供纯声明式的“Vue方式”来使用Transformer工具,但你仍然可以通过手动操作Konva节点来实现这一功能。
在这里插入图片描述
在这里插入图片描述

<template>
  <v-stage
    ref="stage"
    :config="stageSize"
    @mousedown="handleStageMouseDown"
    @touchstart="handleStageMouseDown"
  >
    <v-layer ref="layer">
      <v-rect
        v-for="item in rectangles"
        :key="item.id"
        :config="item"
        @transformend="handleTransformEnd"
      />
      <v-transformer ref="transformer" />
    </v-layer>
  </v-stage>
</template>

<script>
import Konva from 'konva';
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height,
      },
      rectangles: [
        {
          rotation: 0,
          x: 10,
          y: 10,
          width: 100,
          height: 100,
          scaleX: 1,
          scaleY: 1,
          fill: 'red',
          name: 'rect1',
          draggable: true,
        },
        {
          rotation: 0,
          x: 150,
          y: 150,
          width: 100,
          height: 100,
          scaleX: 1,
          scaleY: 1,
          fill: 'green',
          name: 'rect2',
          draggable: true,
        },
      ],
      selectedShapeName: '',
    };
  },
  methods: {
    handleTransformEnd(e) {
      // 形状被变换,保存新的属性回节点
      // 在我们的状态中找到元素
      const rect = this.rectangles.find(
        (r) => r.name === this.selectedShapeName
      );
      // 更新状态
      rect.x = e.target.x();
      rect.y = e.target.y();
      rect.rotation = e.target.rotation();
      rect.scaleX = e.target.scaleX();
      rect.scaleY = e.target.scaleY();

      // 更改填充色
      rect.fill = Konva.Util.getRandomColor();
    },
    handleStageMouseDown(e) {
      // 点击舞台 - 清除选择
      if (e.target === e.target.getStage()) {
        this.selectedShapeName = '';
        this.updateTransformer();
        return;
      }

      // 点击变换器 - 什么都不做
      const clickedOnTransformer =
        e.target.getParent().className === 'Transformer';
      if (clickedOnTransformer) {
        return;
      }

      // 通过名称找到被点击的矩形
      const name = e.target.name();
      const rect = this.rectangles.find((r) => r.name === name);
      if (rect) {
        this.selectedShapeName = name;
      } else {
        this.selectedShapeName = '';
      }
      this.updateTransformer();
    },
    updateTransformer() {
      // 手动附加或分离变换器节点
      const transformerNode = this.$refs.transformer.getNode();
      const stage = transformerNode.getStage();
      const { selectedShapeName } = this;

      const selectedNode = stage.findOne('.' + selectedShapeName);
      // 如果选定节点已经附加,则什么都不做
      if (selectedNode === transformerNode.node()) {
        return;
      }

      if (selectedNode) {
        // 附加到另一个节点
        transformerNode.nodes([selectedNode]);
      } else {
        // 移除变换器
        transformerNode.nodes([]);
      }
    },
  },
};
</script>

十一、动画效果

Vue Konva允许你为图形添加动画效果。你可以使用Konva的Tween和Animation方法来实现这一点。
在这里插入图片描述
在这里插入图片描述

<template>
  <v-stage ref="stage" :config="stageSize">
    <v-layer ref="layer">
      <v-rect
        ref="rect"
        @dragstart="changeSize"
        @dragend="changeSize"
        :config="{
            width: 50,
            height: 50,
            fill: 'green',
            draggable: true
          }"
      />
      <v-regular-polygon
        ref="hexagon"
        :config="{
          x: 200,
          y: 200,
          sides: 6,
          radius: 20,
          fill: 'red',
          stroke: 'black',
          strokeWidth: 4
        }"
      />
    </v-layer>
  </v-stage>
</template>

<script>
import Konva from "konva";
const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      stageSize: {
        width: width,
        height: height
      }
    };
  },
  methods: {
    changeSize(e) {
      // to()是Konva.Node实例的方法
      e.target.to({
        scaleX: Math.random() + 0.8,
        scaleY: Math.random() + 0.8,
        duration: 0.2
      });
    }
  },
  mounted() {
    const vm = this;
    const amplitude = 100;
    const period = 5000;
    // in ms
    const centerX = vm.$refs.stage.getNode().getWidth() / 2;

    const hexagon = this.$refs.hexagon.getNode();

    // Konva.Animation示例
    const anim = new Konva.Animation(function(frame) {
      hexagon.setX(
        amplitude * Math.sin((frame.time * 2 * Math.PI) / period) + centerX
      );
    }, hexagon.getLayer());

    anim.start();
  }
};
</script>

十二、缓存图形

在Vue Konva中,你可以通过访问Konva节点并使用node.cache()函数来缓存节点。
在这里插入图片描述

<template>
  <div>
    <v-stage ref="stage" :config="stageConfig">
      <v-layer ref="layer">
        <v-group ref="group">
          <v-star
            v-for="item in list"
            :key="item.id"
            :config="{
            x: item.x,
            y: item.y,
            rotation: item.rotation,
            id: item.id,
            numPoints: 5,
            innerRadius: 30,
            outerRadius: 50, fill: '#89b717',
            opacity: 0.8,
            shadowColor: 'black',
            shadowBlur: 10,
            shadowOpacity: 0.6,
            scaleX: item.scale,
            scaleY: item.scale,
          }"
          />
        </v-group>
      </v-layer>
    </v-stage>
    <div class="cache">
      <input type="checkbox" @change="handleCacheChange"> 缓存图形
    </div>
  </div>
</template>

<script>
const width = window.innerWidth;
const height = window.innerHeight;
export default {
  data() {
    return {
      list: [],
      dragItemId: null,
      stageConfig: {
        width: width,
        height: height,
        draggable: true
      }
    };
  },
  methods: {
    handleCacheChange(e) {
      const shouldCache = e.target.checked;
      if (shouldCache) {
        this.$refs.group.getNode().cache();
      } else {
        this.$refs.group.getNode().clearCache();
      }
    }
  },
  mounted() {
    for (let n = 0; n < 300; n++) {
      this.list.push({
        id: Math.round(Math.random() * 10000).toString(),
        x: Math.random() * width,
        y: Math.random() * height,
        rotation: Math.random() * 180,
        scale: Math.random()
      });
    }
  }
};
</script>

<style>
body {
  margin: 0;
  padding: 0;
}

.cache {
  position: absolute;
  top: 0;
  left: 0;
}
</style>

十三、改变zIndex和组件排序
在Vue Konva中,不推荐直接使用zIndex来改变组件的堆叠顺序。相反,你应该通过更新应用的数据来确保组件在模板中的顺序正确。
在这里插入图片描述
在这里插入图片描述

<template>
  <div>
    <v-stage ref="stage" :config="configKonva">
      <v-layer ref="layer">
        <v-circle
          v-for="item in items"
          :key="item.id"
          :config="item"
          @dragstart="handleDragstart"
          @dragend="handleDragend"
        ></v-circle>
      </v-layer>
    </v-stage>
  </div>
</template>

<script>
import Konva from "konva";
const width = window.innerWidth;
const height = window.innerHeight;

function generateItems() {
  const items = [];
  for (let i = 0; i < 10; i++) {
    items.push({
      x: Math.random() * width,
      y: Math.random() * height,
      radius: 50,
      id: "node-" + i,
      fill: Konva.Util.getRandomColor(),
      draggable: true,
    });
  }
  return items;
}

export default {
  data() {
    return {
      items: [],
      dragItemId: null,
      configKonva: {
        width: width,
        height: height,
      },
    };
  },
  methods: {
    handleDragstart(e) {
      // 保存拖动元素:
      this.dragItemId = e.target.id();
      // 通过重新排列items数组,将当前元素移动到顶部:
      const item = this.items.find((i) => i.id === this.dragItemId);
      const index = this.items.indexOf(item);
      this.items.splice(index, 1);
      this.items.push(item);
    },
    handleDragend(e) {
      this.dragItemId = null;
    },
  },
  mounted() {
    this.items = generateItems();
  },
};
</script>

<style>
body {
  margin: 0;
  padding: 0;
}
</style>

总结

通过以上内容,我们全面地介绍了Vue Konva的各种功能和用法。从基础图形的绘制到复杂的动画效果,Vue Konva都提供了强大的支持。希望这篇博客能够帮助你更好地理解和使用Vue Konva,为你的Web应用增添更多的交互性和视觉效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/967050.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

8.JVM-方法区

前言 这次所讲述的是运行时数据区的最后一个部分 从线程共享与否的角度来看 ThreadLocal&#xff1a;如何保证多个线程在并发环境下的安全性&#xff1f;典型应用就是数据库连接管理&#xff0c;以及会话管理 栈、堆、方法区的交互关系 下面就涉及了对象的访问定位 Person&a…

面向对象程序设计-实验3

题目1 &#xff08;给出题目描述&#xff09;设计一个类CRectangle 代码清单&#xff1a; #include<iostream> using namespace std; class CRectangle { public: CRectangle() { m_l1.0; m_w1.0; } void get() { cin>>m_l; if(m_l>50) { m_l1.0; } cin&g…

边缘计算网关驱动智慧煤矿智能升级——实时预警、低延时决策与数字孪生护航矿山安全高效运营

迈向智能化煤矿管理新时代 工业物联网和边缘计算技术的迅猛发展&#xff0c;煤矿安全生产与高效运营正迎来全新变革。传统煤矿监控模式由于现场环境复杂、数据采集和传输延时较高&#xff0c;已难以满足当下高标准的安全管理要求。为此&#xff0c;借助边缘计算网关的实时数据…

deepseek本地部署+web图形化页面配置+对比其他ai模型

公众号&#xff1a;泷羽Sec-尘宇安全 前言 最近deepseek非常火&#xff0c;训练成本低&#xff0c;其预训练费用仅为OpenAI GPT-4o模型的不到十分之一&#xff0c;但是效果堪比OpenAI&#xff0c;使用深度思考&#xff0c;回答的问题很不错&#xff0c;啥都敢说 可惜惨遭ddos…

Deepseek 接入Word处理对话框(隐藏密钥)

硅基流动邀请码&#xff1a;1zNe93Cp 邀请链接&#xff1a;网页链接 亲测deepseek接入word&#xff0c;自由调用对话&#xff0c;看截图有兴趣的复用代码&#xff08;当然也可以自己向deepseek提问&#xff0c;帮助你完成接入&#xff0c;但是提问逻辑不一样给出的答案是千差万…

从家庭IP到全球网络资源的无缝连接:Cliproxy的专业解决方案

数字化时代&#xff0c;家庭IP作为个人或家庭接入互联网的门户&#xff0c;其重要性日益凸显。然而&#xff0c;要实现从家庭IP到全球网络资源的无缝连接&#xff0c;并享受高效、安全、稳定的网络访问体验&#xff0c;往往需要借助专业的代理服务。Cliproxy&#xff0c;作为业…

微信点餐系统小程序ssm+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

牛客寒假集训营2

A 牛客传送门 代码如下: const int N2e610,M1e410; const int INF0x3f3f3f3f; const int mod998244353; ll n;void solve(){map<int,int>mp;mp[1]mp[2]mp[3]mp[5]mp[6]1;for(int i1;i<7;i){int a…

第3章 使用 Vue 脚手架

第3章 使用 Vue 脚手架 3.1 初始化脚手架3.1.1 说明3.1.2. 具体步骤3.1.3 分析脚手架结构1 总结2 细节分析1 配置文件2 src文件1 文件结构分析2 例子 3 public文件4 最终效果 3.2 ref属性3.3 props配置项3.4 mixin混入3.5 插件3.6 scoped样式3.7 Todo-list 案例3.7.1 组件化编码…

去除install4j学习版生成的安装程序和主程序的neg弹窗的解决思路

文章目录 去除install4j学习版生成的安装程序和主程序的neg弹窗的解决思路概述笔记打补丁之前打补丁之后 效果备注 END 去除install4j学习版生成的安装程序和主程序的neg弹窗的解决思路 概述 最近可能有修改openpnp源码并打包的需求。 openpnp2.2 用 install4j 10.0.5 来打包…

前后端服务配置

1、安装虚拟机&#xff08;VirtualBox或者vmware&#xff09;&#xff0c;在虚拟机上配置centos(选择你需要的Linux版本)&#xff0c;配置如nginx服务器等 1.1 VMware 下载路径Sign In注册下载 1.2 VirtualBox 下载路径https://www.virtualbox.org/wiki/Downloads 2、配置服…

基于javaweb的SpringBoot+MyBatis毕业设计选题答辩管理系统(源码+文档+部署讲解)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具技术框架适用功能说明eclipse/MyEclipse运行&#xff1a; ![在这里插入图片描述](https://i-blog.csdnimg.cn/dir…

【Elasticsearch】nested聚合

在 Elasticsearch 中&#xff0c;嵌套聚合&#xff08;nestedaggregation&#xff09;的语法形式用于对嵌套字段&#xff08;nestedfields&#xff09;进行聚合操作。嵌套字段是 Elasticsearch 中的一种特殊字段类型&#xff0c;用于存储数组中的对象&#xff0c;这些对象需要独…

Linux第106步_Linux内核RTC驱动实验

1、了解rtc_device结构体 1)、打开“include/linux/rtc.h” rtc_class_ops是需要用户根据所使用的RTC设备编写的,其结构体如下: struct rtc_class_ops { int (*ioctl)(struct device *, unsigned int, unsigned long);/*函数指针ioctl*/ int (*read_time)(struct device *,…

微信小程序案例2——天气微信小程序(学会绑定数据)

文章目录 一、项目步骤1 创建一个weather项目2 进入index.wxml、index.js、index.wxss文件,清空所有内容,进入App.json,修改导航栏标题为“中国天气网”。3进入index.wxml,进行当天天气情况的界面布局,包括温度、最低温、最高温、天气情况、城市、星期、风行情况,代码如下…

Linux系统-centos防火墙firewalld详解

Linux系统-centos7.6 防火墙firewalld详解 1 firewalld了解 CentOS 7.6默认的防火墙管理工具是firewalld&#xff0c;它取代了之前的iptables防火墙。firewalld属于典型的包过滤防火墙或称之为网络层防火墙&#xff0c;与iptables一样&#xff0c;都是用来管理防火墙的工具&a…

Sealos的k8s高可用集群搭建

Sealos 介绍](https://sealos.io/zh-Hans/docs/Intro) Sealos 是一个 Go 语言开发的简单干净且轻量的 Kubernetes 集群部署工具&#xff0c;能很好的支持在生产环境中部署高可用的 Kubernetes 集群。 Sealos 特性与优势 支持离线安装&#xff0c;工具与部署资源包分离&#…

算法篇——动态规划

核心思想&#xff1a; 将问题分解为重叠的子问题&#xff0c;并储存子问题的解&#xff08;使用字典、数组或哈希表&#xff09;&#xff0c;避免重复计算&#xff0c;从而提高效率。 题目特点&#xff1a;重叠子问题&#xff08;特殊地&#xff0c;是最优子结构&#xff09; …

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码及效果展示

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码示例&#xff0c;使用Arduino语言&#xff1a; 硬件连接 INMP441 VCC → ESP32的3.3VINMP441 GND → ESP32的GNDINMP441 SCK → ESP32的GPIO 17INMP441 WS → ESP32的GPIO 18INMP441 SD → ESP32的GPIO 16RG…

零基础学习书生.浦语大模型--基础岛

第二关:玩转书生[多模态对话]和[AI搜索]产品 任务一&#xff1a;使用MindSearch 任务二&#xff1a;尝试使用书生.浦语 尝试让其写一段Self-Attention网络模块代码 import torch import torch.nn as nn import torch.nn.functional as Fclass SelfAttention(nn.Module):def _…