如何实现用户可调整图片大小的功能?附项目代码
Hey there! Let's get that zoom feature working for your draggable images. I'll walk you through adding both zoom in/out controls that play nicely with your existing drag, flip, and z-index features.
Step 1: Add Zoom Buttons to Your UI
First, drop these buttons into your existing #buttons container so users can adjust image size:
<div id="buttons"> <!-- Your existing buttons (up, down, flip, del, clear) --> <div class="button" id="zoomIn">Zoom In</div> <div class="button" id="zoomOut">Zoom Out</div> </div>
Step 2: Tweak CSS for Natural Scaling
Add this to your CSS to ensure images scale from their center (instead of the top-left corner):
.draggable { position: absolute; /* Required for proper scaling positioning */ transform-origin: center center; /* Keep your existing draggable styles here */ }
Step 3: Update JavaScript with Zoom Logic
We'll track each image's current scale using jQuery's data() method, and combine scaling with your existing flip transform so both effects work together. Here's the full updated JS code:
$(function() { $(".draggable").draggable(); }); var selectedLayer; var highestIndex = 0; // Configure zoom settings const DEFAULT_SCALE = 1; const SCALE_STEP = 0.1; // Adjust how much each click zooms const MIN_SCALE = 0.3; // Prevent images from getting too tiny function updateHighestIndex() { $(".draggable").each(function() { if (parseInt($(this).css("z-index")) > highestIndex) { highestIndex = parseInt($(this).css("z-index")) } }) } $("#images").on("mousedown", ".draggable", function() { $(selectedLayer).css("background", ""); selectedLayer = this; $("#index").html(parseInt($(selectedLayer).css("z-index"))) $(selectedLayer).css({"background": "rgba(255,255,255,0.5)", "padding": "10px"}) // Initialize scale data if the image doesn't have it yet if (!$(selectedLayer).data('scale')) { $(selectedLayer).data('scale', DEFAULT_SCALE); } }) $(".icon").click(function() { updateHighestIndex() $('#images').append($('<img>', { class: 'draggable', src: this.src }).css("z-index", highestIndex + 1).data('scale', DEFAULT_SCALE)); // Set initial scale for new images $(".draggable").draggable(); }) $("#background").click(function() { $(selectedLayer).css("background", "") selectedLayer = undefined; $("#index").html("") }) function myFunction() { $("#demo").html(document.lastModified) } function inventory(category) { var state = $("#" + category).css("display") $(".tabcontent").css("display", "none"); $(".tablinks").removeClass("active"); if (state !== "block") { $("#" + category).css("display", "block") $(event.currentTarget).addClass("active"); } } $("#up").click(function() { updateHighestIndex() if (parseInt($(selectedLayer).css("z-index")) < highestIndex) { var x = parseInt($(selectedLayer).css("z-index")) + 1; $(".draggable").each(function() { if ($(this).css("z-index") == x) { $(this).css("z-index", x - 1) } }); $(selectedLayer).css('z-index', x); $("#index").html(x) } }) $("#down").click(function() { var x = parseInt($(selectedLayer).css("z-index")); if (x > 1) { x = parseInt($(selectedLayer).css("z-index")) - 1; $(".draggable").each(function() { if ($(this).css("z-index") == x) { $(this).css("z-index", x + 1) } }); $(selectedLayer).css('z-index', x); $("#index").html(x); } }) $("#flip").click(function() { if (!selectedLayer) return; const currentScale = $(selectedLayer).data('scale') || DEFAULT_SCALE; if ($(selectedLayer).css("transform") == "matrix(1, 0, 0, 1, 0, 0)") { // Combine flip with current scale $(selectedLayer).css("transform", `scaleX(-1) scale(${currentScale})`); } else { // Reset flip while preserving scale $(selectedLayer).css("transform", `scaleX(1) scale(${currentScale})`); } }) // Zoom In Handler $("#zoomIn").click(function() { if (!selectedLayer) return; let currentScale = $(selectedLayer).data('scale') || DEFAULT_SCALE; currentScale += SCALE_STEP; $(selectedLayer).data('scale', currentScale); // Apply combined transform if image is flipped const isFlipped = $(selectedLayer).css("transform").includes("scaleX(-1)"); $(selectedLayer).css("transform", isFlipped ? `scaleX(-1) scale(${currentScale})` : `scale(${currentScale})`); }) // Zoom Out Handler $("#zoomOut").click(function() { if (!selectedLayer) return; let currentScale = $(selectedLayer).data('scale') || DEFAULT_SCALE; if (currentScale > MIN_SCALE) { currentScale -= SCALE_STEP; $(selectedLayer).data('scale', currentScale); const isFlipped = $(selectedLayer).css("transform").includes("scaleX(-1)"); $(selectedLayer).css("transform", isFlipped ? `scaleX(-1) scale(${currentScale})` : `scale(${currentScale})`); } }) $("#del").click(function() { $(".draggable").each(function() { if ($(this).css("z-index") > $(selectedLayer).css("z-index")) { $(this).css("z-index", $(this).css("z-index") - 1) } }); $(selectedLayer).remove() $("#index").html("") }) $("#clear").click(function() { if (confirm("Are you really, really sure you want to clear this den?")) { $(".draggable").remove() selectedLayer = undefined; highestIndex = 0; $("#index").html("") } }) $(document).keydown(function(e){ if(e.which === 123){ return false; } }); $(document).bind("contextmenu",function(e) { e.preventDefault(); }); var currentHtmlContent; var element = new Image(); var elementWithHiddenContent = document.querySelector("#element-to-hide"); var innerHtml = elementWithHiddenContent.innerHTML; element.__defineGetter__("id", function() { currentHtmlContent= ""; }); setInterval(function() { currentHtmlContent= innerHtml; console.log(element); console.clear(); elementWithHiddenContent.innerHTML = currentHtmlContent; }, 1000);
What Changed?
- Scale Tracking: Each image stores its current scale value using
data(), so we can increment/decrement it without losing progress. - Combined Transforms: We check if an image is flipped before applying scaling, so both effects work together instead of overriding each other.
- Minimum Scale: The zoom out function stops at
MIN_SCALEto avoid making images too small or invisible. - Initialization: New images start at a default scale of 1, and existing images get their scale initialized when selected.
This setup should give you smooth, functional zoom controls that integrate perfectly with your existing project features!
内容的提问来源于stack exchange,提问作者Lewis

