Isotope
씨발 존 나 깔쌈한 라이브러리…
존네좋군
Filter 와 Sort 기능을 갖춘 반응형 레이아웃 js 플러그인 – isotope.js
http://jsfiddle.net/tahirahmed/ku2kyfow/
http://imagesloaded.desandro.com/
http://purecss.io/layouts/side-menu/#
https://codepen.io/hanlinC/pen/dJwil
"use strict";
var resolve = {
delay: function($q, $timeout) {
var delay = $q.defer();
return $timeout(delay.resolve, 0, !1), delay.promise
}
};
angular.module("dropApp", ["ngCookies", "ngResource", "ngRoute", "ngSanitize", "ngProgress", "timer", "infinite-scroll"]).config(["$compileProvider", function($compileProvider) {
$compileProvider.debugInfoEnabled(!1)
}]).config(["$routeProvider", "$locationProvider", "$httpProvider", function($routeProvider, $locationProvider, $httpProvider) {
$routeProvider.when("/", {
templateUrl: "views/main.html",
controller: "MainCtrl",
resolve: resolve
}).when("/all", {
templateUrl: "views/all.html",
controller: "AllCtrl",
resolve: resolve
}).when("/create", {
templateUrl: "views/create.html",
controller: "CreateCtrl",
resolve: resolve
}).when("/featured", {
templateUrl: "views/drop.html",
controller: "DropCtrl",
reloadOnSearch: !1,
resolve: resolve
}).when("/drop/:id", {
templateUrl: "views/drop.html",
controller: "DropCtrl",
reloadOnSearch: !1,
resolve: resolve
}).otherwise({
redirectTo: "/"
}), $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
var param = function(obj) {
var name, value, fullSubName, subName, subValue, innerObj, i, query = "";
for (name in obj)
if (value = obj[name], value instanceof Array)
for (i = 0; i < value.length; ++i) subValue = value[i], fullSubName = name + "[" + i + "]", innerObj = {}, innerObj[fullSubName] = subValue, query += param(innerObj) + "&";
else if (value instanceof Object)
for (subName in value) subValue = value[subName], fullSubName = name + "[" + subName + "]", innerObj = {}, innerObj[fullSubName] = subValue, query += param(innerObj) + "&";
else void 0 !== value && null !== value && (query += encodeURIComponent(name) + "=" + encodeURIComponent(value) + "&");
return query.length ? query.substr(0, query.length - 1) : query
};
$httpProvider.defaults.transformRequest = [function(data) {
return angular.isObject(data) && "[object File]" !== String(data) ? param(data) : data
}]
}]).run(["$rootScope", "$location", "$route", "$timeout", "Spotify", "ngProgress", function($rootScope, $location, $route, $timeout, Spotify, ngProgress) {
var token_key = "access_token=",
token_index = window.location.href.indexOf(token_key);
if (token_index > -1) {
var token = window.location.href.substr(token_index + token_key.length).split("&")[0];
Spotify.set_access_token(token), $location.path("/create")
}
var oldLocation = "";
$rootScope.$on("$routeChangeStart", function(angularEvent, next) {
$rootScope.view_class = "view-" + $location.path().substr(1), ngProgress.reset();
var isForwards = !0;
if (next && next.$$route) {
var newLocation = next.$$route.originalPath;
oldLocation !== newLocation && -1 !== oldLocation.indexOf(newLocation) && (isForwards = !1), oldLocation = newLocation
}
}), ngProgress.color("#16e58a")
}]), angular.module("dropApp").service("Image", function() {
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null
}
this.grayscale = function(pixels) {
for (var d = pixels.data, i = 0; i < d.length; i += 4) {
var r = d[i],
g = d[i + 1],
b = d[i + 2],
v = .2126 * r + .7152 * g + .0722 * b;
d[i] = d[i + 1] = d[i + 2] = v
}
return pixels
}, this.duotone = function(img, tone1, tone2) {
var gradient = this.gradientMap(tone1, tone2);
img = this.grayscale(img);
for (var d = img.data, i = 0; i < d.length; i += 4) d[i] = gradient[4 * d[i]], d[i + 1] = gradient[4 * d[i + 1] + 1], d[i + 2] = gradient[4 * d[i + 2] + 2];
return img
}, this.gradientMap = function(tone1, tone2) {
for (var rgb1 = hexToRgb(tone1), rgb2 = hexToRgb(tone2), gradient = [], i = 0; 1024 > i; i += 4) gradient[i] = ((256 - i / 4) * rgb1.r + i / 4 * rgb2.r) / 256, gradient[i + 1] = ((256 - i / 4) * rgb1.g + i / 4 * rgb2.g) / 256, gradient[i + 2] = ((256 - i / 4) * rgb1.b + i / 4 * rgb2.b) / 256, gradient[i + 3] = 255;
return gradient
}, this.flipImage = function(input) {
for (var tempCtx = document.createElement("canvas").getContext("2d"), output = tempCtx.createImageData(input.width, input.height), w = input.width, h = input.height, inputData = input.data, outputData = output.data, y = 1; h - 1 > y; y += 1)
for (var x = 1; w - 1 > x; x += 1)
for (var i = 4 * (y * w + x), flip = 4 * (y * w + (w - x)), c = 0; 4 > c; c += 1) outputData[i + c] = inputData[flip + c];
return output
}
}), angular.module("dropApp").service("BlockFormatter", function() {
this.format_media = function(media, parent) {
var block = {};
switch (block.type = "media", block.media_type = media.drop_type, block.title = media.title ? media.title : "Check out this exclusive " + media.drop_type + "!", block.description = media.description ? media.description : "Love " + parent.name + "? Don't miss this!", block.url = "/drop/" + media.artist_id + "?media=" + media.id, media.drop_type) {
case "video":
block.call_to_action = "watch now";
break;
case "gallery":
block.call_to_action = "gallery";
break;
case "playlist":
block.call_to_action = "follow"
}
return block
}, this.format_drop = function(data) {
var block = {};
return block.type = "drop", block.title = data.name, block.image = data.files[data.featured_image_id].url, block.url = "/drop/" + data.id, block.call_to_action = "view drop", block
}
}), angular.module("dropApp").service("Spotify", ["$http", "$location", "$window", "$q", function($http, $location, $window, $q) {
var access_token, user, client_id = "d8c2bf8b2663462e93004f0575f821e8",
redirect_uri = "http://spotify-thedrop.com/",
authorization_url = "https://accounts.spotify.com/authorize",
api_base = "https://api.spotify.com/v1";
this.set_access_token = function(token) {
access_token = token
}, this.get_access_token = function() {
return access_token
}, this.authenticate = function() {
var url_string = authorization_url + "?response_type=token&client_id=" + client_id + "&redirect_uri=" + redirect_uri;
$window.location.href = url_string
}, this.get_user = function() {
var deferred = $q.defer();
return user ? deferred.resolve(user) : $http({
url: api_base + "/me",
headers: {
Authorization: "Bearer " + access_token
}
}).success(function(response) {
deferred.resolve(user = response)
}).error(function(response) {
deferred.reject()
}), deferred.promise
}
}]), angular.module("dropApp").service("Api", ["$http", "$q", function($http, $q) {
function card_shim(raw) {
for (var i = 0; i < raw.length; i++) raw[i].type = "card";
return raw
}
function drop_shim(data) {
function get_image_url(id) {
return data.files[id] ? data.files[id].url : null
}
function get_image_content_url(i, id) {
return data.content[i].files[id] ? data.content[i].files[id].url : null
}
var now = (new Date).getTime();
data.type = "drop", data.featured_image = get_image_url(data.featured_image_id), data.header_image = get_image_url(data.header_image_id), data.dropped_at = moment(data.reveal_date).fromNow(), data.single_uri = "spotify:track:" + data.single, data.dropped = moment(data.release_date).isBefore(now), "i" === data.dropped_at.charAt(0) && "n" === data.dropped_at.charAt(1) ? data.dropped_at = "Dropping " + data.dropped_at : data.dropped_at = "Dropped " + data.dropped_at, data.card_images = [];
var card_image_1 = get_image_url(data.artist_image1_id),
card_image_2 = get_image_url(data.artist_image2_id),
card_image_3 = get_image_url(data.artist_image3_id);
if (card_image_1 && data.card_images.push(card_image_1), card_image_2 && data.card_images.push(card_image_2), card_image_3 && data.card_images.push(card_image_3), data.content)
for (var i = 0; i < data.content.length; i++) {
var content = data.content[i];
content.item_index = i, content.type = "media", content.media_type = content.content_type, content.media_index = i, content.featured_image = get_image_content_url(i, content.featured_image_id), content.dropped_at = moment(content.release_date).fromNow(), content.drop_id = data.id, content.locked = moment(content.release_date).isAfter(now)
}
return data
}
var drops, cards, ads, base = "http://api.spotify-thedrop.com";
this.get_drop = function(id) {
var deferred = $q.defer();
return $http.get(base + "/drop/" + id + "/").success(function(response) {
deferred.resolve(drop_shim(response))
}), deferred.promise
}, this.get_all_drops = function() {
var deferred = $q.defer();
return drops ? deferred.resolve(drops) : $http.get(base + "/drops").success(function(response) {
for (var i = 0; i < response.length; i++) response[i] = drop_shim(response[i]);
deferred.resolve(drops = response)
}), deferred.promise
}, this.get_featured = function() {
var deferred = $q.defer();
return $http.get(base + "/drops?featured=1").success(function(response) {
deferred.resolve(drop_shim(response[response.length - 1]))
}), deferred.promise
}, this.get_cards = function() {
var deferred = $q.defer();
return cards ? deferred.resolve(cards) : $http.get(base + "/cards?featured=1/").success(function(response) {
cards = card_shim(response), deferred.resolve(cards)
}), deferred.promise
}, this.get_single_card = function(route) {
var deferred = $q.defer();
return cards ? deferred.resolve(cards) : $http.get(route).success(function(response) {
deferred.resolve(response)
}), deferred.promise
}, this.get_ad = function() {
var deferred = $q.defer(),
addArray = [];
return ads ? deferred.resolve(ads) : $http.get(base + "/brands").success(function(response) {
if ("object" == typeof response) {
var adObj = {
type: "ad",
image: "images/mc-ad-blue.jpg",
description: "It takes two to tango with a 20 piece.",
content_url: ""
},
add_timestamp = function(url) {
return url ? String(url).replace("[timestamp]", (new Date).getTime()) : ""
},
setObj = function(responseObj) {
adObj.image = responseObj.files[responseObj.image_id].url, adObj.description = responseObj.title, adObj.content_url = responseObj.content_url, adObj.ad_url = add_timestamp(responseObj.ad_url), adObj.ad_text_url = add_timestamp(responseObj.ad_text_url), adObj.ad_text_url || (adObj.ad_text_url = adObj.ad_url), adObj.tracking_pixel_url = add_timestamp(responseObj.tracking_pixel_url), addArray.push(angular.copy(adObj))
};
response = response.sort(function(a, b) {
return a.id == b.id ? 0 : a.id > b.id ? -1 : 1
});
for (var i = 0; i < response.length; i++) setObj(response[i])
}
deferred.resolve(addArray)
}), deferred.promise
}, this.save_card = function(card_data, image) {
var deferred = $q.defer(),
data = {
drop_id: card_data.drop.id,
creator_id: card_data.user.id,
image: image
};
return $http({
method: "POST",
url: base + "/card/",
data: data,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
}).success(function(response, status, headers, config) {
deferred.resolve("" + base + headers().location)
}), deferred.promise
}
}]), angular.module("dropApp").controller("MainCtrl", ["$scope", "$timeout", "$q", "$location", "Api", "ngProgress", function($scope, $timeout, $q, $location, Api, ngProgress) {
$scope.items = [];
var featured = 0;
$scope.selectFeature = function(setFeature) {
featured = setFeature
}, $scope.isFeatured = function(checkFeature) {
return featured === checkFeature
}, this.load_featured_drop = function() {
Api.get_featured().then(function(response) {
ngProgress.complete(), $scope.featured = response, $scope.$on("imageLoaded", function() {
$timeout(function() {
$scope.backgroundLoaded = !0, $scope.firstLoad = !0;
media: for (var i = $scope.featured.content.length; i--; i >= 0)
if (!$scope.featured.content[i].locked) {
$scope.items.unshift($scope.featured.content[i]), $scope.items[0].name = $scope.featured.name, $timeout(function() {
$scope.firstLoad = !1
}, 1e3);
break media
}
$timeout(function() {
Api.get_ad().then(function(response) {
$scope.items.push(response[0])
}), $scope.ready = !0
}, 1600)
}, 700)
})
})
};
var random_drops, ad_blocks, counter = 0;
$scope.load_random_assets = function() {
ngProgress.start(), $q.all([Api.get_all_drops(), Api.get_ad()]).then(function(response) {
ngProgress.complete(), random_drops = angular.copy(response[0]), ad_blocks = angular.copy(response[1]), $scope.add_random_assets()
})
}, $scope.add_random_assets = function() {
if (counter++, $scope.ready = !1, !random_drops || !random_drops.length) return $scope.load_random_assets(), !1;
for (var random_items = [], random_index = Math.floor(Math.random() * (random_drops.length - 9)), random_range = random_drops.splice(random_index, 10), i = 0; i < random_range.length; i++) {
var selected_drop = random_range[i],
selected_drop_media_length = selected_drop.content ? selected_drop.content.length : 0,
selected_random_index = Math.floor(Math.random() * (selected_drop_media_length + 1));
selected_random_index === selected_drop_media_length ? random_items.push(selected_drop) : (selected_drop.content[selected_random_index].name = selected_drop.name, random_items.push(selected_drop.content[selected_random_index]))
}
if (counter % 2 === 0) {
var shuffle = function(a) {
var j, x, i;
for (i = a.length; i; i -= 1) j = Math.floor(Math.random() * i), x = a[i - 1], a[i - 1] = a[j], a[j] = x;
return a
};
random_items = shuffle(random_items);
var shuffle_merge = function(source, target) {
for (var sourceInds = [], result = [], i = 0; i < source.length; i++) sourceInds.push(i);
sourceInds = shuffle(shuffle(sourceInds)).slice(0, target.length).sort();
for (var currentInd = sourceInds.shift(), i = 0; i < source.length; i++) i == currentInd && (result.push(target.pop()), currentInd = sourceInds.shift()), result.push(source[i]);
return result
};
random_items = shuffle_merge(random_items, ad_blocks)
}
$scope.items = $scope.items.concat(random_items), $scope.ready = !0
}, this.load_featured_drop()
}]), angular.module("dropApp").controller("HeaderCtrl", ["$scope", "$location", function($scope, $location) {
$scope.links = [{
title: "FEATURED",
path: "/drop/featured",
color: "#fae62d"
}, {
title: "ALL",
path: "/all",
color: "#9bf0e1"
}], $scope.timestamp = (new Date).getTime(), $scope.visisble = !0, $scope.toggleShare = function(toggle) {
var $shareButtons = $(".share-button"),
buttonsNum = $shareButtons.length,
buttonsMid = buttonsNum / 3,
spacing = 90;
$scope.visisble && "close" !== toggle ? ($shareButtons.each(function(i) {
var $cur = $(this),
pos = i - 1,
dist = Math.abs(pos);
$cur.css({
zIndex: buttonsMid - dist
}), TweenMax.to($cur, 1.1 * dist, {
x: pos * spacing,
y: 90,
scale: .95,
width: 60,
height: 60,
ease: Elastic.easeOut,
easeParams: [1.01, .5]
}), TweenMax.to($cur, .8, {
delay: .2 * dist - .1,
scale: .95,
width: 60,
height: 60,
ease: Elastic.easeOut,
easeParams: [1.1, .6]
}), TweenMax.fromTo($cur.children(".share-icon"), .2, {
scale: 0
}, {
delay: .2 * dist - .1,
scale: 1,
ease: Quad.easeInOut
})
}), $scope.visisble = !$scope.visisble) : "close" === toggle ? ($shareButtons.each(function(i) {
var $cur = $(this),
pos = i,
dist = Math.abs(pos);
$cur.css({
zIndex: dist
}), TweenMax.to($cur, .4 + .1 * (buttonsMid - dist), {
x: 0,
y: 0,
scale: 0,
width: 32,
height: 32,
ease: Quad.easeInOut
}), TweenMax.to($cur.children(".share-icon"), .2, {
scale: 0,
ease: Quad.easeIn
})
}), $scope.visisble = !0) : ($shareButtons.each(function(i) {
var $cur = $(this),
pos = i,
dist = Math.abs(pos);
$cur.css({
zIndex: dist
}), TweenMax.to($cur, .4 + .1 * (buttonsMid - dist), {
x: 0,
y: 0,
scale: 0,
width: 32,
height: 32,
ease: Quad.easeInOut
}), TweenMax.to($cur.children(".share-icon"), .2, {
scale: 0,
ease: Quad.easeIn
})
}), $scope.visisble = !0)
}, $scope.$on("$locationChangeSuccess", function(e, next) {
$scope.path = $location.path(), $scope.toggleShare("close")
}), $scope.path = $location.path()
}]), angular.module("dropApp").controller("FeaturedCtrl", ["$scope", "$timeout", "$q", "$location", "Api", "ngProgress", function($scope, $timeout, $q, $location, Api, ngProgress) {
$scope.items = [], this.load_featured_drop = function() {
ngProgress.start(), Api.get_featured().then(function(response) {
ngProgress.complete(), $timeout(function() {
$scope.featured = response;
media: for (var i = $scope.quantity; i--; i >= 0)
if (!$scope.featured.content[i].locked) {
$scope.items.unshift($scope.featured.content[i]);
break media
}
Api.get_ad().then(function(response) {
$scope.items.push(response[0])
}), $scope.ready = !0
}, 500)
})
};
var random_drops, random_cards;
$scope.load_random_assets = function() {
ngProgress.start(), $q.all([Api.get_all_drops(), Api.get_cards()]).then(function(response) {
ngProgress.complete(), random_drops = angular.copy(response[0]), random_cards = angular.copy(response[1]), $scope.add_random_assets()
})
}, $scope.add_random_assets = function() {
if ($scope.ready = !1, !random_drops || !random_drops.length) return $scope.load_random_assets(), !1;
for (var random_items = [], random_index = Math.floor(Math.random() * (random_drops.length - 4)), random_range = random_drops.splice(random_index, 5), i = 0; i < random_range.length; i++) {
var selected_drop = random_range[i],
selected_drop_media_length = selected_drop.content ? selected_drop.content.length : 0,
selected_random_index = Math.floor(Math.random() * (selected_drop_media_length + 1));
selected_random_index === selected_drop_media_length ? random_items.push(selected_drop) : random_items.push(selected_drop.content[selected_random_index])
}
if (random_cards.length) {
var random_card_index = Math.floor(Math.random() * (random_items.length - 1));
random_items.splice(random_card_index, 0, random_cards.pop())
}
$scope.items = $scope.items.concat(random_items), $scope.ready = !0
}, this.load_featured_drop()
}]), angular.module("dropApp").controller("AllCtrl", ["$scope", "$timeout", "Api", "ngProgress", function($scope, $timeout, Api, ngProgress) {
$scope.limit = 6, $scope.limit_per_page = 6, $scope.visible = !1, this.load_drops = function() {
ngProgress.start(), Api.get_all_drops().then(function(response) {
ngProgress.complete(), $timeout(function() {
$scope.drops = response.reverse(), $scope.visible = !0
}, 500)
})
}, $scope.background = "/images/auth/all.jpg", $scope.next_page = function() {
$scope.limit = $scope.limit + $scope.limit_per_page
}, this.load_drops()
}]), angular.module("dropApp").controller("CreateCtrl", ["$scope", "$q", "$timeout", "Api", "Spotify", "ngProgress", function($scope, $q, $timeout, Api, Spotify, ngProgress) {
$scope.card = {}, $scope.imageUrl = "spotify-thedrop.com", $scope.auth_blocked = !Spotify.get_access_token(), $scope.auth_blocked || (ngProgress.start(), $scope.auth_blocked = !1, $q.all([Spotify.get_user(), Api.get_all_drops()]).then(function(response) {
ngProgress.complete(), $scope.card.drop = response[1][0], $scope.card.track = $scope.card.drop.song_list[0], $scope.$watch("card.drop", function() {
$scope.card.track = $scope.card.drop.song_list[0], $scope.randomize()
}, !0), $timeout(function() {
$timeout(function() {
$scope.drops = response[1], $scope.card.user = response[0]
}, 500)
}, 500)
}, function(response) {
ngProgress.complete(), $scope.auth_blocked = !0, console.log("error")
})), $scope.authenticate = function() {
Spotify.authenticate()
}, $scope.themes = [{
text: "#F59B23",
foreground: "#AF2896",
background: "#503750",
value: 0
}, {
text: "#2D46B9",
foreground: "#CDF564",
background: "#FF4632",
value: 1
}, {
text: "#F573A0",
foreground: "#9BF0E1",
background: "#503750",
value: 2
}, {
text: "#000000",
foreground: "#FAE62D",
background: "#F037A5",
value: 3
}], $scope.background = "/images/auth/auth.png", $scope.bursts = ["/images/bursts/triangle.png", "/images/bursts/rectangle.png", "/images/bursts/circle.png"], $scope.select_type = function(type) {
$scope.card.type = type
}, $scope.select_burst = function(burst) {
$scope.card.burst = burst
}, $scope.select_image = function(image) {
$scope.card.image = image
}, $scope.select_theme = function(theme) {
$scope.card.theme = theme
}, $scope.scale_background = function() {
$scope.card.scale = !$scope.card.scale
}, $scope.flip_background = function() {
$scope.card.flip = !$scope.card.flip
}, $scope.rotate_background = function() {
$scope.card.rotation = $scope.card.rotation < 3 ? ++$scope.card.rotation : 0
}, $scope.drag_background = function() {
$scope.drag = !$scope.drag
}, $scope.randomize = function() {
$scope.card.type = Math.random() >= .5 ? "burst" : "image", $scope.card.image = $scope.card.drop ? $scope.card.drop.card_images[Math.floor(Math.random() * $scope.card.drop.card_images.length)] : "", $scope.card.burst = $scope.bursts[Math.floor(Math.random() * $scope.bursts.length)], $scope.card.theme = $scope.themes[Math.floor(Math.random() * $scope.themes.length)], $scope.card.rotation = Math.floor(3 * Math.random()), $scope.card.flip = Math.random() >= .5, $scope.card.scale = Math.random() >= .5
}
}]), angular.module("dropApp").controller("DropCtrl", ["$scope", "$routeParams", "$timeout", "$location", "Api", function($scope, $routeParams, $timeout, $location, Api) {
function load_drop() {
isNaN($routeParams.id) ? Api.get_featured().then(render_drop) : Api.get_drop($routeParams.id).then(render_drop)
}
function render_drop(drop) {
"i" === drop.dropped_at.charAt(0) || "i" === drop.dropped_at.charAt(5) ? drop.dropped = !1 : drop.dropped = !0, $scope.drop = drop, $scope.drop.album_uri = "spotify:album:" + $scope.drop.album_uri, $scope.drop.endpoint = "http://open.spotify.com/" + $scope.drop.album_uri.replace("spotify:", "").replace(/:/g, "/"), $scope.spotify = "/images/spotify.png";
for (var i = $scope.drop.content.length; i--; i >= 0) $scope.drop.content[i].locked ? $scope.drop.content.splice($scope.drop.content.length, 0, $scope.drop.content.splice($scope.drop.content[i], 1)[0]) : $scope.items.unshift($scope.drop.content[i]);
Api.get_ad().then(function(response) {
$scope.items.push(response[0])
}), $timeout(function() {
$scope.$broadcast("timer-start")
}, 400), $scope.$on("$routeUpdate", $scope.on_route_update), $scope.on_route_update()
}
$scope.items = [], $scope.clickWatch = 0, $scope.set_media = function(index) {
$location.search("media", index), $scope.clickWatch++
}, $scope.clear_media = function() {
$(".youtube-player iframe").remove(), $location.url($location.path())
}, $scope.on_route_update = function() {
$scope.media_index = $location.search().media, $scope.media = $scope.drop.content[$scope.media_index]
}, load_drop()
}]), angular.module("dropApp").directive("audioPlayer", function() {
return {
scope: {
uri: "=audioPlayerUri",
albumUri: "=audioPlayerAlbumUri",
revealDate: "=audioPlayerRevealDate"
},
link: function(scope, element) {
var base = '<iframe src="https://embed.spotify.com/?uri={uri}" width="100%" height="100%" frameborder="0" allowtransparency="true"></iframe>';
scope.afterRelease = !1, scope.$watch("revealDate", function() {
if (scope.revealDate) {
var revealDate = moment(scope.revealDate),
currentDate = moment(),
diff = currentDate.diff(revealDate, "seconds");
scope.afterRelease = diff > 0 ? !0 : !1
}
}), scope.$watch("albumUri", function() {
scope.afterRelease && (scope.albumUri ? (element.html(base.replace("{uri}", scope.albumUri)), setTimeout(function() {
element.addClass("activated album")
}, 500)) : element.removeClass("activated"))
}), scope.$watch("uri", function() {
scope.afterRelease || (scope.uri ? (element.html(base.replace("{uri}", scope.uri)), setTimeout(function() {
element.addClass("activated")
}, 500)) : element.removeClass("activated"))
})
}
}
}), angular.module("dropApp").directive("slider", function() {
return {
scope: {
options: "=sliderOptions",
switcher: "=clickWatch"
},
templateUrl: "/partials/slider.html",
transclude: !0,
controller: ["$scope", function($scope) {
this.initialize = function() {
$scope.init()
}
}],
link: function(scope, element) {
var defaults = {
grabCursor: !0,
pagination: $(element).find(".swiper-pagination"),
nextButton: $(element).find(".swiper-button-next"),
prevButton: $(element).find(".swiper-button-prev"),
paginationClickable: !0,
preloadImages: !1,
lazyLoading: !0
};
scope.$watch("switcher", function() {
$(".swiper-slide .swiper-lazy").each(function(idx) {
self = $(this), $(this).attr("src") && (self.removeClass("swiper-lazy-loaded"), self.removeAttr("src"), setTimeout(function() {
s.lazy.load()
}))
})
});
var s, options = angular.extend(defaults, scope.options);
scope.init = function() {
s && s.destroy(), setTimeout(function() {
s = new Swiper(element[0], options)
}, 100)
}
}
}
}), angular.module("dropApp").directive("sliderItem", function() {
return {
require: "^slider",
link: function(scope, element, attrs, sliderCtrl) {
scope.$last && sliderCtrl.initialize()
}
}
}), angular.module("dropApp").directive("mediaCircle", function() {
return {
templateUrl: "partials/media-circle.html",
link: function(scope, element) {
var r = 4 * Math.random() + 2.5,
t = .25 * Math.PI,
labelX = r + r * Math.cos(t),
labelY = r + r * Math.sin(t);
scope.circleStyle = {
width: 2 * r + "em",
height: 2 * r + "em"
}, scope.labelStyle = {
top: labelY + "em",
left: labelX + "em"
}, setTimeout(function() {
element.addClass("revealed")
}, 200 * scope.$index + 1500)
}
}
}), angular.module("dropApp").directive("imageLoader", function() {
return {
scope: {
imageLoaderSrc: "=imageLoaderSrc"
},
template: '<div class="image-loader-element" ng-style="backgroundImage"></div><div class="image-loader-progress"></div>',
link: function(scope, element, attrs) {
function loadImage() {
image = new Image, image.onload = onImageLoaded, image.src = scope.imageLoaderSrc, element.removeClass("image-loader-complete").addClass("image-loader-loading")
}
function onImageLoaded() {
void 0 !== attrs.backgroundImage && scope.$emit("imageLoaded"), element.removeClass("image-loader-loading").addClass("image-loader-complete").children().first().css("background-image", "url(" + scope.imageLoaderSrc + ")")
}
function onImageError() {
element.removeClass("image-loader-loading").removeClass("image-loader-complete")
}
var image;
scope.$watch("imageLoaderSrc", function(val) {
val ? setTimeout(function() {
loadImage()
}, 300) : onImageError()
})
}
}
}), angular.module("dropApp").directive("gallery", function() {
return {
scope: {
items: "=galleryItems"
},
templateUrl: "partials/gallery.html",
link: function(scope, element, attrs) {
scope.gallerySliderOptions = {
slidesPerView: 1,
pagination: ".swiper-pagination",
nextButton: ".swiper-button-next",
prevButton: ".swiper-button-prev",
paginationClickable: !0,
preloadImages: !1,
lazyLoading: !0,
loop: !0
}
}
}
}), angular.module("dropApp").directive("youtubePlayer", ["$sce", "$timeout", function($sce, $timeout) {
return {
scope: {
data: "=youtubePlayer"
},
templateUrl: "partials/videoplayer.html",
link: function(scope, element, attrs) {
var id, base = "http://www.youtube.com/embed/{id}?autoplay=1&showinfo=0&rel=0&autohide=1&showinfo=0&enablejsapi=1&playerapiid=ytplaye";
scope.visible = !1, scope.$watch("data", function() {
if (scope.data && scope.data.content) {
if (!scope.data.content.url) return void scope.stop();
id = scope.data.content.url.split("watch?v=")[1], $timeout(scope.play, 500)
} else scope.stop()
}), scope.play = function() {
scope.iframe_url = $sce.trustAsResourceUrl(base.replace("{id}", id)), scope.playing = !0
}, scope.stop = function() {
scope.iframe_url = $sce.trustAsResourceUrl("about:blank"), scope.playing = !1
}, window.uploadDone = function() {
scope.data && (scope.visible = !0, scope.$apply())
}
}
}
}]), angular.module("dropApp").directive("packery", function() {
return {
scope: !0,
controller: ["$scope", function($scope) {
this.initialize = function() {
$scope.init()
}
}],
link: function(scope, element, attrs) {
var p, defaults = {
itemSelector: ".block-item",
percentPosition: !0,
masonry: {
columnWidth: ".block-item-small"
}
};
scope.init = function() {
setTimeout(function() {
p = new Isotope(element[0], defaults)
}, 200), setTimeout(function() {
p.arrange()
}, 300)
}
}
}
}), angular.module("dropApp").directive("packeryItem", function() {
return {
require: "^packery",
link: function(scope, element, attrs, packeryCtrl) {
scope.$last && packeryCtrl.initialize()
}
}
}), angular.module("dropApp").directive("blockItem", function() {
return {
scope: {
data: "=blockItemData"
},
template: '<div ng-include="get_template_url()"></div>',
link: function(scope, element, attrs) {
function generate_media_cta(type) {
switch (type) {
case "video":
return "watch now";
case "playlist":
return "listen";
case "single":
return "listen";
case "gallery":
return "view now";
case "ad":
return "watch now";
default:
return "view " + type
}
}
function get_image_url(id, files) {
return files[id] ? files[id].url : null
}
function build_card() {
switch (scope.data.type) {
case "card":
scope.template_url = "partials/block-item-card.html", scope.cta = "create your card", scope.image = get_image_url(scope.data.image_id, scope.data.files), element.addClass("block-item-small block-item-card");
break;
case "ad":
scope.template_url = "partials/block-item-ad.html", scope.cta = "", scope.ad_url = scope.data.ad_url, scope.tracking_pixel_url = scope.data.tracking_pixel_url, element.addClass("block-item-small block-item-ad");
break;
case "media":
scope.template_url = "partials/block-item-media.html", scope.cta = generate_media_cta(scope.data.media_type), element.addClass("video" === scope.data.media_type ? "block-item-large" : "block-item-small");
break;
case "drop":
scope.template_url = "partials/block-item-drop.html", scope.cta = "view drop", element.addClass("block-item-small")
}
if (!scope.data.image && !scope.data.featured_image) {
var random_drop_style = Math.floor(5 * Math.random());
element.addClass("drop-style-" + random_drop_style)
}
}
scope.$watch("data", function(val) {
val && build_card()
}), scope.get_template_url = function() {
return scope.template_url
}, scope.show_ad_video = function(youtube_id) {
if (youtube_id) {
var iframeHtml = '<iframe width="560" height="315" style="z-index: 2" src="http://www.youtube.com/embed/' + youtube_id + '?autoplay=1&showinfo=0" frameborder="0" allowfullscreen></iframe>';
$.fancybox(iframeHtml, {
title: "",
closeBtn: !1,
closeClick: !0,
width: 560,
height: 300,
autoSize: !1,
autoHeight: !1,
scrolling: !1,
helpers: {
overlay: {
closeClick: !0,
locked: !1,
css: {
position: "fixed",
width: "100%",
height: "100%",
top: 0,
left: 0,
background: "rgba(50,50,50, 0.7)",
zIndex: 0
}
}
}
})
}
}, scope.is_playing = !1, scope.toggle_music = function() {
scope.is_playing ? (scope.is_playing = !1, element.removeClass("block-item-playing"), scope.audio_uri = null) : (scope.is_playing = !0, element.addClass("block-item-playing"), scope.audio_uri = "spotify:track:1XALSFY5nrFQ9NaI2XNp9t")
}
}
}
}), angular.module("dropApp").directive("dropCard", ["Image", "Api", function(Image, Api) {
return {
scope: !1,
restrict: "A",
link: function(scope, element, attrs) {
function render_background() {
var is_burst = "burst" === scope.card.type;
background.onImageLoaded(function() {
var img_data = background.getOriginalImageData();
img_data = Image.duotone(img_data, scope.card.theme.background, scope.card.theme.foreground), img_data = scope.card.flip ? Image.flipImage(img_data) : img_data, background.setImageData(img_data), background.setRotation(is_burst ? 90 * scope.card.rotation : 0), background.update(!is_burst && scope.card.scale ? {
w: 900,
h: 900,
x: -300,
y: -300
} : {
w: 450,
h: 450,
x: -75,
y: -75
})
}), card.background.update({
fill: scope.card.theme.background
}), background.changeURL(is_burst ? scope.card.burst : scope.card.image)
}
function render_text() {
return scope.card.track ? (text.song.changeText(scope.card.track), text.songxs.changeText(""), text.artist.changeText(scope.card.drop.album), text.song.w > 270 ? (text.song.changeText(""), text.songxs.changeText(scope.card.track), format_text("small"), text.songxs.w > 270 && text.songxs.truncate(270)) : format_text("normal"), void(text.artist.w > 200 && text.artist.truncate(200))) : !1
}
function format_text(type) {
switch (type) {
case "small":
text.headline.update({
y: 100
}), text.songxs.update({
y: 138
}), text.from.update({
y: 170
}), text.artist.update({
y: 170
});
break;
default:
text.headline.update({
y: 100
}), text.song.update({
y: 145
}), text.from.update({
y: 178
}), text.artist.update({
y: 178
})
}
for (var t in text) text[t].update({
fill: scope.card.theme.text
})
}
function render_user() {
if (scope.card.user) {
var img = new window.Image;
img.crossOrigin = "Anonymous", img.onload = function() {
var c = document.createElement("canvas"),
ctx = c.getContext("2d");
ctx.beginPath(), ctx.arc(25, 25, 25, 0, 2 * Math.PI, !0), ctx.closePath(), ctx.fill(), ctx.clip(), ctx.drawImage(this, 0, 0, 50, 50);
var d = ctx.getImageData(0, 0, 50, 50);
avatar.setImageData(d), avatar.update({
y: 15
})
}, img.src = scope.card.user.images[0].url, username.changeText(scope.card.user.display_name), username.update({
y: 35
})
}
}
function onMouseLeave() {
is_dragging = !1
}
function onMouseDown(x, y) {
drag_position.x = x - background.x, drag_position.y = y - background.y, is_dragging = !0
}
function onMouseUp() {
is_dragging = !1
}
function onMouseMove(x, y) {
if (is_dragging) {
var _x = x - drag_position.x,
_y = y - drag_position.y;
_x >= -1 ? _x = -1 : _x + background.w <= card.width - 1 && (_x = card.width - background.w + 1), _y >= -1 ? _y = -1 : _y + background.h <= card.height - 1 && (_y = card.height - background.h + 1), background.update({
x: _x,
y: _y
})
}
}
var card = new Postcard(element[0], {
filename: "dropcard.png"
}),
background = card.addImage("background", ""),
avatar = (card.addImage("bottomLogos", "/images/bottomlogos.png", {
x: 0,
y: 260,
w: 300,
h: 40
}), card.addImage("avatar", "/images/sample-profile.png", {
x: 15,
y: -45,
w: 35,
h: 35
})),
username = card.addText("username", "", 10, {
x: 58,
y: -35,
family: "light",
size: "14px"
}),
text = {
headline: card.addText("intro", "I'm feeling", 10, {
x: 15,
y: -15,
family: "light",
size: "20px"
}),
song: card.addText("song", "", 10, {
x: 15,
y: 128,
family: "bold",
size: "40px"
}),
songxs: card.addText("song.small", "", 10, {
x: 15,
y: 121,
family: "bold",
size: "30px"
}),
from: card.addText("from", "from", 10, {
x: 15,
y: -15,
family: "light",
size: "20px"
}),
artist: card.addText("artist", "", 10, {
x: 63,
y: -15,
family: "bold",
size: "20px"
}),
cta: card.addText("cta", "Album out now", 10, {
x: 15,
y: -15,
family: "light",
size: "15px"
})
};
scope.refresh = function() {
scope.saved = !1, render_background(), render_text(), render_user()
}, scope.$watch("card", scope.refresh, !0), scope.randomize();
var is_dragging = !1,
drag_position = {};
scope.$watch("drag", function() {
scope.drag ? (element.css("cursor", "move").bind("mouseleave", onMouseLeave), card.onMouseDown(onMouseDown), card.onMouseUp(onMouseUp), card.onMouseMove(onMouseMove)) : (element.css("cursor", "auto"), card.clearMouseEvents())
}), scope.save = function() {
Api.save_card(scope.card, card["export"]()).then(function(response) {
scope.saved = !0, Api.get_single_card(response).then(function(data) {
scope.imageUrl = encodeURIComponent(data.files[data.image_id].url)
})
})
}, scope.download = function(event) {
card.save(event)
}, PostcardTextObject.prototype.truncate = function(width) {
for (var t = this.text, i = 0; this.w > width;) this.changeText(t.substr(0, t.length - ++i) + "...")
}
}
}
}]), angular.module("dropApp").directive("mediaIcon", function() {
return {
scope: {
media: "=mediaIcon"
},
link: function(scope, element, attrs) {
scope.$watch("media", function() {
if (element.removeClass(), scope.media.locked) element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Locked-white.svg"><span>Locked Content</span></div>');
else switch (scope.media.media_type) {
case "video":
element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Video-white.svg"><span>Exclusive Video</span></div>');
break;
case "playlist":
element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Playlist-white.svg"><span>Exclusive Playlist</span></div>');
break;
case "single":
element.addClass("fa fa-play");
break;
case "gallery":
element.replaceWith('<div class="exlusive-video"><img src="/images/icons/Gallery-white.svg"><span>Exclusive Gallery</span></div>')
}
})
}
}
});