Commit b0c182ea authored by 周宏民's avatar 周宏民

feat: 邳州登陆页

parent 9d9968c2
......@@ -129,6 +129,7 @@
"hoist-non-react-statics": "3.3.0",
"immer": "3.0.0",
"immutable": "^4.0.0-rc.12",
"jquery": "^3.7.0",
"js-base64": "^3.5.2",
"js-cookie": "^2.2.1",
"kit_global_config": "^1.0.46",
......
/**
* jQuery Ripples plugin v0.6.3 / https://github.com/sirxemic/jquery.ripples
* MIT License
* @author sirxemic / https://sirxemic.com/
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
(factory(global.$));
}(this, (function ($) { 'use strict';
$ = $ && 'default' in $ ? $['default'] : $;
var gl;
var $window = $(window); // There is only one window, so why not cache the jQuery-wrapped window?
function isPercentage(str) {
return str[str.length - 1] == '%';
}
/**
* Load a configuration of GL settings which the browser supports.
* For example:
* - not all browsers support WebGL
* - not all browsers support floating point textures
* - not all browsers support linear filtering for floating point textures
* - not all browsers support rendering to floating point textures
* - some browsers *do* support rendering to half-floating point textures instead.
*/
function loadConfig() {
var canvas = document.createElement('canvas');
gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
// Browser does not support WebGL.
return null;
}
// Load extensions
var extensions = {};
[
'OES_texture_float',
'OES_texture_half_float',
'OES_texture_float_linear',
'OES_texture_half_float_linear'
].forEach(function(name) {
var extension = gl.getExtension(name);
if (extension) {
extensions[name] = extension;
}
});
// If no floating point extensions are supported we can bail out early.
if (!extensions.OES_texture_float) {
return null;
}
var configs = [];
function createConfig(type, glType, arrayType) {
var name = 'OES_texture_' + type,
nameLinear = name + '_linear',
linearSupport = nameLinear in extensions,
configExtensions = [name];
if (linearSupport) {
configExtensions.push(nameLinear);
}
return {
type: glType,
arrayType: arrayType,
linearSupport: linearSupport,
extensions: configExtensions
};
}
configs.push(
createConfig('float', gl.FLOAT, Float32Array)
);
if (extensions.OES_texture_half_float) {
configs.push(
// Array type should be Uint16Array, but at least on iOS that breaks. In that case we
// just initialize the textures with data=null, instead of data=new Uint16Array(...).
// This makes initialization a tad slower, but it's still negligible.
createConfig('half_float', extensions.OES_texture_half_float.HALF_FLOAT_OES, null)
);
}
// Setup the texture and framebuffer
var texture = gl.createTexture();
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Check for each supported texture type if rendering to it is supported
var config = null;
for (var i = 0; i < configs.length; i++) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, configs[i].type, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) {
config = configs[i];
break;
}
}
return config;
}
function createImageData(width, height) {
try {
return new ImageData(width, height);
}
catch (e) {
// Fallback for IE
var canvas = document.createElement('canvas');
return canvas.getContext('2d').createImageData(width, height);
}
}
function translateBackgroundPosition(value) {
var parts = value.split(' ');
if (parts.length === 1) {
switch (value) {
case 'center':
return ['50%', '50%'];
case 'top':
return ['50%', '0'];
case 'bottom':
return ['50%', '100%'];
case 'left':
return ['0', '50%'];
case 'right':
return ['100%', '50%'];
default:
return [value, '50%'];
}
}
else {
return parts.map(function(part) {
switch (value) {
case 'center':
return '50%';
case 'top':
case 'left':
return '0';
case 'right':
case 'bottom':
return '100%';
default:
return part;
}
});
}
}
function createProgram(vertexSource, fragmentSource, uniformValues) {
function compileSource(type, source) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error('compile error: ' + gl.getShaderInfoLog(shader));
}
return shader;
}
var program = {};
program.id = gl.createProgram();
gl.attachShader(program.id, compileSource(gl.VERTEX_SHADER, vertexSource));
gl.attachShader(program.id, compileSource(gl.FRAGMENT_SHADER, fragmentSource));
gl.linkProgram(program.id);
if (!gl.getProgramParameter(program.id, gl.LINK_STATUS)) {
throw new Error('link error: ' + gl.getProgramInfoLog(program.id));
}
// Fetch the uniform and attribute locations
program.uniforms = {};
program.locations = {};
gl.useProgram(program.id);
gl.enableVertexAttribArray(0);
var match, name, regex = /uniform (\w+) (\w+)/g, shaderCode = vertexSource + fragmentSource;
while ((match = regex.exec(shaderCode)) != null) {
name = match[2];
program.locations[name] = gl.getUniformLocation(program.id, name);
}
return program;
}
function bindTexture(texture, unit) {
gl.activeTexture(gl.TEXTURE0 + (unit || 0));
gl.bindTexture(gl.TEXTURE_2D, texture);
}
function extractUrl(value) {
var urlMatch = /url\(["']?([^"']*)["']?\)/.exec(value);
if (urlMatch == null) {
return null;
}
return urlMatch[1];
}
function isDataUri(url) {
return url.match(/^data:/);
}
var config = loadConfig();
var transparentPixels = createImageData(32, 32);
// Extend the css
$('head').prepend('<style>.jquery-ripples { position: relative; z-index: 0; }</style>');
// RIPPLES CLASS DEFINITION
// =========================
var Ripples = function (el, options) {
var that = this;
this.$el = $(el);
// Init properties from options
this.interactive = options.interactive;
this.resolution = options.resolution;
this.textureDelta = new Float32Array([1 / this.resolution, 1 / this.resolution]);
this.perturbance = options.perturbance;
this.dropRadius = options.dropRadius;
this.crossOrigin = options.crossOrigin;
this.imageUrl = options.imageUrl;
// Init WebGL canvas
var canvas = document.createElement('canvas');
canvas.width = this.$el.innerWidth();
canvas.height = this.$el.innerHeight();
this.canvas = canvas;
this.$canvas = $(canvas);
this.$canvas.css({
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: -1
});
this.$el.addClass('jquery-ripples').append(canvas);
this.context = gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
// Load extensions
config.extensions.forEach(function(name) {
gl.getExtension(name);
});
// Auto-resize when window size changes.
this.updateSize = this.updateSize.bind(this);
$(window).on('resize', this.updateSize);
// Init rendertargets for ripple data.
this.textures = [];
this.framebuffers = [];
this.bufferWriteIndex = 0;
this.bufferReadIndex = 1;
var arrayType = config.arrayType;
var textureData = arrayType ? new arrayType(this.resolution * this.resolution * 4) : null;
for (var i = 0; i < 2; i++) {
var texture = gl.createTexture();
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, config.linearSupport ? gl.LINEAR : gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, config.linearSupport ? gl.LINEAR : gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.resolution, this.resolution, 0, gl.RGBA, config.type, textureData);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
this.textures.push(texture);
this.framebuffers.push(framebuffer);
}
// Init GL stuff
this.quad = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.quad);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1, -1,
+1, -1,
+1, +1,
-1, +1
]), gl.STATIC_DRAW);
this.initShaders();
this.initTexture();
this.setTransparentTexture();
// Load the image either from the options or CSS rules
this.loadImage();
// Set correct clear color and blend mode (regular alpha blending)
gl.clearColor(0, 0, 0, 0);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
// Plugin is successfully initialized!
this.visible = true;
this.running = true;
this.inited = true;
this.destroyed = false;
this.setupPointerEvents();
// Init animation
function step() {
if (!that.destroyed) {
that.step();
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
};
Ripples.DEFAULTS = {
imageUrl: null,
resolution: 256,
dropRadius: 20,
perturbance: 0.03,
interactive: true,
crossOrigin: ''
};
Ripples.prototype = {
// Set up pointer (mouse + touch) events
setupPointerEvents: function() {
var that = this;
function pointerEventsEnabled() {
return that.visible && that.running && that.interactive;
}
function dropAtPointer(pointer, big) {
if (pointerEventsEnabled()) {
that.dropAtPointer(
pointer,
that.dropRadius * (big ? 1.5 : 1),
(big ? 0.14 : 0.01)
);
}
}
// Start listening to pointer events
this.$el
// Create regular, small ripples for mouse move and touch events...
.on('mousemove.ripples', function(e) {
dropAtPointer(e);
})
.on('touchmove.ripples touchstart.ripples', function(e) {
var touches = e.originalEvent.changedTouches;
for (var i = 0; i < touches.length; i++) {
dropAtPointer(touches[i]);
}
})
// ...and only a big ripple on mouse down events.
.on('mousedown.ripples', function(e) {
dropAtPointer(e, true);
});
},
// Load the image either from the options or the element's CSS rules.
loadImage: function() {
var that = this;
gl = this.context;
var newImageSource = this.imageUrl ||
extractUrl(this.originalCssBackgroundImage) ||
extractUrl(this.$el.css('backgroundImage'));
// If image source is unchanged, don't reload it.
if (newImageSource == this.imageSource) {
return;
}
this.imageSource = newImageSource;
// Falsy source means no background.
if (!this.imageSource) {
this.setTransparentTexture();
return;
}
// Load the texture from a new image.
var image = new Image;
image.onload = function() {
gl = that.context;
// Only textures with dimensions of powers of two can have repeat wrapping.
function isPowerOfTwo(x) {
return (x & (x - 1)) == 0;
}
var wrapping = (isPowerOfTwo(image.width) && isPowerOfTwo(image.height)) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
gl.bindTexture(gl.TEXTURE_2D, that.backgroundTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapping);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapping);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
that.backgroundWidth = image.width;
that.backgroundHeight = image.height;
// Hide the background that we're replacing.
that.hideCssBackground();
};
// Fall back to a transparent texture when loading the image failed.
image.onerror = function() {
gl = that.context;
that.setTransparentTexture();
};
// Disable CORS when the image source is a data URI.
image.crossOrigin = isDataUri(this.imageSource) ? null : this.crossOrigin;
image.src = this.imageSource;
},
step: function() {
gl = this.context;
if (!this.visible) {
return;
}
this.computeTextureBoundaries();
if (this.running) {
this.update();
}
this.render();
},
drawQuad: function() {
gl.bindBuffer(gl.ARRAY_BUFFER, this.quad);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
},
render: function() {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, this.canvas.width, this.canvas.height);
gl.enable(gl.BLEND);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(this.renderProgram.id);
bindTexture(this.backgroundTexture, 0);
bindTexture(this.textures[0], 1);
gl.uniform1f(this.renderProgram.locations.perturbance, this.perturbance);
gl.uniform2fv(this.renderProgram.locations.topLeft, this.renderProgram.uniforms.topLeft);
gl.uniform2fv(this.renderProgram.locations.bottomRight, this.renderProgram.uniforms.bottomRight);
gl.uniform2fv(this.renderProgram.locations.containerRatio, this.renderProgram.uniforms.containerRatio);
gl.uniform1i(this.renderProgram.locations.samplerBackground, 0);
gl.uniform1i(this.renderProgram.locations.samplerRipples, 1);
this.drawQuad();
gl.disable(gl.BLEND);
},
update: function() {
gl.viewport(0, 0, this.resolution, this.resolution);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffers[this.bufferWriteIndex]);
bindTexture(this.textures[this.bufferReadIndex]);
gl.useProgram(this.updateProgram.id);
this.drawQuad();
this.swapBufferIndices();
},
swapBufferIndices: function() {
this.bufferWriteIndex = 1 - this.bufferWriteIndex;
this.bufferReadIndex = 1 - this.bufferReadIndex;
},
computeTextureBoundaries: function() {
var backgroundSize = this.$el.css('background-size');
var backgroundAttachment = this.$el.css('background-attachment');
var backgroundPosition = translateBackgroundPosition(this.$el.css('background-position'));
// Here the 'container' is the element which the background adapts to
// (either the chrome window or some element, depending on attachment)
var container;
if (backgroundAttachment == 'fixed') {
container = { left: window.pageXOffset, top: window.pageYOffset };
container.width = $window.width();
container.height = $window.height();
}
else {
container = this.$el.offset();
container.width = this.$el.innerWidth();
container.height = this.$el.innerHeight();
}
// TODO: background-clip
if (backgroundSize == 'cover') {
var scale = Math.max(container.width / this.backgroundWidth, container.height / this.backgroundHeight);
var backgroundWidth = this.backgroundWidth * scale;
var backgroundHeight = this.backgroundHeight * scale;
}
else if (backgroundSize == 'contain') {
var scale = Math.min(container.width / this.backgroundWidth, container.height / this.backgroundHeight);
var backgroundWidth = this.backgroundWidth * scale;
var backgroundHeight = this.backgroundHeight * scale;
}
else {
backgroundSize = backgroundSize.split(' ');
var backgroundWidth = backgroundSize[0] || '';
var backgroundHeight = backgroundSize[1] || backgroundWidth;
if (isPercentage(backgroundWidth)) {
backgroundWidth = container.width * parseFloat(backgroundWidth) / 100;
}
else if (backgroundWidth != 'auto') {
backgroundWidth = parseFloat(backgroundWidth);
}
if (isPercentage(backgroundHeight)) {
backgroundHeight = container.height * parseFloat(backgroundHeight) / 100;
}
else if (backgroundHeight != 'auto') {
backgroundHeight = parseFloat(backgroundHeight);
}
if (backgroundWidth == 'auto' && backgroundHeight == 'auto') {
backgroundWidth = this.backgroundWidth;
backgroundHeight = this.backgroundHeight;
}
else {
if (backgroundWidth == 'auto') {
backgroundWidth = this.backgroundWidth * (backgroundHeight / this.backgroundHeight);
}
if (backgroundHeight == 'auto') {
backgroundHeight = this.backgroundHeight * (backgroundWidth / this.backgroundWidth);
}
}
}
// Compute backgroundX and backgroundY in page coordinates
var backgroundX = backgroundPosition[0];
var backgroundY = backgroundPosition[1];
if (isPercentage(backgroundX)) {
backgroundX = container.left + (container.width - backgroundWidth) * parseFloat(backgroundX) / 100;
}
else {
backgroundX = container.left + parseFloat(backgroundX);
}
if (isPercentage(backgroundY)) {
backgroundY = container.top + (container.height - backgroundHeight) * parseFloat(backgroundY) / 100;
}
else {
backgroundY = container.top + parseFloat(backgroundY);
}
var elementOffset = this.$el.offset();
this.renderProgram.uniforms.topLeft = new Float32Array([
(elementOffset.left - backgroundX) / backgroundWidth,
(elementOffset.top - backgroundY) / backgroundHeight
]);
this.renderProgram.uniforms.bottomRight = new Float32Array([
this.renderProgram.uniforms.topLeft[0] + this.$el.innerWidth() / backgroundWidth,
this.renderProgram.uniforms.topLeft[1] + this.$el.innerHeight() / backgroundHeight
]);
var maxSide = Math.max(this.canvas.width, this.canvas.height);
this.renderProgram.uniforms.containerRatio = new Float32Array([
this.canvas.width / maxSide,
this.canvas.height / maxSide
]);
},
initShaders: function() {
var vertexShader = [
'attribute vec2 vertex;',
'varying vec2 coord;',
'void main() {',
'coord = vertex * 0.5 + 0.5;',
'gl_Position = vec4(vertex, 0.0, 1.0);',
'}'
].join('\n');
this.dropProgram = createProgram(vertexShader, [
'precision highp float;',
'const float PI = 3.141592653589793;',
'uniform sampler2D texture;',
'uniform vec2 center;',
'uniform float radius;',
'uniform float strength;',
'varying vec2 coord;',
'void main() {',
'vec4 info = texture2D(texture, coord);',
'float drop = max(0.0, 1.0 - length(center * 0.5 + 0.5 - coord) / radius);',
'drop = 0.5 - cos(drop * PI) * 0.5;',
'info.r += drop * strength;',
'gl_FragColor = info;',
'}'
].join('\n'));
this.updateProgram = createProgram(vertexShader, [
'precision highp float;',
'uniform sampler2D texture;',
'uniform vec2 delta;',
'varying vec2 coord;',
'void main() {',
'vec4 info = texture2D(texture, coord);',
'vec2 dx = vec2(delta.x, 0.0);',
'vec2 dy = vec2(0.0, delta.y);',
'float average = (',
'texture2D(texture, coord - dx).r +',
'texture2D(texture, coord - dy).r +',
'texture2D(texture, coord + dx).r +',
'texture2D(texture, coord + dy).r',
') * 0.25;',
'info.g += (average - info.r) * 2.0;',
'info.g *= 0.995;',
'info.r += info.g;',
'gl_FragColor = info;',
'}'
].join('\n'));
gl.uniform2fv(this.updateProgram.locations.delta, this.textureDelta);
this.renderProgram = createProgram([
'precision highp float;',
'attribute vec2 vertex;',
'uniform vec2 topLeft;',
'uniform vec2 bottomRight;',
'uniform vec2 containerRatio;',
'varying vec2 ripplesCoord;',
'varying vec2 backgroundCoord;',
'void main() {',
'backgroundCoord = mix(topLeft, bottomRight, vertex * 0.5 + 0.5);',
'backgroundCoord.y = 1.0 - backgroundCoord.y;',
'ripplesCoord = vec2(vertex.x, -vertex.y) * containerRatio * 0.5 + 0.5;',
'gl_Position = vec4(vertex.x, -vertex.y, 0.0, 1.0);',
'}'
].join('\n'), [
'precision highp float;',
'uniform sampler2D samplerBackground;',
'uniform sampler2D samplerRipples;',
'uniform vec2 delta;',
'uniform float perturbance;',
'varying vec2 ripplesCoord;',
'varying vec2 backgroundCoord;',
'void main() {',
'float height = texture2D(samplerRipples, ripplesCoord).r;',
'float heightX = texture2D(samplerRipples, vec2(ripplesCoord.x + delta.x, ripplesCoord.y)).r;',
'float heightY = texture2D(samplerRipples, vec2(ripplesCoord.x, ripplesCoord.y + delta.y)).r;',
'vec3 dx = vec3(delta.x, heightX - height, 0.0);',
'vec3 dy = vec3(0.0, heightY - height, delta.y);',
'vec2 offset = -normalize(cross(dy, dx)).xz;',
'float specular = pow(max(0.0, dot(offset, normalize(vec2(-0.6, 1.0)))), 4.0);',
'gl_FragColor = texture2D(samplerBackground, backgroundCoord + offset * perturbance) + specular;',
'}'
].join('\n'));
gl.uniform2fv(this.renderProgram.locations.delta, this.textureDelta);
},
initTexture: function() {
this.backgroundTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.backgroundTexture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
},
setTransparentTexture: function() {
gl.bindTexture(gl.TEXTURE_2D, this.backgroundTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, transparentPixels);
},
hideCssBackground: function() {
// Check whether we're changing inline CSS or overriding a global CSS rule.
var inlineCss = this.$el[0].style.backgroundImage;
if (inlineCss == 'none') {
return;
}
this.originalInlineCss = inlineCss;
this.originalCssBackgroundImage = this.$el.css('backgroundImage');
this.$el.css('backgroundImage', 'none');
},
restoreCssBackground: function() {
// Restore background by either changing the inline CSS rule to what it was, or
// simply remove the inline CSS rule if it never was inlined.
this.$el.css('backgroundImage', this.originalInlineCss || '');
},
dropAtPointer: function(pointer, radius, strength) {
var borderLeft = parseInt(this.$el.css('border-left-width')) || 0,
borderTop = parseInt(this.$el.css('border-top-width')) || 0;
this.drop(
pointer.pageX - this.$el.offset().left - borderLeft,
pointer.pageY - this.$el.offset().top - borderTop,
radius,
strength
);
},
/**
* Public methods
*/
drop: function(x, y, radius, strength) {
gl = this.context;
var elWidth = this.$el.innerWidth();
var elHeight = this.$el.innerHeight();
var longestSide = Math.max(elWidth, elHeight);
radius = radius / longestSide;
var dropPosition = new Float32Array([
(2 * x - elWidth) / longestSide,
(elHeight - 2 * y) / longestSide
]);
gl.viewport(0, 0, this.resolution, this.resolution);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffers[this.bufferWriteIndex]);
bindTexture(this.textures[this.bufferReadIndex]);
gl.useProgram(this.dropProgram.id);
gl.uniform2fv(this.dropProgram.locations.center, dropPosition);
gl.uniform1f(this.dropProgram.locations.radius, radius);
gl.uniform1f(this.dropProgram.locations.strength, strength);
this.drawQuad();
this.swapBufferIndices();
},
updateSize: function() {
var newWidth = this.$el.innerWidth(),
newHeight = this.$el.innerHeight();
if (newWidth != this.canvas.width || newHeight != this.canvas.height) {
this.canvas.width = newWidth;
this.canvas.height = newHeight;
}
},
destroy: function() {
this.$el
.off('.ripples')
.removeClass('jquery-ripples')
.removeData('ripples');
// Make sure the last used context is garbage-collected
gl = null;
$(window).off('resize', this.updateSize);
this.$canvas.remove();
this.restoreCssBackground();
this.destroyed = true;
},
show: function() {
this.visible = true;
this.$canvas.show();
this.hideCssBackground();
},
hide: function() {
this.visible = false;
this.$canvas.hide();
this.restoreCssBackground();
},
pause: function() {
this.running = false;
},
play: function() {
this.running = true;
},
set: function(property, value) {
switch (property) {
case 'dropRadius':
case 'perturbance':
case 'interactive':
case 'crossOrigin':
this[property] = value;
break;
case 'imageUrl':
this.imageUrl = value;
this.loadImage();
break;
}
}
};
// RIPPLES PLUGIN DEFINITION
// ==========================
var old = $.fn.ripples;
$.fn.ripples = function(option) {
if (!config) {
throw new Error('Your browser does not support WebGL, the OES_texture_float extension or rendering to floating point textures.');
}
var args = (arguments.length > 1) ? Array.prototype.slice.call(arguments, 1) : undefined;
return this.each(function() {
var $this = $(this),
data = $this.data('ripples'),
options = $.extend({}, Ripples.DEFAULTS, $this.data(), typeof option == 'object' && option);
if (!data && typeof option == 'string') {
return;
}
if (!data) {
$this.data('ripples', (data = new Ripples(this, options)));
}
else if (typeof option == 'string') {
Ripples.prototype[option].apply(data, args);
}
});
};
$.fn.ripples.Constructor = Ripples;
// RIPPLES NO CONFLICT
// ====================
$.fn.ripples.noConflict = function() {
$.fn.ripples = old;
return this;
};
})));
.withripple {
position: relative;
}
.ripple-container {
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
overflow: hidden;
border-radius: inherit;
pointer-events: none;
}
.ripple {
position: absolute;
width: 20px;
height: 20px;
margin-left: -10px;
margin-top: -10px;
border-radius: 100%;
background-color: #000;
background-color: rgba(0, 0, 0, 0.05);
-webkit-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
-webkit-transform-origin: 50%;
-ms-transform-origin: 50%;
-o-transform-origin: 50%;
transform-origin: 50%;
opacity: 0;
pointer-events: none;
}
.ripple.ripple-on {
-webkit-transition: opacity 0.15s ease-in 0s, -webkit-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
-o-transition: opacity 0.15s ease-in 0s, -o-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
opacity: 0.1;
}
.ripple.ripple-out {
-webkit-transition: opacity 0.1s linear 0s !important;
-o-transition: opacity 0.1s linear 0s !important;
transition: opacity 0.1s linear 0s !important;
opacity: 0;
}
/*# sourceMappingURL=ripples.css.map */
\ No newline at end of file
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
/* globals jQuery, navigator */
(function($, window, document, undefined) {
"use strict";
/**
* Define the name of the plugin
*/
var ripples = "ripples";
/**
* Get an instance of the plugin
*/
var self = null;
/**
* Define the defaults of the plugin
*/
var defaults = {};
/**
* Create the main plugin function
*/
function Ripples(element, options) {
self = this;
this.element = $(element);
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = ripples;
this.init();
}
/**
* Initialize the plugin
*/
Ripples.prototype.init = function() {
var $element = this.element;
$element.on("mousedown touchstart", function(event) {
/**
* Verify if the user is just touching on a device and return if so
*/
if(self.isTouch() && event.type === "mousedown") {
return;
}
/**
* Verify if the current element already has a ripple wrapper element and
* creates if it doesn't
*/
if(!($element.find(".ripple-container").length)) {
$element.append("<div class=\"ripple-container\"></div>");
}
/**
* Find the ripple wrapper
*/
var $wrapper = $element.children(".ripple-container");
/**
* Get relY and relX positions
*/
var relY = self.getRelY($wrapper, event);
var relX = self.getRelX($wrapper, event);
/**
* If relY and/or relX are false, return the event
*/
if(!relY && !relX) {
return;
}
/**
* Get the ripple color
*/
var rippleColor = self.getRipplesColor($element);
/**
* Create the ripple element
*/
var $ripple = $("<div></div>");
$ripple
.addClass("ripple")
.css({
"left": relX,
"top": relY,
"background-color": rippleColor
});
/**
* Append the ripple to the wrapper
*/
$wrapper.append($ripple);
/**
* Make sure the ripple has the styles applied (ugly hack but it works)
*/
(function() { return window.getComputedStyle($ripple[0]).opacity; })();
/**
* Turn on the ripple animation
*/
self.rippleOn($element, $ripple);
/**
* Call the rippleEnd function when the transition "on" ends
*/
setTimeout(function() {
self.rippleEnd($ripple);
}, 500);
/**
* Detect when the user leaves the element
*/
$element.on("mouseup mouseleave touchend", function() {
$ripple.data("mousedown", "off");
if($ripple.data("animating") === "off") {
self.rippleOut($ripple);
}
});
});
};
/**
* Get the new size based on the element height/width and the ripple width
*/
Ripples.prototype.getNewSize = function($element, $ripple) {
return (Math.max($element.outerWidth(), $element.outerHeight()) / $ripple.outerWidth()) * 2.5;
};
/**
* Get the relX
*/
Ripples.prototype.getRelX = function($wrapper, event) {
var wrapperOffset = $wrapper.offset();
if(!self.isTouch()) {
/**
* Get the mouse position relative to the ripple wrapper
*/
return event.pageX - wrapperOffset.left;
} else {
/**
* Make sure the user is using only one finger and then get the touch
* position relative to the ripple wrapper
*/
event = event.originalEvent;
if(event.touches.length === 1) {
return event.touches[0].pageX - wrapperOffset.left;
}
return false;
}
};
/**
* Get the relY
*/
Ripples.prototype.getRelY = function($wrapper, event) {
var wrapperOffset = $wrapper.offset();
if(!self.isTouch()) {
/**
* Get the mouse position relative to the ripple wrapper
*/
return event.pageY - wrapperOffset.top;
} else {
/**
* Make sure the user is using only one finger and then get the touch
* position relative to the ripple wrapper
*/
event = event.originalEvent;
if(event.touches.length === 1) {
return event.touches[0].pageY - wrapperOffset.top;
}
return false;
}
};
/**
* Get the ripple color
*/
Ripples.prototype.getRipplesColor = function($element) {
var color = $element.data("ripple-color") ? $element.data("ripple-color") : window.getComputedStyle($element[0]).color;
return color;
};
/**
* Verify if the client browser has transistion support
*/
Ripples.prototype.hasTransitionSupport = function() {
var thisBody = document.body || document.documentElement;
var thisStyle = thisBody.style;
var support = (
thisStyle.transition !== undefined ||
thisStyle.WebkitTransition !== undefined ||
thisStyle.MozTransition !== undefined ||
thisStyle.MsTransition !== undefined ||
thisStyle.OTransition !== undefined
);
return support;
};
/**
* Verify if the client is using a mobile device
*/
Ripples.prototype.isTouch = function() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
};
/**
* End the animation of the ripple
*/
Ripples.prototype.rippleEnd = function($ripple) {
$ripple.data("animating", "off");
if($ripple.data("mousedown") === "off") {
self.rippleOut($ripple);
}
};
/**
* Turn off the ripple effect
*/
Ripples.prototype.rippleOut = function($ripple) {
$ripple.off();
if(self.hasTransitionSupport()) {
$ripple.addClass("ripple-out");
} else {
$ripple.animate({"opacity": 0}, 100, function() {
$ripple.trigger("transitionend");
});
}
$ripple.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function() {
$ripple.remove();
});
};
/**
* Turn on the ripple effect
*/
Ripples.prototype.rippleOn = function($element, $ripple) {
var size = self.getNewSize($element, $ripple);
if(self.hasTransitionSupport()) {
$ripple
.css({
"-ms-transform": "scale(" + size + ")",
"-moz-transform": "scale(" + size + ")",
"-webkit-transform": "scale(" + size + ")",
"transform": "scale(" + size + ")"
})
.addClass("ripple-on")
.data("animating", "on")
.data("mousedown", "on");
} else {
$ripple.animate({
"width": Math.max($element.outerWidth(), $element.outerHeight()) * 2,
"height": Math.max($element.outerWidth(), $element.outerHeight()) * 2,
"margin-left": Math.max($element.outerWidth(), $element.outerHeight()) * (-1),
"margin-top": Math.max($element.outerWidth(), $element.outerHeight()) * (-1),
"opacity": 0.2
}, 500, function() {
$ripple.trigger("transitionend");
});
}
};
/**
* Create the jquery plugin function
*/
$.fn.ripples = function(options) {
return this.each(function() {
if(!$.data(this, "plugin_" + ripples)) {
$.data(this, "plugin_" + ripples, new Ripples(this, options));
}
});
};
})(jQuery, window, document);
......@@ -2,7 +2,7 @@
* @Author: 634665781 634665781@qq.com
* @Date: 2022-07-08 14:28:01
* @LastEditors: Please set LastEditors
* @LastEditTime: 2023-01-13 10:01:40
* @LastEditTime: 2023-08-22 11:36:58
* @FilePath: \CivWeb\src\pages\user\login\index.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -34,6 +34,8 @@ import WeixinLogin from './template/project/weixin';
import PanoramaLogin from './template/panorama';
import JiangXi from './template/project/jiangxi';
import Queshan from './template/project/queshan';
import PiZhouLogin from './template/project/pizhou';
import { AppInitState } from '../../../render';
const LoginTemplate = {
'新春.html': baseLoginNewYear,
......@@ -64,6 +66,7 @@ const LoginTemplate = {
'项目 - 江西.html': JiangXi,
'项目 - 长水机场.html': ChangShuiJiChang,
'项目 - 确山.html': Queshan,
'项目 - 邳州.html': PiZhouLogin,
default: BaseLogin,
};
/* eslint-disable */
......@@ -76,7 +79,6 @@ export default (props) => {
}, []);
if(Object.keys(window.globalConfig || {}).length === 0) return null;
let template = window.globalConfig && window.globalConfig.loginTemplate;
let arr =template.split('|')
let loginParams=[]
if(arr.length>1){
......
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
/*
* 功能名称: 邳州登录页
* 功能路径:
* 功能参数:
*/
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import $ from 'jquery';
import { Modal, Popover } from 'antd';
import QRCode from 'qrcode.react';
import { Helmet, HelmetProvider } from 'react-helmet-async';
import { connect } from 'react-redux';
import { useHistory, withRouter } from '@wisdom-utils/runtime';
import { actionCreators } from '@/containers/App/store';
import classnames from 'classnames';
import moment from 'moment';
import QueueAnim from 'rc-queue-anim';
import defaultSetting from '../../../../../../../config/defaultSetting';
import LoginAction from '../../../login';
import styles from './index.less';
import Account from '../../../js/useAccount';
import { defaultApp } from '../../../../../../micro';
import logo from './images/logo.png';
import qrcodePng from './images/1.png';
const Cripples = require('@/assets/js/ripples/jquery.ripples');
const PopOvercontent = () => {
const qrcodes = window.globalConfig && window.globalConfig.qrcode;
if (qrcodes) {
return <QRCode value={qrcodes} />;
}
return <span>手持APP下载未配置</span>;
};
const Login = forwardRef((props, _ref) => {
const sliVerify = useRef();
const loginFormRef = useRef();
const formRef = useRef(null);
const [status, setStatus] = useState('normal');
const [show, setShow] = useState(false);
const [autoLogin, setAutoLogin] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [type, setType] = useState('Account');
const [visible, setVisible] = useState(false);
const history = useHistory();
const [action, setAction] = useState(() => new LoginAction(Object.assign({}, props, { history }), setVisible, false));
const [dateObj, setDateObj] = useState({});
const handleSubmit = values => {
/* eslint-disable */
action &&
(type === 'Account'
? action.loginHandler(values.userName, values.password, null, autoLogin, sliVerify)
: type === 'Mobile'
? action.phoneLoginFormHandler(values.mobile, values.captcha)
: null);
setSubmitting(true);
props.updateCurrentIndex && props.updateCurrentIndex(-1);
};
useEffect(() => {
action &&
action.events.on('loginSuccess', event => {
setSubmitting(false);
props.updateCurrentIndex && props.updateCurrentIndex(0);
props.history.push(`/?client=${props.global.client}`);
defaultApp();
});
action &&
action.events.on('loginError', event => {
setVisible(false);
setSubmitting(false);
});
action &&
action.events.on('loginVisible', status => {
setVisible(status);
});
return () => {
action && action.events && action.events.removeAllListeners('loginSuccess');
action && action.events && action.events.removeAllListeners('loginError');
action && action.events && action.events.removeAllListeners('loginVisible');
};
}, [props.loginMode]);
useEffect(() => {
setSubmitting(false);
}, [visible]);
const renderPlatform = () => {
const template = props.global.loginTemplate;
const params = {
fromRef: formRef,
type,
setType,
status,
submitting,
autoLogin,
setAutoLogin,
action,
onSubmit: handleSubmit,
loginMode: props.loginMode,
updateLoginMode: props.updateLoginMode,
welcome: null,
};
return <Account {...params} />;
};
/* eslint-disable */
const handleWeek = () => {
const weekOfDay = Number(moment().format('E'));
let weekDayName = '';
switch (weekOfDay) {
case 1:
weekDayName = '周一';
break;
case 2:
weekDayName = '周二';
break;
case 3:
weekDayName = '周三';
break;
case 4:
weekDayName = '周四';
break;
case 5:
weekDayName = '周五';
break;
case 6:
weekDayName = '周六';
break;
case 7:
weekDayName = '周日';
break;
default:
weekDayName = '';
}
return weekDayName;
};
const onShow = () => {
if (!show) {
setShow(true);
}
};
useEffect(() => {
setTimeout(() => {
onShow();
}, 300);
setTimeout(() => {
$('.CarouselRipples').ripples({
resolution: 800,
dropRadius: 20, //px
perturbance: 2,
});
}, 1000);
}, []);
useEffect(() => {
return () => {};
}, [show]);
useEffect(() => {
const timer = setInterval(() => {
setDateObj({
curTime: moment().format('HH:mm:ss'),
week: handleWeek(),
date: moment().format('YYYY/MM/DD'),
});
}, 1000);
return () => {
clearInterval(timer);
};
}, []);
return (
<HelmetProvider>
<Helmet>
<title>{props.global.title || defaultSetting.title}</title>
<meta name="description" content={props.global.title || defaultSetting.title} />
</Helmet>
<div className={classnames(styles.pizhouLogin, 'pizhouLogin')} onClick={onShow}>
{show ? (
<div className={classnames(styles['wrapper'])}>
<QueueAnim type="scale" duration={1000}>
<div key={'innerwrapper'} className={classnames(styles['inner-wrapper'])}>
<div className={styles['inner-center']}>
<div className={styles['welcome-title']}>汇一脉水 润邳州城 筑供水梦</div>
<div className={classnames(styles['inner-bg'], styles['login-part'])} ref={loginFormRef}>
{renderPlatform()}
</div>
</div>
<Popover
content={PopOvercontent}
title="扫码下载APP"
placement="right"
overlayClassName={'popover-style'}
>
<img src={qrcodePng} alt="APP" className={styles['qrcode-box']} />
</Popover>
</div>
</QueueAnim>
<div key="loginheader" className={classnames(styles['login-header'])}>
<QueueAnim type="left">
<div key="logintitle" className={styles['left-title']}>
<div>
<img src={logo} alt="logo" />
</div>
<div className={styles['cn-title']}>{props.global.title || defaultSetting.title}</div>
</div>
</QueueAnim>
<QueueAnim type="right">
<div key="logintime" className={styles['right-timebox']}>
<div className={styles['curr-time']}>{dateObj.curTime}</div>
<div className={styles['curr-week-date']}>
<div className={styles['curr-week']}>{dateObj.week}</div>
<div className={styles['curr-date']}>{dateObj.date}</div>
</div>
</div>
</QueueAnim>
</div>
</div>
) : null}
<div className={classnames(styles.CarouselRipples, 'CarouselRipples')} data-ripple="ripple" />
<Modal centered visible={visible} width={340} footer={null} closable={false} bodyStyle={{ padding: '15px' }}>
<div ref={sliVerify} />
</Modal>
</div>
</HelmetProvider>
);
});
const mapStateToProps = state => ({
global: state.getIn(['global', 'globalConfig']),
loginMode: state.getIn(['global', 'loginMode']),
});
const mapDispatchToProps = dispatch => ({
updateConfig(config) {
dispatch(actionCreators.getConfig(config));
},
createContext(data) {
dispatch(actionCreators.createContext(data));
},
updateLoginMode(mode) {
dispatch(actionCreators.changeLoginMode(mode));
},
updateCurrentIndex(index) {
dispatch(actionCreators.updateCurrentIndex(index));
},
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(withRouter(Login));
@font-face {
font-family: PingFang SC;
src: url('@/assets/fonts/PingFang.ttf');
}
.pizhouLogin {
width: 100%;
height: 100%;
background: url('./images/邳州背景.jpg') no-repeat center center;
position: relative;
min-height: 7.0rem;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
.caseHide {
display: none !important;
}
.inner-bg {
width: 100%;
height: 100%;
&>div {
width: 80%;
margin: 0 10% 10%;
}
}
.inner-wrapper {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
top: 250px;
left: calc(50% - 240px);
z-index: 50;
}
.inner-bg .title {
font-size: 27px;
font-weight: bold;
color: rgba(255, 255, 255, 1);
letter-spacing: 2px;
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.inner-center {
position: relative;
width: 537px;
height: 345px;
border: 1px solid #FDFDFD;
box-shadow: 0px 6px 18px 0px rgba(25, 61, 79, 0.35);
border-radius: 15px;
z-index: 2;
backdrop-filter: blur(6px);
}
.welcome-title {
height: 100px;
border-radius: 8px 8px 0px 0px;
text-align: center;
line-height: 100px;
font-size: 31px;
font-weight: bold;
color: #008EFE;
// text-shadow: 0px 4px 5px #A3AFC7;
// -webkit-text-stroke:0.5px #FFFFFF;
text-shadow: #FFFFFF 1.5px 0 0, #FFFFFF 0 1.5px 0, #FFFFFF -1.5px 0 0, #FFFFFF 0 -1.5px 0;
font-family: 宋体;
}
.formgroup2 {
display: flex;
align-items: center;
display: flex;
margin: 0px 5.5%;
margin-bottom: 10%;
align-items: center;
margin-bottom: 40px;
}
.APPcodeBox {
width: 100%;
display: flex;
flex-flow: column;
align-items: center;
cursor: pointer;
position: relative;
}
.APPCtext {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #000000;
line-height: 30px;
opacity: 0.75;
}
.login-header {
box-sizing: border-box;
width: 100%;
position: absolute;
top: 0;
left: 0;
height: 82px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 22px;
z-index: 50;
// border-bottom: 1px solid rgba(255, 255, 255, 0.12);
.left-title {
display: flex;
justify-content: flex-start;
align-items: center;
img {
width: 166px;
height: 55px;
}
.cn-title {
font-size: 44px;
font-family: PingFang SC;
font-weight: 800;
color: #FFFFFF;
line-height: 55px;
text-shadow: 0px 1px 10px #A3AFC7;
line-height: 1;
margin-left: 10px;
}
}
.right-timebox {
display: flex;
justify-content: center;
align-items: center;
height: 60px;
.curr-time {
width: 140px;
font-size: 34px;
font-family: Microsoft YaHei;
font-weight: 300;
color: #333;
text-align: right;
}
.curr-week-date {
margin-left: 10px;
.curr-week {
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #333;
}
.curr-date {
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #333;
}
}
}
}
.copyright {
position: absolute;
bottom: 7%;
width: 100%;
margin: 0 auto;
font-size: 12px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #F1F6FD;
text-align: center;
}
.qrcode-box {
position: absolute;
bottom: 0;
right: -23px;
width: 23px;
height: 23px;
background: #FFFFFF;
opacity: 0.8;
cursor: pointer;
}
}
& :global {
.pizhouLogin {
.panda-console-base-btn {
border-radius: 20px;
}
}
.popover-style {
.@{ant-prefix}-popover-inner-content {
display: flex;
justify-content: center;
align-items: center;
}
.@{ant-prefix}-popover-title {
display: flex;
justify-content: center;
align-items: center;
}
}
}
:global {
.popover-style {
.@{ant-prefix}-popover-inner-content {
display: flex;
justify-content: center;
align-items: center;
}
.@{ant-prefix}-popover-title {
display: flex;
justify-content: center;
align-items: center;
}
}
}
.CarouselRipples {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
& :global {
.CarouselRipples:before {
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment