Визуализация рамки в элементе canvas - PullRequest
0 голосов
/ 23 октября 2019

Я работаю над созданием по индивидуальному заказу веб-сайта, и мне нужно показать пример рамки на экране, пока клиент вводит свои размеры. Я сделал большую часть этого, с текущей проблемой, как обрезать угол изображения. Я использую HTML-элемент Canvas.

Ввод размеров и отображение кадра будет происходить в компоненте Vue JS.

Используемое изображение является прямой частью кадра.

До сих пор мне удавалось заставить кадр повторяться по всему холсту при правильном соотношении сторон относительно размеров. Способ, которым я достиг, это начать с верхней стороны, повторить изображение поперек, затем повернуть холст на 90 градусов, повторить изображение вниз по правой стороне, снова повернуть на 90 градусов, повторить изображение вдоль дна, снова повернуть холсти повторите изображение вниз по левой стороне.

После того, как компонент «смонтирован»:

mounted() {
    let self = this

    window.addEventListener('load', function (e) {            
      self.canvas = document.getElementById('selected-frame')
      self.ctx = self.canvas.getContext('2d')

      self.setDims()            
    })
}
setDims: function() {
    let ratio = this.calculateAspectRatioFit(
        this.frameWidth,
        this.frameHeight,
        800,
        500
    )

    this.canvas.width = ratio.width
    this.canvas.height = ratio.height

    this.ctx.fillStyle = 'green'
    this.ctx.fillRect(0, 0, ratio.width, ratio.height)

    let pixelsPerMm = this.canvas.width / this.frameWidth

    let img = document.getElementById("moulding-6210PT")

    let mouldingImgRatio = this.calculateAspectRatioFit(
        img.width,
        img.height,
        800,
        this.mouldingWidth * pixelsPerMm
    )

    let runningLength = 0
    let i = 0

    // Top
    for (i; runningLength < this.canvas.width; i++) {
        runningLength = runningLength + mouldingImgRatio.width

        this.ctx.drawImage(img, mouldingImgRatio.width * i, 0, mouldingImgRatio.width, mouldingImgRatio.height)
    }

    // Right
    this.ctx.rotate((Math.PI/180) * 90) // Rotate 90 degrees
    runningLength = 0
    i = 0
    for (i; runningLength < this.canvas.height; i++) {
        runningLength = runningLength + mouldingImgRatio.width

        this.ctx.drawImage(img, mouldingImgRatio.width * i, -ratio.width, mouldingImgRatio.width, mouldingImgRatio.height)
    }

    // Bottom
    this.ctx.rotate((Math.PI/180) * 90) // Rotate another 90 degrees
    runningLength = 0
    i = 0
    for (i; runningLength < this.canvas.width; i++) {
        runningLength = runningLength + mouldingImgRatio.width

        this.ctx.drawImage(img, -ratio.width + (mouldingImgRatio.width * i), -ratio.height, mouldingImgRatio.width, mouldingImgRatio.height)
    }

    // Left
    this.ctx.rotate((Math.PI/180) * 90) // Rotate another 90 degrees
    runningLength = 0
    i = 0
    for (i; runningLength < this.canvas.height; i++) {
        runningLength = runningLength + mouldingImgRatio.width

        this.ctx.drawImage(img, -ratio.height + (mouldingImgRatio.width * i), 0, mouldingImgRatio.width, mouldingImgRatio.height)
    }
}

Метод расчета соотношения сторон (взято из https://stackoverflow.com/a/14731922/1520367):

calculateAspectRatioFit: function(srcWidth, srcHeight, maxWidth, maxHeight) {
    var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
    return { width: srcWidth*ratio, height: srcHeight*ratio };
},

Мне нужен способ изменить изображение части рамки, чтобы углы выглядели так, как будто они были обрезаны и соединены под прямым углом. Любые предложения действительно будут оценены.

Вот то, чего я достиг на данный момент:

enter image description here

Вот чего я хочу достичь:

enter image description here

Вот изображение части рамки, которую я использую: enter image description here

1 Ответ

0 голосов
/ 23 октября 2019

Похоже, вам придется использовать SVG clipPath: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath

Это позволит вам указать точные точки для обрезки, довольно похоже на то, что вы уже выкладываетеваши изображения.

Первоначально я писал, что вы можете использовать PNG с предварительно вырезанными углами, но затем прочитайте ваш вопрос еще раз и понял, что вы повторяете изображения. Если вы можете получить изображение кадра с достаточно высоким разрешением, вы должны иметь возможность заполнить его на всю ширину, не повторяя его. Тогда вы можете использовать PNG и вообще не использовать SVG clipPath.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...