Vue реализует обрезку картинок и загрузку на сервер

внешний интерфейс Vue.js Canvas

визуализация

ссылка для предварительного просмотраНажмите, чтобы просмотреть

cropper

нужно

  • [x] Предварительный просмотр: адаптивное заполнение левой области обрезки в соответствии с выбранным размером изображения
  • [x] Обрезка: переместите область предварительного просмотра в правую часть поля обрезки для предварительного просмотра в реальном времени.
  • [x] Загрузить и очистить: нажмите «ОК», чтобы загрузить обрезанное изображение, нажмите «Отмена», чтобы очистить изображение.
  • [ ] Рамка кадрирования с изменяемым размером

Этапы реализации

method:funName() - соответствует методу funName в методах в исходном коде.

Данные: DATANAME - данные DATANAME, соответствующие данным в исходном коде

Выбор и чтение

  • Выберите изображение:(методы: selectPic) использоватьinput[type="file"]Появится всплывающее окно с изображением выбора, и js активно инициирует событие щелчка;
  • читать изображение: (методы: readImage) Чтобы создать объект изображения, используйтеcreateObjectURLотображать изображение.objectURL = URL.createObjectURL(blob);

2. Отображение изображений на холсте

Знания, связанные с холстом, которые необходимо освоить:

  1. пустой холстctx.clearRect(x,y,width,height);
  2. заполненный прямоугольникctx.fillRect(x,y,width,height);
  3. нарисовать дугуctx.arc(x,y,r,startAngle,endAngle,counterclockwise); нарисовать прямоугольникctx.rect(x,y,width,height);
  4. нарисовать изображениеdrawImage
    drawImage
        # 语法
        ctx.drawImage(image, dx, dy);
        ctx.drawImage(image, dx, dy, dWidth, dHeight);
        ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
        # 参数
        image                # 绘制的元素(可以为HTMLImageElement,HTMLVideoElement,或者 HTMLCanvasElement。)
        dx,dy                # 目标画布(destination canvas)左上角的坐标
        dWidth,dHeight       # 目标画布(destination canvas)上绘制图像宽高
        sx,sy                # 源画布(source canvase)左上角的坐标
        sWidth,sHeight       # 源画布(source canvase)选择的图像宽高
    
  5. Портнойctx.clip();

Конкретные шаги:

  • Рассчитать ширину и высоту холста:(методы:calcCropperSize) По размеру изображения рассчитать ширину и высоту холста (данные:cropperCanvasSize), чтобы изображение можно было адаптивно отображать в области кадрирования, и определить положение левого верхнего угла кадрирования (данные: расположение обрезки).
  • Нарисуйте изображение левой области обрезки:(методы: renderCropperImg)

Данные vue схемы области отсечения:

vue data

  • Нарисуйте изображение для предварительного просмотра вправо:(методы:renderPreviewImg)

3. Переместите поле обрезки

Точка знаний: onmousedown, onmousemove, onmouseup

Реализация:

methods:drag()

Запишите координаты мыши, и движение мыши вычислит положение центра круга в соответствии со смещением.

      canvas.onmousedown = e => {
        let [lastX, lastY] = [e.offsetX, e.offsetY];
        self.movement = true;
        canvas.onmousemove = e => {
          self.circleCenter = {
            X:
              self.cropperCanvasSize.width > 2 * self.slectRadius
                ? self.circleCenter.X + (e.offsetX - lastX)
                : self.cropperCanvasSize.width / 2,
            Y:
              self.cropperCanvasSize.height > 2 * self.slectRadius
                ? self.circleCenter.Y + (e.offsetY - lastY)
                : self.cropperCanvasSize.height / 2
          };
          self.renderCropperImg();
          [lastX, lastY] = [e.offsetX, e.offsetY];
        };
        canvas.onmouseup = e => {
          self.movement = false;
          canvas.onmousemove = null;
          canvas.onmouseup = null;
        };
      };

4. Загрузите изображение на сервер

Точка знаний:

Реализация:

methods:upload()

      this.$refs.preview.toBlob((blob)=> {
        const url = URL.createObjectURL(blob);
        const formData = new FormData();
        formData.append(this.uploadProps.name, blob, `${Date.now()}.png`);
        if(this.data){
            Object.keys(this.uploadProps.data).forEach(key => {
                formData.append(key, this.uploadProps.data[key]);
            });
        }
        const request = new XMLHttpRequest();
        request.open("POST", this.uploadProps.action, true);
        request.send(formData);

        request.onreadystatechange = () => {
          if (request.readyState === 4 && request.status === 200) {
                // ...
          }
        };
      });

адрес исходного кода Оригинальная ссылка