簡體   English   中英

為了獲得更好的拖動效果,正確的偏移量是多少?

[英]What is the right offset for better drag effect?

我正在嘗試使我的雲變得可拖動。 它可以工作,但是正如我在示例中所看到的,雲總是從中心到鼠標位置修剪。

這是我當前的設置。

 $(document).ready(function () { var canvas = document.getElementById("background-canvas"); canvas.width = $(window).width(); canvas.height = $(window).height(); canvas.style.zIndex = -1; var ctx = canvas.getContext("2d"); var mousePosition = new Vector2d(0,0); var background = new Background(ctx, canvas.width, canvas.height, new Color(224,247,250,0.8)); var cloud = new Cloud(background, 300, 100, new Vector2d(10,10), 20, 1000); img=new Image(); img.src="https://i.imgur.com/hIVsoho.png"; background.addCloud(cloud); for (var i = 0; i < background.allClouds.length; i++){ var selectedCloud = background.allClouds[i]; for (var j = 0; j < selectedCloud.maxNumberofPixels; j++){ var pixel = cloud.createPixel(); // TODO: cloud shall not define pixel. //new Pixel(2, 4, getRandomLocationWithinParent(selectedCloud), new Vector2d(0,5), new Vector2d(0,0), new Color(0,0,128,1)); cloud.addPixel(pixel); } } /* * Input listeners */ document.addEventListener("mousemove", function (evt) { mousePosition = getMousePos(canvas, evt); }, false); document.addEventListener("mousedown", function (evt){ console.log(mousePosition); for(var i = 0; i < background.allClouds.length; i++) if(background.allClouds[i].hover(mousePosition)) background.allClouds[i].isClicked = true; }, false) document.addEventListener("mouseup", function (evt){ for(var i = 0; i < background.allClouds.length; i++) if(background.allClouds[i].hover(mousePosition)) background.allClouds[i].isClicked = false; }, false) setInterval(updateBackground, 20); function updateBackground() { // paint background color. ctx.fillStyle = background.color.getColorString(); ctx.fillRect(0,0,background.width, background.height); // paint clouds for(var i = 0; i < background.allClouds.length; i++){ var selectedCloud = background.allClouds[i]; //ctx.fillStyle = selectedCloud.color.getColorString(); //ctx.fillRect(0, 0, selectedCloud.width, selectedCloud.height); rectangle view of cloud. // paint rain var deadPixelContainer = []; for (var j = 0; j < selectedCloud.allPixels.length; j++){ var selectedPixel = selectedCloud.allPixels[j]; ctx.fillStyle = selectedPixel.color.getColorString(); ctx.save(); ctx.translate(selectedPixel.location.x, selectedPixel.location.y); ctx.fillRect(-selectedPixel.width / 2, -selectedPixel.height / 2, selectedPixel.width, selectedPixel.height); ctx.restore(); if(!selectedPixel.alive){ deadPixelContainer.push(selectedPixel); continue; } selectedPixel.update(); selectedPixel.checkEdges(background); } if(deadPixelContainer.length > 0){ selectedCloud.removePixels(deadPixelContainer); } ctx.save(); ctx.translate(selectedCloud.location.x, selectedCloud.location.y); ctx.drawImage(img,0,0,img.width,img.height,-25, -10,350,100); ctx.restore(); cloud.update(mousePosition); } } // TODO: Create object for mouse function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return new Vector2d(evt.clientX - rect.left, evt.clientY - rect.top); } }); function Cloud(background, width, height, location, startNumberOfPixels, maxNumberofPixels){ this.width = width; this.height = height; this.location = location; this.allPixels = []; this.maxNumberofPixels = maxNumberofPixels; this.color = new Color(255,255,255,0.5); this.isClicked = false; this.rainStrength = 5; // how often cloud spawns new pixels per update cycle. this.addPixel = function(pixel){ if(this.allPixels.length <= startNumberOfPixels) this.allPixels.push(pixel); } this.update = function(mousePosition){ // make cloud draggable if(this.isClicked){ var offsetX = mousePosition.x - this.location.x; var offsetY = mousePosition.y - this.location.y; this.location = new Vector2d(this.location.x + offsetX - this.width/2, this.location.y + offsetY - this.height/2); } // add more pixels overtime. if(this.allPixels.length <= this.maxNumberofPixels) for(var i = 0; i < this.rainStrength; i++) this.allPixels.push(this.createPixel()); } this.hover = function(mousePosition){ if(mousePosition.x > this.location.x && mousePosition.x < this.location.x + this.width && mousePosition.y > this.location.y && mousePosition.y < this.location.y + this.height) return true; return false; } this.createPixel = function(){ return new Pixel(2, 4, this.getRandomLocation(), new Vector2d(0,7), new Vector2d(0,0.05), new Color(0,0,128,1)); } this.removePixels = function(deadPixelContainer){ for(var i = 0; i < deadPixelContainer.length; i++){ try{ var pixelContainer = this.allPixels.slice(); pixelContainer.splice(this.allPixels.findIndex(v => v === deadPixelContainer[i]), 1).slice(); this.allPixels = pixelContainer.slice(); }catch(e){ console.log(e); } } } this.getRandomLocation = function(){ var minWidth = this.location.x; var maxWidth = this.location.x + this.width; var minHeight = this.location.y + this.height/2; // don't count upper part of cloud. Rain forms at the bottom. var maxHeight = this.location.y + this.height; var randomWidthLocation = Math.random() * (maxWidth - minWidth + 1)+minWidth; var randomHeightLocation = Math.random() * (maxHeight - minHeight + 1) + minHeight; return new Vector2d(randomWidthLocation, randomHeightLocation); } } function Background(ctx, width, height, color){ this.width = width; this.height = height; this.color = color; //"#191919" this.isPaused = false; this.allPixels = []; // might need to be removed. this.allClouds = []; this.pixelCount = 150; this.addCloud = function(cloud){ this.allClouds.push(cloud); }; this.refreshCanvas = function(){ this.width = $(window).width(); this.height = $(window).height(); }; this.addPixelOn = function(pixelWidht, pixelHeight, location, velocity, acceleration, color) { // might need to be removed. var pixel = new Pixel(pixelWidht, pixelHeight, location, velocity, acceleration, color); this.allPixels.push(pixel); }; this.addPixel = function(pixelWidht, pixelHeight, velocity, acceleration, color) { // might need to be removed. var location = new Vector2d(Math.random() * this.width, Math.random() * this.height); this.addPixelOn(pixelWidht, pixelHeight, location, velocity, acceleration, color); }; } function Pixel(widht, height, location, velocity, acceleration, color) { this.height = height; this.width = widht; this.color = color; //"#00CC33" this.location = location; this.velocity = velocity; this.acceleration = acceleration; this.alive = true; this.update = function () { this.velocity.add(this.acceleration); //this.velocity.limit(topspeed); this.location.add(this.velocity); }; this.checkEdges = function (background) { if (this.location.y > background.height) { this.alive = false; } }; this.setColor = function(color){ this.color = color; }; this.setHeight = function(height){ this.height = height; }; this.setWidth = function(width){ this.width = width; } } function Color(r,g,b,o){ this.red = r; this.green = g; this.blue = b; this.opacity = o; this.getColorString = function(){ return "rgba("+this.red+","+this.green+","+this.blue+","+this.opacity+")"; } } function Vector2d(x, y) { this.x = x; this.y = y; this.add = function (vector2d) { this.x += vector2d.x; this.y += vector2d.y; }; this.sub = function (vector2d) { this.x -= vector2d.x; this.y -= vector2d.y; }; this.mult = function (mult) { this.x *= mult; this.y *= mult; }; this.div = function (div) { this.x /= div; this.y /= div; }; this.mag = function () { return Math.sqrt(this.x * this.x, this.y * this.y); }; this.norm = function () { var m = this.mag(); if (m !== 0) { this.div(m); } } } 
 #background-canvas { position: fixed; width: 100%; height: 100% background-color:red; top:0; left:0; } 
 <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body> <canvas id="background-canvas" /> </body> </html> 

設置拖動時雲的位置的代碼是:

// make cloud draggable
if(this.isClicked){
    var offsetX = mousePosition.x - this.location.x;
    var offsetY = mousePosition.y - this.location.y;

    this.location = new Vector2d(this.location.x + offsetX - this.width/2, this.location.y + offsetY - this.height/2);
}

這不能正常工作。 我希望它不會夾在中間。

誰能幫我這個 ?

如果尚不清楚問題是什么,或者您需要其他信息,請詢問。

您需要記住點擊的位置在雲的本地坐標系中:

if(background.allClouds[i].hover(mousePosition)) {
    background.allClouds[i].isClicked = true;
    background.allClouds[i].clickLocalPosition = new Vector2d(mousePosition.x, mousePosition.y);
    background.allClouds[i].clickLocalPosition.sub(background.allClouds[i].location);
}

然后,當您更新時,您將根據點擊位置計算新位置:

this.location.x = mousePosition.x - this.clickLocalPosition.x;
this.location.y = mousePosition.y - this.clickLocalPosition.y;  

 $(document).ready(function () { var canvas = document.getElementById("background-canvas"); canvas.width = $(window).width(); canvas.height = $(window).height(); canvas.style.zIndex = -1; var ctx = canvas.getContext("2d"); var mousePosition = new Vector2d(0,0); var background = new Background(ctx, canvas.width, canvas.height, new Color(224,247,250,0.8)); var cloud = new Cloud(background, 300, 100, new Vector2d(10,10), 20, 1000); img=new Image(); img.src="https://i.imgur.com/hIVsoho.png"; background.addCloud(cloud); for (var i = 0; i < background.allClouds.length; i++){ var selectedCloud = background.allClouds[i]; for (var j = 0; j < selectedCloud.maxNumberofPixels; j++){ var pixel = cloud.createPixel(); // TODO: cloud shall not define pixel. //new Pixel(2, 4, getRandomLocationWithinParent(selectedCloud), new Vector2d(0,5), new Vector2d(0,0), new Color(0,0,128,1)); cloud.addPixel(pixel); } } /* * Input listeners */ document.addEventListener("mousemove", function (evt) { mousePosition = getMousePos(canvas, evt); }, false); document.addEventListener("mousedown", function (evt){ console.log(mousePosition); for(var i = 0; i < background.allClouds.length; i++) if(background.allClouds[i].hover(mousePosition)) { background.allClouds[i].isClicked = true; background.allClouds[i].clickLocalPosition = new Vector2d(mousePosition.x, mousePosition.y); background.allClouds[i].clickLocalPosition.sub(background.allClouds[i].location); } }, false) document.addEventListener("mouseup", function (evt){ for(var i = 0; i < background.allClouds.length; i++) if(background.allClouds[i].hover(mousePosition)) background.allClouds[i].isClicked = false; }, false) setInterval(updateBackground, 20); function updateBackground() { // paint background color. ctx.fillStyle = background.color.getColorString(); ctx.fillRect(0,0,background.width, background.height); // paint clouds for(var i = 0; i < background.allClouds.length; i++){ var selectedCloud = background.allClouds[i]; //ctx.fillStyle = selectedCloud.color.getColorString(); //ctx.fillRect(0, 0, selectedCloud.width, selectedCloud.height); rectangle view of cloud. // paint rain var deadPixelContainer = []; for (var j = 0; j < selectedCloud.allPixels.length; j++){ var selectedPixel = selectedCloud.allPixels[j]; ctx.fillStyle = selectedPixel.color.getColorString(); ctx.save(); ctx.translate(selectedPixel.location.x, selectedPixel.location.y); ctx.fillRect(-selectedPixel.width / 2, -selectedPixel.height / 2, selectedPixel.width, selectedPixel.height); ctx.restore(); if(!selectedPixel.alive){ deadPixelContainer.push(selectedPixel); continue; } selectedPixel.update(); selectedPixel.checkEdges(background); } if(deadPixelContainer.length > 0){ selectedCloud.removePixels(deadPixelContainer); } ctx.save(); ctx.translate(selectedCloud.location.x, selectedCloud.location.y); ctx.drawImage(img,0,0,img.width,img.height,-25, -10,350,100); ctx.restore(); cloud.update(mousePosition); } } // TODO: Create object for mouse function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return new Vector2d(evt.clientX - rect.left, evt.clientY - rect.top); } }); function Cloud(background, width, height, location, startNumberOfPixels, maxNumberofPixels){ this.width = width; this.height = height; this.location = location; this.allPixels = []; this.maxNumberofPixels = maxNumberofPixels; this.color = new Color(255,255,255,0.5); this.isClicked = false; this.rainStrength = 5; // how often cloud spawns new pixels per update cycle. this.addPixel = function(pixel){ if(this.allPixels.length <= startNumberOfPixels) this.allPixels.push(pixel); } this.update = function(mousePosition){ // make cloud draggable if(this.isClicked){ this.location.x = mousePosition.x - this.clickLocalPosition.x; this.location.y = mousePosition.y - this.clickLocalPosition.y; } // add more pixels overtime. if(this.allPixels.length <= this.maxNumberofPixels) for(var i = 0; i < this.rainStrength; i++) this.allPixels.push(this.createPixel()); } this.hover = function(mousePosition){ if(mousePosition.x > this.location.x && mousePosition.x < this.location.x + this.width && mousePosition.y > this.location.y && mousePosition.y < this.location.y + this.height) return true; return false; } this.createPixel = function(){ return new Pixel(2, 4, this.getRandomLocation(), new Vector2d(0,7), new Vector2d(0,0.05), new Color(0,0,128,1)); } this.removePixels = function(deadPixelContainer){ for(var i = 0; i < deadPixelContainer.length; i++){ try{ var pixelContainer = this.allPixels.slice(); pixelContainer.splice(this.allPixels.findIndex(v => v === deadPixelContainer[i]), 1).slice(); this.allPixels = pixelContainer.slice(); }catch(e){ console.log(e); } } } this.getRandomLocation = function(){ var minWidth = this.location.x; var maxWidth = this.location.x + this.width; var minHeight = this.location.y + this.height/2; // don't count upper part of cloud. Rain forms at the bottom. var maxHeight = this.location.y + this.height; var randomWidthLocation = Math.random() * (maxWidth - minWidth + 1)+minWidth; var randomHeightLocation = Math.random() * (maxHeight - minHeight + 1) + minHeight; return new Vector2d(randomWidthLocation, randomHeightLocation); } } function Background(ctx, width, height, color){ this.width = width; this.height = height; this.color = color; //"#191919" this.isPaused = false; this.allPixels = []; // might need to be removed. this.allClouds = []; this.pixelCount = 150; this.addCloud = function(cloud){ this.allClouds.push(cloud); }; this.refreshCanvas = function(){ this.width = $(window).width(); this.height = $(window).height(); }; this.addPixelOn = function(pixelWidht, pixelHeight, location, velocity, acceleration, color) { // might need to be removed. var pixel = new Pixel(pixelWidht, pixelHeight, location, velocity, acceleration, color); this.allPixels.push(pixel); }; this.addPixel = function(pixelWidht, pixelHeight, velocity, acceleration, color) { // might need to be removed. var location = new Vector2d(Math.random() * this.width, Math.random() * this.height); this.addPixelOn(pixelWidht, pixelHeight, location, velocity, acceleration, color); }; } function Pixel(widht, height, location, velocity, acceleration, color) { this.height = height; this.width = widht; this.color = color; //"#00CC33" this.location = location; this.velocity = velocity; this.acceleration = acceleration; this.alive = true; this.update = function () { this.velocity.add(this.acceleration); //this.velocity.limit(topspeed); this.location.add(this.velocity); }; this.checkEdges = function (background) { if (this.location.y > background.height) { this.alive = false; } }; this.setColor = function(color){ this.color = color; }; this.setHeight = function(height){ this.height = height; }; this.setWidth = function(width){ this.width = width; } } function Color(r,g,b,o){ this.red = r; this.green = g; this.blue = b; this.opacity = o; this.getColorString = function(){ return "rgba("+this.red+","+this.green+","+this.blue+","+this.opacity+")"; } } function Vector2d(x, y) { this.x = x; this.y = y; this.add = function (vector2d) { this.x += vector2d.x; this.y += vector2d.y; }; this.sub = function (vector2d) { this.x -= vector2d.x; this.y -= vector2d.y; }; this.mult = function (mult) { this.x *= mult; this.y *= mult; }; this.div = function (div) { this.x /= div; this.y /= div; }; this.mag = function () { return Math.sqrt(this.x * this.x, this.y * this.y); }; this.norm = function () { var m = this.mag(); if (m !== 0) { this.div(m); } } } 
 #background-canvas { position: fixed; width: 100%; height: 100% background-color:red; top:0; left:0; } 
 <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body> <canvas id="background-canvas" /> </body> </html> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM