精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

在瀏覽器里裁剪圖片:純?cè)⒘阋蕾嚨?JavaScript 小妙招

開發(fā) 前端 瀏覽器
?今天帶你用瀏覽器原生能力實(shí)現(xiàn)圖片裁剪:不裝庫、不走服務(wù)端、即時(shí)預(yù)覽、即可下載。

先用一個(gè)極簡 demo 走一遍流程。

你將做出什么

  • 從用戶設(shè)備本地上傳圖片
  • 在 <canvas> 中實(shí)時(shí)展示與裁剪
  • 拖拽框調(diào)整裁剪區(qū)域
  • 即時(shí)預(yù)覽裁剪結(jié)果
  • 一鍵生成并下載裁剪后的圖片,無需服務(wù)器

Demo(原生 HTML/CSS/JS)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
      .container {
        max-width: 600px;
        margin: 20px auto;
        text-align: center;
        font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
      }
      .image-wrapper {
        position: relative;
        display: inline-block;
      }
      .crop-frame {
        display: none;
        position: absolute;
        border: 3px dashed #28a745; /* 視覺反饋更明顯 */
        box-sizing: border-box;
        cursor: move;
      }
      .resize-handle {
        position: absolute;
        width: 12px;
        height: 12px;
        background: #28a745;
        cursor: nwse-resize;
      }
      .preview-area {
        margin-top: 20px;
      }
      button {
        padding: 10px20px;
        background: #28a745;
        color: #fff;
        border: none;
        cursor: pointer;
        border-radius: 6px;
      }
      button:disabled {
        opacity: .6;
        cursor: not-allowed;
      }
    </style>
</head>
<body>
    <div class="container">
      <input type="file" id="imageInput" accept="image/*" />
      <div class="image-wrapper">
        <canvas id="mainCanvas"></canvas>
        <div class="crop-frame" id="cropFrame"></div>
      </div>
      <button id="cropButton" disabled>Crop & Download</button>
      <div class="preview-area">
        <canvas id="previewCanvas"></canvas>
      </div>
    </div>

    <script>
      const imageInput = document.getElementById("imageInput");
      const mainCanvas = document.getElementById("mainCanvas");
      const ctx = mainCanvas.getContext("2d");
      const cropFrame = document.getElementById("cropFrame");
      const previewCanvas = document.getElementById("previewCanvas");
      const previewCtx = previewCanvas.getContext("2d");
      const cropButton = document.getElementById("cropButton");

      let image = new Image();
      let cropData = { x: 100, y: 100, width: 150, height: 150 };
      let isDragging = false;

      // 初始尺寸設(shè)為 0(數(shù)值),避免拉伸
      mainCanvas.width = 0;
      mainCanvas.height = 0;

      imageInput.addEventListener("change", (e) => {
        const file = e.target.files && e.target.files[0];
        if (!file) return;

        image.src = URL.createObjectURL(file);
        image.onload = () => {
          // 固定畫布演示尺寸(也可按比例自適應(yīng))
          mainCanvas.width = 600;
          mainCanvas.height = 450;

          // 繪制整圖到畫布
          ctx.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
          ctx.drawImage(image, 0, 0, mainCanvas.width, mainCanvas.height);

          // 啟用裁剪
          updateCropFrame();
          cropButton.disabled = false;
        };
      });

      function updateCropFrame() {
        cropFrame.style.display = "block";
        cropFrame.style.left = `${cropData.x}px`;
        cropFrame.style.top = `${cropData.y}px`;
        cropFrame.style.width = `${cropData.width}px`;
        cropFrame.style.height = `${cropData.height}px`;
        cropFrame.innerHTML =
          '<div class="resize-handle" style="bottom: -6px; right: -6px;"></div>';
      }

      cropFrame.addEventListener("mousedown", (e) => {
        isDragging = true;
        if (e.target.classList.contains("resize-handle")) {
          cropFrame.dataset.mode = "resize";
        } else {
          cropFrame.dataset.mode = "move";
        }
      });

      document.addEventListener("mousemove", (e) => {
        if (!isDragging) return;
        const rect = mainCanvas.getBoundingClientRect();
        const mouseX = e.clientX - rect.left;
        const mouseY = e.clientY - rect.top;

        if (cropFrame.dataset.mode === "move") {
          cropData.x = Math.max(
            0,
            Math.min(
              mouseX - cropData.width / 2,
              mainCanvas.width - cropData.width
            )
          );
          cropData.y = Math.max(
            0,
            Math.min(
              mouseY - cropData.height / 2,
              mainCanvas.height - cropData.height
            )
          );
        } elseif (cropFrame.dataset.mode === "resize") {
          cropData.width = Math.max(50, mouseX - cropData.x);
          cropData.height = Math.max(50, mouseY - cropData.y);
          // 限制在畫布范圍內(nèi)
          cropData.width = Math.min(cropData.width, mainCanvas.width - cropData.x);
          cropData.height = Math.min(cropData.height, mainCanvas.height - cropData.y);
        }

        updateCropFrame();
      });

      document.addEventListener("mouseup", () => {
        isDragging = false;
        cropFrame.dataset.mode = "";
      });

      cropButton.addEventListener("click", () => {
        if (!image.width) return;

        previewCanvas.width = cropData.width;
        previewCanvas.height = cropData.height;

        // 將畫布坐標(biāo)映射回原圖坐標(biāo)
        const scaleX = image.width / mainCanvas.width;
        const scaleY = image.height / mainCanvas.height;

        previewCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);
        previewCtx.drawImage(
          image,
          cropData.x * scaleX,
          cropData.y * scaleY,
          cropData.width * scaleX,
          cropData.height * scaleY,
          0,
          0,
          cropData.width,
          cropData.height
        );

        const link = document.createElement("a");
        link.download = "cropped-image.png";
        link.href = previewCanvas.toDataURL("image/png");
        link.click();
      });
    </script>
</body>
</html>

原理一眼看懂

  • 用一個(gè) <canvas> 承擔(dān)圖片渲染,輕量且原生
  • 用戶選擇本地圖片,加載到固定尺寸的畫布里;拖動(dòng)裁剪框或其縮放手柄,實(shí)時(shí)改變裁剪區(qū)域。
  • 綠框與手柄提供直觀的視覺反饋;布局簡單,移動(dòng)端/桌面端都能順利操作。
  • 點(diǎn)擊按鈕后,按比例把畫布坐標(biāo)映射到原圖像素,把裁剪結(jié)果繪到預(yù)覽畫布,并生成 Data URL 觸發(fā)下載——全程不觸服務(wù)器

重點(diǎn)回顧

  • 純 HTML/CSS/JS 即可完成:上傳 → 裁剪 → 預(yù)覽 → 下載
  • canvas.drawImage() + 比例換算是關(guān)鍵
  • 交互只需拖動(dòng)移動(dòng)單點(diǎn)縮放兩種模式,邏輯清晰、易擴(kuò)展

把它塞進(jìn)你的下一個(gè)小項(xiàng)目里試試吧。

責(zé)任編輯:姜華 來源: 大遷世界
相關(guān)推薦

2025-09-09 10:00:00

前端瀏覽器API

2015-01-21 15:45:50

斯巴達(dá)瀏覽器

2017-01-05 09:07:25

JavaScript瀏覽器驅(qū)動(dòng)

2016-10-09 08:38:01

JavaScript瀏覽器事件

2013-11-15 13:22:22

瀏覽器JavaScript

2011-01-05 09:52:30

微軟谷歌零日漏洞

2020-03-12 11:29:51

JavaScript瀏覽器語言

2012-03-30 14:52:03

瀏覽器大戰(zhàn)

2011-08-02 14:23:09

iPhone UIScrollVi 圖片

2010-09-15 09:12:03

JavaScript瀏覽器兼容

2020-12-15 11:05:21

JavascriptChrome瀏覽器

2010-04-05 21:57:14

Netscape瀏覽器

2013-08-22 10:09:00

2023-08-29 08:28:43

React并發(fā)更新

2024-02-02 12:52:34

瀏覽器時(shí)間切片線程

2012-11-06 11:37:26

傲游瀏覽器

2014-05-16 11:18:14

瀏覽器ChromeFirefox

2017-12-04 09:39:41

瀏覽器Chrome小技巧

2017-03-03 16:50:01

2012-03-20 11:07:08

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

岛国av在线网站| 精品久久无码中文字幕| 日韩成人免费| 欧美一二三在线| 久草青青在线观看| 黄色在线免费网站| 2024国产精品| 91免费看国产| 黑人精品无码一区二区三区AV| 成人影视亚洲图片在线| 欧美va在线播放| jizz欧美激情18| 日本乱理伦在线| 国产欧美日本一区二区三区| 国产精品9999久久久久仙踪林| 欧美亚洲另类小说| 红桃视频国产精品| 日韩亚洲在线观看| 日韩中文字幕电影| 韩国精品福利一区二区三区| 亚洲一级电影| 最好看的2019的中文字幕视频| 亚洲图片欧美另类| 日韩毛片免费看| 在线这里只有精品| 日韩精品―中文字幕| 18加网站在线| 国产精品久久久久毛片软件| 久久久久久久久一区| 国产农村妇女毛片精品| 日韩黄色小视频| 欧美专区福利在线| 日产精品久久久久| 午夜日韩激情| 久久久国产一区| 影音先锋男人在线| 亚洲小说图片| 亚洲精品久久久久中文字幕欢迎你| 国产在线视频三区| 欧美a一级片| 欧美性大战xxxxx久久久| 国产97在线 | 亚洲| 999福利在线视频| 亚洲影院在线观看| 菠萝蜜视频在线观看入口| 黄网页在线观看| 亚洲三级在线免费观看| 一区二区在线观看网站| 自拍视频在线播放| 亚洲国产精品t66y| 亚洲国产欧洲综合997久久 | 日韩精品第一页| 免费在线高清av| 久久精品亚洲精品国产欧美kt∨| 久久天天狠狠| 免费在线观看一级毛片| 久久免费国产精品| 日韩精品久久久毛片一区二区| 四虎影院在线播放| 久久嫩草精品久久久久| 欧美不卡1区2区3区| 国产在线资源| 国产精品久久久爽爽爽麻豆色哟哟| 亚洲精品中文综合第一页| av网站无病毒在线| 亚洲丝袜美腿综合| 免费视频爱爱太爽了| 538视频在线| 欧美三级免费观看| 青青青在线视频免费观看| 免费视频观看成人| 欧美一区二区三区白人| 久久久无码人妻精品无码| 极品束缚调教一区二区网站| 日韩精品免费在线| 中文字幕伦理片| 亚洲天堂免费| 国内成人精品视频| 秋霞av一区二区三区| 老司机一区二区| 操一操视频一区| 日中文字幕在线| 国产精品福利av| 妞干网视频在线观看| 在线高清av| 欧美喷潮久久久xxxxx| 色姑娘综合天天| 日韩电影不卡一区| 日韩在线一区二区三区免费视频| 九九视频在线观看| 久久资源在线| av成人综合网| 国产精品一区二区三区四区色 | 欧美精品二区三区| 久久精品国产一区二区三| 国产精品午夜av在线| 成人午夜电影在线观看| 一区二区三区自拍| 免费在线观看的毛片| 日韩一区二区三区色| 亚洲美女在线视频| 日本a级片视频| 日韩精品亚洲专区| 99在线看视频| 免费黄网站在线| 欧美日韩国产一区二区三区| 91看片破解版| 国产探花一区| 性欧美xxxx视频在线观看| 亚洲最大成人av| 91片在线免费观看| 黄色一级大片免费| 国产欧美自拍| 亚洲精品一区av在线播放| 青草影院在线观看| 蜜桃视频一区二区| 美媛馆国产精品一区二区| 欧美日韩精品综合| 和岳每晚弄的高潮嗷嗷叫视频| 国产一二在线播放| 欧美巨大另类极品videosbest | 国产精品av免费观看| 成人香蕉视频| 亚洲国产成人av在线| 成人自拍小视频| 免费成人av在线播放| 欧美裸体网站| 狼人综合视频| 亚洲精品720p| 国产对白videos麻豆高潮| 国产美女视频一区| 亚洲在线色站| 97成人超碰| 伊人一区二区三区久久精品 | 麻豆影视在线观看_| 日本韩国视频一区二区| 日本一区二区在线免费观看| 欧美日韩国产成人精品| 91天堂在线视频| 国产最新在线| 欧美一区国产二区| www深夜成人a√在线| 理论片日本一区| 一道精品一区二区三区| 成人精品国产| 综合欧美国产视频二区| 怡春院在线视频| 国产精品传媒入口麻豆| 亚洲高清视频免费| 91精品99| yellow视频在线观看一区二区 | 深夜视频在线免费| 欧美午夜片欧美片在线观看| 免费看污黄网站在线观看| 国产日韩精品视频一区二区三区 | 国产精品99一区二区三区| 国产精品永久免费观看| 国产在线一二三| 欧美三级日韩三级| 亚洲区一区二区三| 国产一区二区91| 久久亚洲精品无码va白人极品| 福利电影一区| 欧美中文在线观看国产| 国产有码在线| 69av一区二区三区| 久久亚洲AV无码| 久久一区二区三区电影| 国产精品爽爽爽爽爽爽在线观看| 1区2区3区在线观看| 欧美男生操女生| 国产一级理论片| wwww国产精品欧美| www.com黄色片| 你懂的国产精品| 精品亚洲一区二区三区四区五区高| 三级中文字幕在线观看| 国产亚洲欧美日韩精品| 一级特黄aaaaaa大片| 亚洲黄色尤物视频| 免费成人深夜夜行p站| 欧美丰满日韩| 99久久伊人精品影院| 老色鬼在线视频| 中文欧美在线视频| 99久久亚洲精品日本无码| 亚洲一二三区在线观看| 一本加勒比北条麻妃| 另类的小说在线视频另类成人小视频在线 | 国产精品视频a| 午夜精品福利久久久| 日本理论中文字幕| 国产精品影视在线| 亚洲中文字幕无码不卡电影| 一区二区三区在线电影| 欧美大陆一区二区| 国产精品一区二区精品| 57pao成人永久免费视频| 婷婷在线视频观看| 日韩成人av在线播放| 国产日韩免费视频| 色婷婷精品久久二区二区蜜臀av| 中日韩一级黄色片| 91麻豆免费看| 好吊操视频这里只有精品| 日韩中文字幕亚洲一区二区va在线 | 麻豆国产在线播放| 日韩亚洲国产中文字幕欧美| 你懂的国产在线| 亚洲男女一区二区三区| 性欧美精品中出| 成人美女视频在线观看18| 一本岛在线视频| 午夜影院日韩| 国产xxxx振车| 亚洲h色精品| 日韩精品不卡| 蜜臀91精品国产高清在线观看| 91在线观看欧美日韩| japanese23hdxxxx日韩| 国内精品美女av在线播放| 操你啦视频在线| 中文字幕久热精品在线视频| 日产精品久久久久久久性色| 精品久久久久久综合日本欧美 | 亚洲国产欧美在线成人app| 国产又粗又猛又爽又黄的视频一 | 国产又粗又猛又爽又黄视频| 一本在线高清不卡dvd| 国产亚洲精品码| 亚洲免费观看高清完整版在线观看| 欧美一区二区三区粗大| 久久这里只有精品首页| 先锋资源av在线| av一区二区三区在线| 最新日本中文字幕| 粉嫩一区二区三区性色av| 国产不卡的av| 国产麻豆视频一区二区| 欧美成人三级在线播放| 日韩精品视频网| 国产视频一区二区视频| 亚洲一区日本| 国产成人无码一二三区视频| 中文亚洲欧美| 日韩人妻精品无码一区二区三区| 一本久久知道综合久久| 国产中文字幕二区| 亚洲精品韩国| 国产在线青青草| 久久精品人人做人人爽电影蜜月| 国产成人精品视频免费看| 国产亚洲亚洲| 国产精品亚洲a| 日本成人在线不卡视频| 国产三区在线视频| 日韩成人dvd| 亚洲怡红院在线| 国产精品一区二区免费不卡| 好吊操视频这里只有精品| 不卡影院免费观看| 3d动漫精品啪啪一区二区下载| 国产视频不卡一区| 99re6热在线精品视频| 亚洲欧洲精品一区二区三区不卡| 91 在线视频| 亚洲一区免费在线观看| 日韩av在线播| 欧美性三三影院| 99热这里只有精品在线观看| 精品国产乱码久久| 三级在线观看| 日韩在线视频免费观看| 欧美xxxx黑人又粗又长| 国产91精品青草社区| 欧美日韩尤物久久| 亚洲在线www| 中文字幕av一区二区三区人| 亚洲精品欧美精品| 欧美+日本+国产+在线a∨观看| 日韩网站在线免费观看| 日日嗨av一区二区三区四区| 久久精品国产99久久99久久久| 成人性生交大片免费看中文| 欧美图片第一页| 亚洲人成影院在线观看| 日韩少妇高潮抽搐| 欧美视频三区在线播放| www.xxx国产| 亚洲美女性视频| 99热国产在线| 国产不卡av在线免费观看| 91久久青草| 久久综合毛片| 欧美激情四色| 手机在线免费观看毛片| 国产盗摄女厕一区二区三区| 真实乱视频国产免费观看| 亚洲女同女同女同女同女同69| www日韩精品| 欧美一区二区三区在线观看视频| 亚洲欧美日本在线观看| 久久精品久久久久久| 樱花草涩涩www在线播放| 亚洲一区二区自拍| 国产成人手机高清在线观看网站| 台湾无码一区二区| 奇米精品一区二区三区在线观看| 亚洲av无码专区在线播放中文| 国产精品国产三级国产普通话蜜臀 | 91国产福利在线| 色窝窝无码一区二区三区成人网站| 最近2019中文免费高清视频观看www99 | 国产精品高潮呻吟视频| 成人性生交大片免费看中文视频 | 国产欧美一区二区在线播放| 99精品视频在线| 国产性生交xxxxx免费| 成人av电影在线网| 婷婷在线精品视频| 欧美日韩一二三区| 精品久久av| 97超视频免费观看| 国偷自产av一区二区三区| 91麻豆天美传媒在线| 免费日本视频一区| 97超碰在线免费观看| 黑人巨大精品欧美一区二区| 懂色av一区二区三区四区| 久久综合五月天| av在线精品| 一区二区视频国产| 麻豆一区二区三| 免费看91的网站| 色哟哟一区二区| 亚洲av毛片成人精品| 91黄色8090| 啪啪激情综合网| 欧美色图色综合| 91啪九色porn原创视频在线观看| 久久久精品人妻一区二区三区四 | 中国av免费看| 午夜精品视频在线观看| 亚洲精品综合久久| 欧美精品第一页在线播放| 亚洲乱码一区| 精品无码国产一区二区三区av| 成人ar影院免费观看视频| 久久一级黄色片| 亚洲国产精品美女| 无遮挡爽大片在线观看视频| 久久综合九九| 日韩影院在线观看| 一级黄色片网址| 欧美剧在线免费观看网站| 九义人在线观看完整免费版电视剧| 国产有码在线一区二区视频| 午夜国产一区二区| 久久黄色一级视频| 亚洲国产美女搞黄色| 色哟哟中文字幕| 欧美自拍大量在线观看| 国产伦精品一区二区三区千人斩| 88av.com| 亚洲欧美日韩电影| 国产极品久久久| 91po在线观看91精品国产性色| 蜜桃a∨噜噜一区二区三区| 免费涩涩18网站入口| 日韩美女久久久| 欧性猛交ⅹxxx乱大交| 人体精品一二三区| 久久激情电影| 色欲无码人妻久久精品| 午夜精品一区二区三区电影天堂| 久久久久久久久亚洲精品| 国产精品嫩草影院久久久| 欧美freesex交免费视频| 国产 中文 字幕 日韩 在线| 欧美性高清videossexo| 羞羞视频在线观看免费| 久久精品一二三区| 老司机午夜精品99久久| 久久一二三四区| 在线国产精品视频| 999国产精品一区| 天美星空大象mv在线观看视频| 亚洲人成网站色在线观看| 香蕉久久国产av一区二区| 国产精品美女久久| 欧美日韩视频| 国产视频三区四区| 欧美成人精精品一区二区频| 国产v综合v| 999一区二区三区| 国产精品三级视频| 天堂在线资源8| 亚洲www在线| 日本sm残虐另类| 99热国产在线观看|