Share a plug-in that automatically falls water droplets, download address: https://github.com/foreverjiangting/rainyday.js
Let’s see how to use it? Add the following code to run it.
The effect is as follows:
The code is as follows:
<!DOCTYPE HTML><html><head><style></style><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title></title><script type="text/javascript">function runImage(){var image=document.getElementById("img");image.src="4.jpg";image.onload=function(){//Set a rain object var engine=new RainyDay({image:this,}); //Calling the rain function engine.rain([[4,6,8000]]);//Set the raindrop size 4,6 to 8000 || Can also be engine.rain([[6,8000]]), at this time the size of the water droplet is smaller engine.rain([[3,3,0.88],[5,5,0.9],[6,2,1]],100);//Set the raindrop repetition time}// image.crossOrigin="jt"; Load cross-domain image}</script></head><body onload="runImage();" ><div><img src="4.jpg" id="img"></div><script type="text/javascript" src="rainy.js"></script> </body></html>Let’s study some of the rainy.js code below. See the source code in github above:
RainyDay.prototype.rain = function(presets, speed) {// Prepare canvas for drop mapping if (this.reflection !== this.REFLECTION_NONE) {this.prepareReflections();}this.animateDrops();// Animation this.presets = presets;this.PRIVATE_GRAVITY_FORCE_FACTOR_Y = (this.options.fps * 0.001) / 25;this.PRIVATE_GRAVITY_FORCE_FACTOR_X = ((Math.PI / 2) - this.options.gravityAngle) * (this.options.fps * 0.001) / 50;// Model to prepare the fall if (this.options.enableCollisions) {// Calculate the largest droplet rounded corner of the fallen water drop var maxDropRadius = 0;for (var i = 0; i < presets.length; i++) {if (presets[i][0] + presets[i][1] > maxDropRadius) {maxDropRadius = Math.floor(presets[i][0] + presets[i][1]);}}if (maxDropRadius > 0) {// Model to initialize the fallen var mwi = Math.ceil(this.canvas.width / maxDropRadius);var mhi = Math.ceil(this.canvas.height / maxDropRadius);this.matrix = new CollisionMatrix(mwi, mhi, maxDropRadius);} else {this.options.enableCollisions = false;}}for (var i = 0; i < presets.length; i++) {if (!presets[i][3]) {presets[i][3] = -1;}}var lastExecutionTime = 0;this.addDropCallback = function() {var timestamp = new Date().getTime();if (timestamp - lastExecutionTime < speed) {return;}lastExecutionTime = timestamp;var context = this.canvas.getContext('2d');context.clearRect(0, 0, this.canvas.width, this.canvas.height);context.drawImage(this.background, 0, 0, this.canvas.width, this.canvas.height);// Select the matching model var preset;for (var i = 0; i < presets.length; i++) {if (presets[i][2] > 1 || presets[i][3] === -1) {if (presets[i][3] !== 0) {presets[i][3]--;for (var y = 0; y < presets[i][2]; ++y) {this.putDrop(new Drop(this, Math.random() * this.canvas.width, Math.random() * this.canvas.height, presets[i][0], presets[i][1]));}} else if (Math.random() < presets[i][2]) {preset = presets[i];break;}}if (preset) {this.putDrop(new Drop(this, Math.random() * this.canvas.width, Math.random() * this.canvas.height, preset[0], preset[1]));}context.save();context.globalAlpha = this.opacity;context.drawImage(this.glass, 0, 0, this.canvas.width, this.canvas.height);context.restore();}.bind(this);};Here I want to mention the question about cross-domain resources, image.crossOrigin="jt"; Loading cross-domain images. At the beginning, I used cross-domain pictures, but there was a problem, and then I used the local picture to load, i.e. src="4.jpg" , and there was no problem. In fact, if you want to use cross-domain images, just add image.crossOrigin="jt";; the code.
(Presponse is that the server has enabled permissions)
This involves CORS issue, let’s take a look at: The full name of CORS is "Cross-origin resource sharing". It allows the browser to cross-origin server
Issuing an xmlhttprequest request overcomes the limitation that AJAX can only be used in the same origin.
We also use the above column to view the problem:
<!DOCTYPE HTML><html><head><style></style><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title></title><script type="text/javascript">function runImage(){var image=document.getElementById("img");image.onload=function(){//Set a rain object var engine=new RainyDay({image:this,});engine.rain([[4,6,8000]]);//Set raindrop size 4,6 The number is 8000engine.rain([[3,3,0.88],[5,5,0.9],[6,2,1]],100);//Set the raindrop repetition time}// image.crossOrigin="jt"; // Cross-domain image image.src="http://img0.imgtn.bdimg.com/it/u=938096994,3074232342&fm=21&gp=0.jpg"; }</script></head><body onload="runImage();" ><div><img src="http://img0.imgtn.bdimg.com/it/u=938096994,3074232342&fm=21&gp=0.jpg" id="img"></div><script type="text/javascript" src="rainy.js"></script></body></html>Let's take a look at the information in the debug console:
Accept image/png,image/*;q=0.8,*/*;q=0.5Accept-Encoding gzip, deflateAccept-Language zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Connection keep-aliveHost img0.imgtn.bdimg.comOrigin null ---In the above header information, the Origin field is used to indicate which source the request comes from (protocol + domain name + port). The server decides whether to agree to the request based on this value. It is not within the scope of the permission. The server will return a normal HTTP response. The browser found that the header information of this response did not contain the Access-Control-Allow-Origin field (see below for details), so it was known that an error occurred, and thus an error was thrown, which was captured by the onerror callback function of XMLHttpRequest. Note that this error cannot be identified by the status code, because the status code of the HTTP response may be 200. GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0. User-Agent Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0
If the domain name specified by Origin is within the permission scope, the response returned by the server will have several additional header fields.
The above content is a plug-in shared by the editor to achieve the automatic droplet droplet fall effect. I hope you like it!