#typescript #canvas #next.js
Вопрос:
Я использую холст для захвата обрезанного изображения. вот функция
export const getCroppedImg = ( image: HTMLImageElement, crop: Crop, fileName: string ): Promise<Blob> => { let canvas: HTMLCanvasElement; let ctx: CanvasRenderingContext2D; // I m using next.js if (typeof window !== "undefined") { if (crop) { canvas = document.createElement("canvas"); const scaleX = image.naturalWidth / image.width; const scaleY = image.naturalHeight / image.height; canvas.width =crop.width ? crop.width * scaleX : undefined; canvas.height =crop.height amp;amp; crop.height * scaleY; ctx = canvas.getContext("2d") as CanvasRenderingContext2D; ctx.drawImage( image, crop.x * scaleX, crop.y * scaleY, crop.width * scaleX, crop.height * scaleY, 0, 0, crop.width * scaleX, crop.height * scaleY ); } }
crop.x, crop.y, crop.width crop.height
вызывает ошибку ts «Объект, возможно, «не определен»». Я обернул всю логику if(crop)
, я попробовал два разных подхода
canvas.width =crop.width ? crop.width * scaleX : undefined; canvas.height =crop.height amp;amp; crop.height * scaleY;
«холст.ширина» и «холст.высота» предупреждают, что
"Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.ts(2322)
Вот урожай:
import { Crop } from "react-image-crop"; interface Crop { aspect?: number; x?: number; y?: number; width?: number; height?: number; unit?: 'px' | '%'; }
Ответ №1:
Извлеките существующие crop.width
и crop.height
в их собственные переменные, прежде чем проверять их.
Вы также не можете назначить undefined
значение a canvas.width
или использовать amp;amp;
для условного присвоения значения высоте — используйте if
вместо этого.
Не похоже, что следовать какой-либо логике имеет смысл, если какие-либо crop
свойства не определены (вы не сможете правильно нарисовать холст или использовать drawImage
его), поэтому в таких случаях выдайте ошибку или вернитесь раньше.
Вы также не возвращаете обещание, поэтому удалите Promise<Blob>
тип.
export const getCroppedImg = ( image: HTMLImageElement, crop: Crop, ) => { const { width, height, x, y } = crop; if (typeof window === "undefined" || !width || !height || !x || !y) { // Proceeding further would make no sense; // can't adjust canvas, or draw the image // return here, or throw an error or something throw new Error('Bad argument'); } const canvas = document.createElement("canvas"); const scaleX = image.naturalWidth / image.width; const scaleY = image.naturalHeight / image.height; canvas.width = width * scaleX; canvas.height = height * scaleY; const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; ctx.drawImage( image, x * scaleX, y * scaleY, width * scaleX, height * scaleY, 0, 0, width * scaleX, height * scaleY ); }
Комментарии:
1. это сработало. Спасибо. еще одна головная боль прошла
Ответ №2:
В этой строке вы говорите, что canvas.width может быть неопределенной:
canvas.width =crop.width ? crop.width * scaleX : undefined;
таким образом, вы можете переработать логику, чтобы это было не так. Тем не менее, иногда вы будете знать больше, чем компилятор TypeScript, поэтому, если вы знаете, что значение никогда не будет неопределенным, когда вам нужно получить к нему доступ, вы можете утверждать значение.
canvas.width as number
Ответ №3:
Почему вы используете дополнительные поля в интерфейсе обрезки?
Вы пробовали это сделать?:
interface Crop { aspect: number; x: number; y: number; width: number; height: number; unit: 'px' | '%'; }
Комментарии:
1. Я этого не делал, я импортировал это из упаковки. я должен был упомянуть, что