Table des matières
Captures d'écran
Analyse des exigences
Rotation
Échelle
Exporter l'image
Maison Applet WeChat Développement de mini-programmes Utilisez le petit canevas de programme pour écrire une application d'image simple

Utilisez le petit canevas de programme pour écrire une application d'image simple

Dec 16, 2020 pm 06:00 PM
canvas 前端 小程序

Tutoriel de développement de mini-programmesLa colonne présente l'utilisation de Canvas pour écrire une image

Utilisez le petit canevas de programme pour écrire une application d'image simple

Recommandé (gratuit) : Tutoriel de développement de mini-programmes

Affichage de l'application

Captures d'écran

Utilisez le petit canevas de programme pour écrire une application dimage simple

Exigences

Comme il s'agit d'une petite application, j'espère que le produit final aura des scénarios applicables Et c'est une précieuse

source de demande

inspiration pour cette demande d'application

Dans ma vie professionnelle précédente, j'ai souvent obtenu des idées par inadvertance de mes collèguesBelle photo

Pour le moment, nous souhaitons transformer cette photo en un paquet d'émoticônes

Ajouter généralement quelques légendes à l'image

Une communication intéressante L'outil (pack émoticônes) est complété

Analyse des exigences

Basée sur le démantèlement des exigences ci-dessus

Vous pouvez trier la mise en œuvre du fonctions de l'application

  • Les utilisateurs doivent télécharger une image
  • peuvent ajouter du texte
  • le texte peut être ajusté le style et rotation et zoom
  • De plus, nous espérons insérer des autocollants
  • Les autocollants peuvent être réalisésRotation et zoom
  • Les utilisateurs peuvent exporter photos de l'album

Mise en œuvre

dépôt github https://github.com/luosijie/f...

Si vous aimez mon projet, donnez-moi une étoile pour m'encourager Jetez un oeil

Cette application est développée à l'aide d'un mini programme

  • Utilisation du framework : mpx
  • Utilisation de la technologie : mini programme canevas

Gestion de l'état

import { createStore } from '@mpxjs/core'

const store = createStore({
  state: {
    cavas: null,         // cnavas实例
    ctx: null,           // canvas上下文实例
    elements: [],        // canvas元素
    activeIndex: null,   // 当前编辑中的元素索引
    mode: 'background',  // 当前编辑模式:background, text, sticker
    fontStyle: {         // 文字默认样式
      opacity: 1,
      fillStyle: '#000000',
      strokeStyle: '#000000'
    }
  },
  mutations: {
    setCanvas (state, data) {
      state.canvas = data
    },
    setCtx (state, data) {
      state.ctx = data
    },
    setElements (state, data) {
      state.elements = data
    },
    setMode (state, data) {
      state.mode = data
    },
    setActiveIndex (state, data) {
      state.activeIndex = data
    },
    setFontStyle (state, { key, data }) {
      state.fontStyle[key] = data
    },
    // 添加文字
    addText (state) {
      const size = 50
      const string = '请输入文字'
      const text = {
        type: 'text',
        data: string,
        scale: 1,
        size,
        left: 100,
        top: 100,
        rotate: 0,
        opacity: state.fontStyle.opacity,
        fillStyle: state.fontStyle.fillStyle,
        strokeStyle: state.fontStyle.strokeStyle
      }
      state.elements.push(text)
      state.activeIndex = state.elements.length - 1
    },
    // 添加贴图
    addSticker (state, data) {
      state.elements.push(data)
      state.activeIndex = state.elements.length - 1
    },
    // 删除当前选中
    deleteActiveELement (state) {
      state.elements.splice(state.activeIndex, 1)
      state.activeIndex = null
    },
    // 清空画布
    clear (state) {
      state.elements = []
      state.activeIndex = null
    }
  }
})

export default store
Copier après la connexion

Initialisation du canevas

// 初始化画布
async initCanvas() {
  const query = this.createSelectorQuery()
  query
    .select('#canvas')
    .fields({ node: true, size: true })
    .exec(async res => {
      const canvas = res[0].node
      const ctx = canvas.getContext('2d')
      store.commit('setCanvas', canvas)
      store.commit('setCtx', ctx)

      await this.loadImage('/images/icon-rotate.png').then(res => {
        this.image.rotate = res
      })

      canvas.width = res[0].width * this.dpr
      canvas.height = res[0].height * this.dpr
      ctx.scale(this.dpr, this.dpr)
      this.drawGrid()
    })
}
Copier après la connexion

Dessiner des images

/**
 * 绘制图片
 * @param { Object } ele canvas元素
 */
drawImage(ele) {
  this.ctx.save()
  const width = ele.width
  const height = ele.height
  const centerX = ele.left + ele.width / 2
  const centerY = ele.top + ele.height / 2
  this.ctx.translate(centerX, centerY)
  this.ctx.rotate(ele.rotate)
  this.ctx.drawImage(ele.data, ele.left - centerX, ele.top - centerY, width, height)
  this.ctx.restore()
}
Copier après la connexion

Dessiner du texte

/**
 * 绘制文字
 * @param { Object } ele canvas元素
 */
drawText(ele) {
  this.ctx.save()
  const width = ele.size * ele.data.length
  const height = ele.size
  const centerX = ele.left + width / 2
  const centerY = ele.top + height / 2
  this.ctx.translate(centerX, centerY)
  this.ctx.rotate(ele.rotate)
  this.ctx.font = `${ele.size}px bold sans-serif`
  this.ctx.globalAlpha = ele.opacity
  this.ctx.fillStyle = ele.fillStyle
  this.ctx.strokeStyle = ele.strokeStyle
  // this.ctx.lineWidth = 2
  this.ctx.textBaseline = 'top'
  console.log('draw-text', ele)
  this.ctx.fillText(ele.data, ele.left - centerX, ele.top - centerY)
  this.ctx.strokeText(ele.data, ele.left - centerX, ele.top - centerY)
  this.ctx.restore()
}
Copier après la connexion

Dessiner un élément de contrôle

initController(ele) {
  const cs = this.convert2ControllerSize(ele)
  this.ctx.save()
  this.ctx.strokeStyle = '#eee'
  this.ctx.translate(cs.centerX, cs.centerY)
  this.ctx.rotate(cs.rotate)
  // 绘制虚线边框
  this.ctx.setLineDash([10, 5], 5)
  this.ctx.strokeRect(cs.left - cs.centerX, cs.top - cs.centerY, cs.width, cs.height)
  // 绘制控制点-旋转
  this.ctx.drawImage(this.image.rotate, cs.left + cs.width - 10 - cs.centerX, cs.top + cs.height - 10 - cs.centerY, 20, 20)
  this.ctx.restore()
}
Copier après la connexion

Fonction de rendu sur toile

// 画布渲染函数
renderCanvas() {
  this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
  this.drawGrid()
  console.log('draw-background', this.background)
  if (this.background) this.drawImage(this.background)
  for (let i = 0; i <p><strong>Écoute d'événements</strong></p><p><strong>Déplacer</strong></p><pre class="brush:php;toolbar:false">// 移动事件绑定函数
handleMove(e) {
  console.log('mouse-move', e)
  if (e.touches.length > 1) return
  const x = e.touches[0].x
  const y = e.touches[0].y
  const dx = this.startTouches[0].x - x
  const dy = this.startTouches[0].y - y
  const elements = this.elements.slice()
  elements[this.activeIndex || 0].left = this.startSelected.left - dx
  elements[this.activeIndex || 0].top = this.startSelected.top - dy
  store.commit('setElements', elements)
}
Copier après la connexion

Rotation

// 旋转绑定函数
handleRotate(e) {
  console.log('handleRotate')
  const start = this.startTouches[0]
  const end = e.touches[0]
  const center = {
    x: this.startSelected.centerX,
    y: this.startSelected.centerY
  }
  const startLength = Math.sqrt((center.x - start.x) ** 2 + (center.y - start.y) ** 2)
  const endLength = Math.sqrt((center.x - end.x) ** 2 + (center.y - end.y) ** 2)
  const radian = this.convert2Radian(start, end, center)
  const scale = endLength / startLength
  const elements = this.elements.slice()
  const selected = elements[this.activeIndex]
  // 旋转
  selected.rotate = this.startSelected.rotate - radian
  // 缩放
  if (selected.type === 'text') {
    selected.left = this.startSelected.centerX - this.startSelected.size * this.startSelected.data.length * scale / 2
    selected.top = this.startSelected.centerY - this.startSelected.size * scale / 2
    selected.size = this.startSelected.size * scale
  }
  if (selected.type === 'sticker') {
    selected.left = this.startSelected.centerX - this.startSelected.width * scale / 2
    selected.top = this.startSelected.centerY - this.startSelected.height * scale / 2
    selected.width = this.startSelected.width * scale
    selected.height = this.startSelected.height * scale
  }
  store.commit('setElements', elements)
}
Copier après la connexion

Échelle

// 缩放事件绑定函数
handleScale(e) {
  if (e.touches.length !== 2 || this.mode !== 'background') return
  const startLength = Math.sqrt(
    (this.startTouches[0].x - this.startTouches[1].x) ** 2 +
      (this.startTouches[0].y - this.startTouches[1].y) ** 2
  )
  const endLength = Math.sqrt(
    (e.touches[0].x - e.touches[1].x) ** 2 + (e.touches[0].y - e.touches[1].y) ** 2
  )
  const scale = endLength / startLength
  const elements = this.elements.slice()
  const selected = elements[this.activeIndex || 0]
  selected.left = this.startSelected.centerX - this.startSelected.width * scale / 2
  selected.top = this.startSelected.centerY - this.startSelected.height * scale / 2
  selected.width = this.startSelected.width * scale
  selected.height = this.startSelected.height * scale
  // elements[this.activeIndex || 0].scale = this.startSelected.scale * scale
  store.commit('setElements', elements)
}
Copier après la connexion

Exporter l'image

export() {
  if (!store.state.elements.length) {
    wx.showToast({
      title: '加点东西再导出吧',
      icon: 'none'
    })
    return
  }
  wx.showModal({
    title: '提示',
    content: '图片将保存到手机相册',
    success(res) {
      if (res.confirm) {
        console.log('export-canvas', store.state.ctx)
        const canvas = store.state.canvas
        wx.canvasToTempFilePath({
          x: 0,
          y: 0,
          width: canvas.width,
          height: canvas.height,
          canvas,
          complete(res) {
            if (res.errMsg === 'canvasToTempFilePath:ok') {
              wx.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success(res) {
                  wx.showToast({
                    title: '图片保存成功',
                    icon: 'none'
                  })
                }
              })
            }
          }
        })
      }
    }
  })
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP et Vue : une combinaison parfaite d'outils de développement front-end PHP et Vue : une combinaison parfaite d'outils de développement front-end Mar 16, 2024 pm 12:09 PM

PHP et Vue : une combinaison parfaite d'outils de développement front-end À l'ère actuelle de développement rapide d'Internet, le développement front-end est devenu de plus en plus important. Alors que les utilisateurs ont des exigences de plus en plus élevées en matière d’expérience des sites Web et des applications, les développeurs front-end doivent utiliser des outils plus efficaces et plus flexibles pour créer des interfaces réactives et interactives. En tant que deux technologies importantes dans le domaine du développement front-end, PHP et Vue.js peuvent être considérés comme une arme parfaite lorsqu'ils sont associés. Cet article explorera la combinaison de PHP et Vue, ainsi que des exemples de code détaillés pour aider les lecteurs à mieux comprendre et appliquer ces deux éléments.

Questions fréquemment posées par les enquêteurs front-end Questions fréquemment posées par les enquêteurs front-end Mar 19, 2024 pm 02:24 PM

Lors des entretiens de développement front-end, les questions courantes couvrent un large éventail de sujets, notamment les bases HTML/CSS, les bases JavaScript, les frameworks et les bibliothèques, l'expérience du projet, les algorithmes et les structures de données, l'optimisation des performances, les requêtes inter-domaines, l'ingénierie front-end, les modèles de conception et les nouvelles technologies et tendances. Les questions de l'intervieweur sont conçues pour évaluer les compétences techniques du candidat, son expérience en matière de projet et sa compréhension des tendances du secteur. Par conséquent, les candidats doivent être parfaitement préparés dans ces domaines pour démontrer leurs capacités et leur expertise.

Django est-il front-end ou back-end ? Vérifiez-le! Django est-il front-end ou back-end ? Vérifiez-le! Jan 19, 2024 am 08:37 AM

Django est un framework d'application Web écrit en Python qui met l'accent sur un développement rapide et des méthodes propres. Bien que Django soit un framework Web, pour répondre à la question de savoir si Django est un front-end ou un back-end, vous devez avoir une compréhension approfondie des concepts de front-end et de back-end. Le front-end fait référence à l'interface avec laquelle les utilisateurs interagissent directement, et le back-end fait référence aux programmes côté serveur. Ils interagissent avec les données via le protocole HTTP. Lorsque le front-end et le back-end sont séparés, les programmes front-end et back-end peuvent être développés indépendamment pour mettre en œuvre respectivement la logique métier et les effets interactifs, ainsi que l'échange de données.

Explorer la technologie front-end du langage Go : une nouvelle vision du développement front-end Explorer la technologie front-end du langage Go : une nouvelle vision du développement front-end Mar 28, 2024 pm 01:06 PM

En tant que langage de programmation rapide et efficace, le langage Go est très populaire dans le domaine du développement back-end. Cependant, peu de gens associent le langage Go au développement front-end. En fait, l’utilisation du langage Go pour le développement front-end peut non seulement améliorer l’efficacité, mais également ouvrir de nouveaux horizons aux développeurs. Cet article explorera la possibilité d'utiliser le langage Go pour le développement front-end et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre ce domaine. Dans le développement front-end traditionnel, JavaScript, HTML et CSS sont souvent utilisés pour créer des interfaces utilisateur.

Apprenez le cadre de canevas et expliquez en détail le cadre de canevas couramment utilisé Apprenez le cadre de canevas et expliquez en détail le cadre de canevas couramment utilisé Jan 17, 2024 am 11:03 AM

Explorez le framework Canvas : Pour comprendre quels sont les frameworks Canvas couramment utilisés, des exemples de code spécifiques sont nécessaires. Introduction : Canvas est une API de dessin fournie en HTML5, grâce à laquelle nous pouvons obtenir des graphiques et des effets d'animation riches. Afin d'améliorer l'efficacité et la commodité du dessin, de nombreux développeurs ont développé différents frameworks Canvas. Cet article présentera certains frameworks Canvas couramment utilisés et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre comment utiliser ces frameworks. 1.Cadre EaselJSEa

Comment devenir membre du mini-programme WeChat Comment devenir membre du mini-programme WeChat May 07, 2024 am 10:24 AM

1. Ouvrez le mini programme WeChat et entrez dans la page du mini programme correspondante. 2. Recherchez l'entrée relative aux membres sur la page du mini-programme. Habituellement, l'entrée des membres se trouve dans la barre de navigation inférieure ou dans le centre personnel. 3. Cliquez sur le portail d'adhésion pour accéder à la page de demande d'adhésion. 4. Sur la page de demande d'adhésion, remplissez les informations pertinentes, telles que le numéro de téléphone portable, le nom, etc. Après avoir complété les informations, soumettez la demande. 5. Le mini-programme examinera la demande d'adhésion. Après avoir réussi l'examen, l'utilisateur pourra devenir membre du mini-programme WeChat. 6. En tant que membre, les utilisateurs bénéficieront de davantage de droits d'adhésion, tels que des points, des coupons, des activités exclusives aux membres, etc.

Django : Un framework magique capable de gérer à la fois le développement front-end et back-end ! Django : Un framework magique capable de gérer à la fois le développement front-end et back-end ! Jan 19, 2024 am 08:52 AM

Django : Un framework magique capable de gérer à la fois le développement front-end et back-end ! Django est un framework d'application Web efficace et évolutif. Il est capable de prendre en charge plusieurs modèles de développement Web, notamment MVC et MTV, et peut facilement développer des applications Web de haute qualité. Django prend non seulement en charge le développement back-end, mais peut également créer rapidement des interfaces frontales et obtenir un affichage de vue flexible via un langage de modèle. Django combine le développement front-end et le développement back-end dans une intégration transparente, afin que les développeurs n'aient pas à se spécialiser dans l'apprentissage.

Combinaison de Golang et de technologie front-end : découvrez comment Golang joue un rôle dans le domaine front-end Combinaison de Golang et de technologie front-end : découvrez comment Golang joue un rôle dans le domaine front-end Mar 19, 2024 pm 06:15 PM

Combinaison de Golang et de la technologie front-end : pour explorer le rôle de Golang dans le domaine front-end, des exemples de code spécifiques sont nécessaires. Avec le développement rapide d'Internet et des applications mobiles, la technologie front-end est devenue de plus en plus importante. Dans ce domaine, Golang, en tant que puissant langage de programmation back-end, peut également jouer un rôle important. Cet article explorera comment Golang est combiné avec la technologie front-end et démontrera son potentiel dans le domaine front-end à travers des exemples de code spécifiques. Le rôle de Golang dans le domaine front-end est celui d'un outil efficace, concis et facile à apprendre.

See all articles