美文网首页
canvas中图片的放大缩小和移动

canvas中图片的放大缩小和移动

作者: kopsht | 来源:发表于2020-12-14 14:32 被阅读0次

项目需求中需要图片的放大、缩小、移动,和实现一个放大缩小的缩略条。在这里记录一下实现的方法。
使用了 vue 和 konva

实现的效果大概是下图这样。 IMG_2089.GIF
 <v-stage ref="layerStage" :config="configKonva">
        <v-layer ref="layerEditor">
          <v-group
            :draggable="true"
            @dragend="bgImageDragEnd"
            @wheel="wheelForScale($event)"
            :config="{
              name: 'layerImage',
              x: bgx,
              y: bgy,
              scaleX: imageScale,
              scaleY: imageScale,
            }"
          >
            <v-image :config="layerImage"></v-image>
          </v-group>
        </v-layer>
      </v-stage>

method

bgImageDragEnd() {
      const layerImageNode = this.stage.find(".layerImage")[0];
      this.bgx = layerImageNode.getAttr("x");
      this.bgy = layerImageNode.getAttr("y");
    }

    // 放大缩小函数
    wheelForScale(e) {
   
        const stage = this.self.stage;
        const oldScale = this.self.imageScale;
        const scaleBy = 1.2;
        let pointer = stage.getPointerPosition();
        // let bar = this.self.$refs.slider.getStage().find('.sliderMoveBar')[0]
  
        var mousePointTo = {
          x: (pointer.x - this.self.bgx) / oldScale,
          y: (pointer.y - this.self.bgy) / oldScale,
        };
        if (e.evt.deltaY > 0 && oldScale * scaleBy > 8) {
          this.self.$noty("已放大到最大");
          return;
        }
        if (e.evt.deltaY < 0 && oldScale / scaleBy < 0.2) {
          this.self.$noty("已缩小到最小");
          return;
        }
        let newScale;
        if (e.evt.deltaY > 0) {
          newScale = oldScale * scaleBy;
        } else {
          newScale = oldScale / scaleBy;
        }
  
        this.self.bgx = pointer.x - mousePointTo.x * newScale;
        this.self.bgy = pointer.y - mousePointTo.y * newScale;
        this.self.imageScale = newScale;
        stage.batchDraw();
      }
    //   还原函数
      reduction() {
        this.self.bgx = 0;
        this.self.bgy = 0;
        this.self.imageScale = 1;
        this.self.hideMenu();
        this.self.$refs.scaleBox.changeScaleBar()
      }

滚动条

<template>
  <div class="scale-box">
    <Tooltip content="[ctrl] + 鼠标滚轮亦可进行缩放" placement="top">
      <div class="slidecontainer">
        <input
          type="range"
          min="0"
          max="200"
          :value="scaleBar"
          @input="sliderDgMove($event)"
          class="slider"
          id="myRange"
        />
      </div>
    </Tooltip>
    <span class="scale-text">{{ showScale }}% &nbsp;</span>
    <Tooltip content="还原" placement="top">
      <Icon class="reduction" @click="reduction" type="ios-expand" />
    </Tooltip>
  </div>
</template>

<script>
export default {
  props: ["imageScale"],
  name: "ScaleBox",
  data() {
    return {
      scaleBar:1
    };
  },
  computed: {
    showScale() {
      let showScale = 100;
      if (this.imageScale > 1) {
        showScale = Math.ceil((8 / (8 - this.imageScale)) * 100);
        showScale > 800 && (showScale = 800);
      }
      if (this.imageScale < 1) {
        showScale = Math.ceil(this.imageScale * 100);
      }
      return showScale;
    }
  },
  methods: {
    sliderDgMove(ev) {
      let val = ev.target.value;
      let upperLen = 100 / 11;
      let lowerLen = 100 / 8;
      let times = 1;
      if (val > 100) {
        times = (val - 100) / upperLen;
      } else if (val < 100) {
        times = (val - 100) / lowerLen;
      } else {
        times = 0;
      }
      let imageScale = Math.pow(1.2, times);
      this.$emit('changeImageScale', imageScale)
      this.changeScaleBar();
    },
    changeScaleBar() {
      let times = Math.round(Math.log(this.imageScale) / Math.log(1.2));
      let upperLen = 100 / 11;
      let lowerLen = 100 / 8;
      if (times >= 0) {
        this.scaleBar = 100 + upperLen * times;
      } else {
        this.scaleBar = 100 + lowerLen * times;
      }
    }
  },
  mounted() {
    this.changeScaleBar();
  },
};
</script>

<style lang="less" scoped>

.scaled-box {
  width: 200px;
  border-top: 2px solid #fff;
  margin: 0 10px;
  position: relative;
  -webkit-user-select: none;
}
.scale-bar {
  position: absolute;
  width: 2px;
  height: 12px;
  background-color: #fff;
  top: -6px;
  cursor: pointer;
}
.scale-text {
  -webkit-user-select: none;
}
.slidecontainer {
  width: 220px;
}

.slider {
  -webkit-appearance: none;
  width: 200px;
  height: 5px;
  background: #d3d3d3;
  outline: none;
  opacity: 0.7;
  -webkit-transition: 0.2s;
  transition: opacity 0.2s;
}

.slider:hover {
  opacity: 1;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 5px;
  height: 24px;
  background: #fff;
  cursor: pointer;
}
</style>

相关文章

  • canvas中图片的放大缩小和移动

    项目需求中需要图片的放大、缩小、移动,和实现一个放大缩小的缩略条。在这里记录一下实现的方法。使用了 vue 和 k...

  • canvas移动端实现画板批改功能

    说明: 最近有图片批改作业主观题的需求,所以研究了一下canvas实现了移动端功能:放大 缩小 批改 橡皮檫 清空...

  • 基础1

    ⒈文字:移动文字使用左最上方箭头 ⒉按住alt 切换放大镜放大缩小 ⒊Ctrl 0在图片放大缩小的情况下最快恢复到...

  • ios-CropImageView-图片和裁剪框都能放大缩小移动

    特点:图片能移动,放大缩小。裁剪框能移动,自由拉伸。移动过程中裁剪框不会超出图片的范围。不在裁剪框里面会有黑色透明...

  • 2017-07-10

    文字:移动文字使用左最上方箭头 按住alt 切换放大镜放大缩小 Ctrl 0在图片放大缩小的情况下最快恢复到在画布...

  • 用electron实现一个批量裁剪图片的工具

    图片批量裁剪的工具 功能: 批量选择图片 放大缩小图片 移动图片 裁剪图片 导出裁剪后的图片 请在Release[...

  • PS学习1

    2020.3.21 好习惯:背景图层复制一层 放大镜:单击放大图片,按住Alt同时单击缩小图片 抓手:移动画布查看...

  • javascript案例

    1 图片的放大和缩小效果演示 1 图片的放大和缩小效果演示原理说明:图片逐渐放大和逐渐缩小是指在一定时间内图片发生...

  • Swift Demo

    *1> 简单实现列表折叠效果 * 2. 图片的放大缩小,移动 * 3. 购买详情动画

  • CGAffineTransform

    问题:在做图片放大缩小的时候,因为需求是一张图片多次放大,缩小, 先用 放大:view.transform=CGA...

网友评论

      本文标题:canvas中图片的放大缩小和移动

      本文链接:https://www.haomeiwen.com/subject/ohyvgktx.html